【问题标题】:OpenCV Color Segmentation Using Kmeans使用 Kmeans 进行 OpenCV 颜色分割
【发布时间】:2019-03-19 01:34:09
【问题描述】:

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

谢谢

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

【问题讨论】:

  • 如果您附加未修改的输入图像,这将非常有用。 (我猜你还在使用 OpenCV 2.4.x,因为你调用 kmeans 时只有 5 个参数?这也很有用。)
  • label 重新整形为与img 相同的宽度/高度,然后使用inRange 创建掩码,选择具有给定标签的所有像素。类似this...

标签: python-2.7 opencv


【解决方案1】:

如果我理解正确,您想将绿色和红色分开吗?如果是这种情况,您可以将图像转换为 HSV 颜色空间并使用cv2.inRange()cv2.bitwise_and() 提取颜色。请注意,代码是使用 OpenCV 3 和 Python 3.5 编写的。希望它有点帮助。干杯!

示例代码:

import cv2
import numpy as np

# Read the image and transform it to HSV color space
img = cv2.imread('watermelon.jpg')
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# define ranges for colors in HSV color space you wish to display

## LIGHT AND DARK GREEN
lower_green_light = np.array([20,20,50])
upper_green_light = np.array([130,150,255])

## DARK GREEN
lower_green = np.array([0, 70, 50])
upper_green = np.array([170, 180, 100])

## RED
lower_red = np.array([170, 130, 0])
upper_red = np.array([180, 255, 255])

# Threshold with inRange() get only specific colors
mask_green = cv2.inRange(hsv, lower_green, upper_green)
mask_green_light = cv2.inRange(hsv, lower_green_light, upper_green_light)
mask_red = cv2.inRange(hsv, lower_red, upper_red)

# Perform bitwise operation with the masks and original image
res_green = cv2.bitwise_and(img,img, mask= mask_green)
res_green_light = cv2.bitwise_and(img,img, mask= mask_green_light)
res_red = cv2.bitwise_and(img,img, mask= mask_red)

# Display results
cv2.imshow('red', res_red)
cv2.imshow('green', res_green)
cv2.imshow('light green', res_green_light)
cv2.waitKey(0)
cv2.destroyAllWindows()

结果:

【讨论】:

    【解决方案2】:

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

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

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

    样本输出:

    不同颜色的样本输出:

    【讨论】:

      猜你喜欢
      • 2017-12-15
      • 2016-09-11
      • 1970-01-01
      • 2016-05-11
      • 1970-01-01
      • 1970-01-01
      • 2015-03-11
      • 2022-07-06
      • 2014-08-25
      相关资源
      最近更新 更多