使用Kmeans的OpenCV颜色分割 [英] OpenCV Color Segmentation Using Kmeans

查看:385
本文介绍了使用Kmeans的OpenCV颜色分割的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'am trying to use threshold for segmentation color. but it's not doesn't work. how can i segmentation red and green in this picture.

谢谢

使用Kmeans后的这张图片

This image after using Kmeans

使用阈值分割后的这张图片

This image after Segmentation using threshold

我的代码

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()

推荐答案

我会利用标签数组的优势并将其用于细分.

I'd take the advantage of the labels array and use that for segmentation.

首先将其调整为与输入图像相同的宽度/高度.

First reshape it back to the same width/height of the input image.

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

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

Now, let's say you want to grab all the pixels with label 2.

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

并简单地将其与cv2.bitwise_and一起使用即可遮盖图像的其余部分.

And simply use it with cv2.bitwise_and to mask out the rest of the image.

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

这种方法的好处是您不需要对任何颜色范围进行硬编码,因此相同的算法可以在许多不同的图像上工作.

The nice thing about this approach is that you don't need to hardcode any colour ranges, so the same algorithm will work on many different images.

示例代码:

注意:为OpenCV 3.x写. OpenCV 2.4.x的用户需要适当地更改cv2.kmeans的调用(有关差异,请参阅文档).

Note: Written for OpenCV 3.x. Users of OpenCV 2.4.x need to change the call of cv2.kmeans appropriately (see docs for the difference).

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))

示例输出:

具有不同颜色的示例输出:

这篇关于使用Kmeans的OpenCV颜色分割的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆