python-2.7 - 使用 Kmeans 的 OpenCV 颜色分割

标签 python-2.7 opencv

我正在尝试使用分割颜色的阈值。但这不是行不通的。如何在这张图片中分割红色和绿色。

感谢

this image after using Kmeans

这张使用Kmeans后的图片

enter image description here

使用阈值分割后的图像

我的代码

import numpy as np
import cv2

img = cv2.imread('watermelon.jpg')
Z = img.reshape((-1,3))

# convert to np.float32
Z = np.float32(Z)

# define criteria, number of clusters(K) and apply kmeans()
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 4
ret,label,center=cv2.kmeans(Z,K, criteria,10,cv2.KMEANS_RANDOM_CENTERS)

# Now convert back into uint8, and make original image
center = np.uint8(center)
res = center[label.flatten()]
res2 = res.reshape((img.shape))
gray = cv2.cvtColor(res2,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

#segmentation
gray = cv2.cvtColor(res2,cv2.COLOR_BGR2GRAY)
ret, threshseg = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

cv2.imwrite('img_CV2_95.jpg',threshseg)
cv2.imwrite('img_CV2_94.jpg',res2)


cv2.imshow('threshseg',threshseg)
cv2.imshow('thresh',thresh)
cv2.imshow('res2',res2)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

最佳答案

我会利用标签数组并将其用于分割。

首先将其重新整形为与输入图像相同的宽度/高度。

labels = labels.reshape((img.shape[:-1]))

现在,假设您要获取标签为 2 的所有像素。

mask = cv2.inRange(labels, 2, 2)

只需将它与 cv2.bitwise_and 一起使用即可屏蔽图像的其余部分。

mask = np.dstack([mask]*3) # Make it 3 channel
ex_img = cv2.bitwise_and(img, mask)

这种方法的好处是您不需要对任何颜色范围进行硬编码,因此相同的算法适用于许多不同的图像。


示例代码:

注意:为 OpenCV 3.x 编写。 OpenCV 2.4.x 的用户需要适本地更改 cv2.kmeans 的调用(请参阅文档了解差异)。

import numpy as np
import cv2

img = cv2.imread('watermelon.jpg')
Z = np.float32(img.reshape((-1,3)))

criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 4
_,labels,centers = cv2.kmeans(Z, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
labels = labels.reshape((img.shape[:-1]))
reduced = np.uint8(centers)[labels]

result = [np.hstack([img, reduced])]
for i, c in enumerate(centers):
    mask = cv2.inRange(labels, i, i)
    mask = np.dstack([mask]*3) # Make it 3 channel
    ex_img = cv2.bitwise_and(img, mask)
    ex_reduced = cv2.bitwise_and(reduced, mask)
    result.append(np.hstack([ex_img, ex_reduced]))

cv2.imwrite('watermelon_out.jpg', np.vstack(result))

示例输出:

Sample Output

不同颜色的示例输出:

Another Sample Output

关于python-2.7 - 使用 Kmeans 的 OpenCV 颜色分割,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52802910/

相关文章:

python-2.7 - Ansible 列表未排序

python - Tornado AsyncHTTPClient 性能下降

python - 如何从文本文件中读取非英语文本并在 python 中打印?

opencv - haarCascades可用于获取对象大小吗?

python - 使用opencv访问手机摄像头

python - MongoKit "ImportError: No module named objectid "错误

Python/ flask - ValueError : I/O operation on closed file

opencv - 检测深度图上的近似物体

opencv - 负载训练的SVM – Emgu CV

c++ - 使用 SSE 的 OpenCV 灰度图像的平方根