【问题标题】:How to separate objects on their color?如何区分物体的颜色?
【发布时间】:2020-01-10 06:03:56
【问题描述】:

我正在尝试从此图像中提取小对象。我已经应用分水岭算法进行分割。如何根据颜色区分对象?我正在尝试关注this guide,但遇到异常错误。

需要提取的图片:

代码截图:

【问题讨论】:

  • 您需要将图像转换为 hsv 并过滤颜色,有很多示例只需搜索 hsv 颜色过滤器。
  • 没有必要在你的iPython笔记本中使用argparseargparse 是一个用于解析命令行参数的实用程序。在您的情况下,由于您没有从命令行运行它,您可以将代码减少到:import cv2cv2.imread("path.jpg")
  • 请不要张贴您的代码图片。将您的代码作为文本发布,以便其他人可以复制和测试它。这是您的输入图像还是分割后的图像。请提供更清晰的细节。如果您发布代码以显示正在处理的输入图像以进行分割,则最好。然后其他人可以尝试添加所需的详细信息。请阅读此论坛的帮助部分,了解如何提出好的问题并提供最低限度的完整、可验证和可重现的代码。
  • @ikibir 如果是 BGR 或任何其他格式,如何找到图像格式?

标签: python opencv


【解决方案1】:

这里不需要真正的颜色检测,因为处理是在cv2.watershed的输出上完成的。这是np.int32 类型的“图像”markers,其值为0, 1, 2, 3, ... 用于cv2.watershed 检测到的单个标记,而0 是背景。所以,没有什么比迭代所有标记值(比如说i),屏蔽markers == i所在的部分,并找到边界矩形的相应坐标,将该部分复制到新图像并将其保存到某个文件。

这是一些代码,其中 cv2.watershed 被相应地使用 cv2.findContourscv2.drawContours 模仿(关于这个问题的有趣部分只是第二个 for 循环): p>

import cv2
import numpy as np
from matplotlib import pyplot as plt
from skimage import io          # Only needed for web grabbing images

# Load some image with circles from web
image = io.imread('https://www.teachertoolsinc.com/images/detailed/26/TCR77379.png')
plt.figure(1), plt.imshow(image), plt.title('original image'), plt.tight_layout()

# Mimic watershed result using findContours and drawContours
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
gray = cv2.threshold(gray, 16, 255, cv2.THRESH_BINARY)[1]
cnts = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
markers = np.zeros_like(gray).astype(np.int32)
for i, cnt in enumerate(cnts):
    markers = cv2.drawContours(markers, [cnt], -1, i+1, cv2.FILLED)
plt.figure(2), plt.imshow(markers), plt.title('markers'), plt.colorbar(), plt.tight_layout()
plt.show()

# Assuming we only have markers now; iterate all values and crop image part
for i in np.arange(1, np.max(markers[:, :])+1):
    pixels = np.array(np.where(markers == i)).astype(np.int32)
    x1 = np.min(pixels[1, :])
    x2 = np.max(pixels[1, :])
    y1 = np.min(pixels[0, :])
    y2 = np.max(pixels[0, :])
    cv2.imwrite(str(i) + '.png', image[y1:y2, x1:x2, :])

这是输入图像:

这是模仿的markers“图片”(参见提供的相关图片):

还有,这里有两个切割圆:

希望有帮助!

-----------------------
System information
-----------------------
Python:      3.8.1
Matplotlib:  3.2.0rc1
NumPy:       1.18.1
OpenCV:      4.1.2
-----------------------

【讨论】:

    猜你喜欢
    • 2014-03-19
    • 2020-10-02
    • 1970-01-01
    • 2021-03-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-10
    • 2016-08-29
    • 1970-01-01
    相关资源
    最近更新 更多