我正在尝试使用阈值进行细分颜色。但这不是行不通的。我如何在这张照片中分割红色和绿色。
谢谢
使用Kmeans后的这张图片
使用阈值分割后的这张图片
我的代码
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()
答案 0 :(得分:2)
如果我理解正确,您想将绿色和红色分开吗?如果是这种情况,您可以将图像转换为HSV颜色空间,并使用*a=20
*b=10
和cv2.inRange()
提取颜色。请注意,代码是使用OpenCV 3和Python 3.5编写的。希望能有所帮助。干杯!
示例代码:
cv2.bitwise_and()
结果:
答案 1 :(得分:1)
我会利用标签数组的优势并将其用于细分。
首先将其调整为与输入图像相同的宽度/高度。
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
的调用(有关差异,请参阅docs)。
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))
示例输出:
不同颜色的示例输出: