如何从 python 中的图像中获取特定像素(蓝色)的 x、y 坐标?

How to fetch x,y coordinates of specific pixels(blue colored) from an image in python?

我的任务是从代码生成的分割图像(蓝点)中获取 x、y 坐标。我如何自动化这个过程?我的最终结果应该是第二张图片中生成的这些蓝点的 x、y 坐标的 zip。

生成蓝点的代码:

    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
# import cv2_imshow
# from google.colab.patches import cv2_imshow
 
    image = cv2.imread('./S3/frame35.jpg')
#cv2_imshow(image)

    result = image.copy()
 
    image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

    # lower boundary RED color range values; Hue (0 - 10)
    lower1 = np.array([0, 100, 20])
    upper1 = np.array([10, 255, 255])

    # upper boundary RED color range values; Hue (160 - 180)
    lower2 = np.array([160,100,20])
    upper2 = np.array([179,255,255])

    lower_mask = cv2.inRange(image, lower1, upper1)
    upper_mask = cv2.inRange(image, lower2, upper2)

    full_mask = lower_mask + upper_mask;

    result = cv2.bitwise_and(result, result, mask=full_mask)

    plt.figure(figsize=[20,20])
    plt.axis("off")
#     plt.subplot(121);plt.imshow(image[:,:,::-1]);plt.title("Original Image",fontdict={'fontsize': 25});plt.axis('off');
    plt.subplot(122);plt.imshow(result, cmap='gray');plt.title("Mask of red Color",fontdict={'fontsize': 25});plt.axis('on');
    plt.savefig('mask_1.jpg', bbox_inches = 'tight')
#     cv2_imshow(full_mask)
#     cv2_imshow(result)
    #print(full_mask)
    #print(result) 
    cv2.waitKey(0)
    cv2.destroyAllWindows()

通过计算二值图像的连通分量,这很简单。

首先,您必须对图像设置阈值以获得分割点的二值图像。例如,您可以使用 cv2.threshold 来执行此操作。 然后你可以使用 cv2.connectedComponentsWithStats,这将 - 除其他外 - return 所有组件的质心列表。虽然其中之一将是背景,但在 returned 值中有一个相同大小的整数数组,其中所有组件都有不同的标签。因此,您可以查找背景组件的标签并将其从质心坐标中删除。


编辑:您添加的代码甚至没有 运行,但我将您的第二张截图作为 mask.png 提供给它,并按如下方式使用上述命令,并绘制 centroids 在图像上:

src = cv2.imread('mask.png')
_, thresh = cv2.threshold(src[:, :, 0:1], 120, 255, cv2.THRESH_BINARY)
_, _, _, centroids = cv2.connectedComponentsWithStats(thresh, 8, cv2.CV_32S)


EDIT2:将以下片段附加到您的最新版本会导致:

_, thresh = cv2.threshold(result[:, :, 0:1], 20, 255, cv2.THRESH_BINARY)
_, _, _, centroids = cv2.connectedComponentsWithStats(thresh, 8, cv2.CV_32S)
plt.imshow(thresh)
plt.plot(centroids[:,0], centroids[:, 1], 'or', mfc='none')
plt.show()

具有上述所有建议更改的最终代码已在下面实现。在阈值之前使用中值滤波器,我能够限制检测到的轮廓数量。接下来,我可以使用索引值访问特定的 x、y 坐标。

    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
# import cv2_imshow
# from google.colab.patches import cv2_imshow
 
    image = cv2.imread('./S3/frame35.jpg')
#cv2_imshow(image)

    result = image.copy()
 
    image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

    # lower boundary RED color range values; Hue (0 - 10)
    lower1 = np.array([0, 100, 20])
    upper1 = np.array([10, 255, 255])

    # upper boundary RED color range values; Hue (160 - 180)
    lower2 = np.array([160,100,20])
    upper2 = np.array([179,255,255])

    lower_mask = cv2.inRange(image, lower1, upper1)
    upper_mask = cv2.inRange(image, lower2, upper2)

    full_mask = lower_mask + upper_mask;

    result = cv2.bitwise_and(result, result, mask=full_mask)

    plt.figure(figsize=[20,20])
    plt.axis("off")
#     plt.subplot(121);plt.imshow(image[:,:,::-1]);plt.title("Original Image",fontdict={'fontsize': 25});plt.axis('off');
    plt.subplot(122);plt.imshow(result, cmap='gray');plt.title("Mask of red Color",fontdict={'fontsize': 25});plt.axis('on');
#     plt.savefig('mask_1.jpg', bbox_inches = 'tight')

    median = cv2.medianBlur(result,9)
    _, thresh = cv2.threshold(median[:, :, 0:1],20, 255, cv2.THRESH_BINARY)
    _, _, _, centroids = cv2.connectedComponentsWithStats(thresh, 8, cv2.CV_32S)
    plt.imshow(thresh)
   
    plt.plot(centroids[:,0], centroids[:, 1], 'or', mfc='none')
    plt.show()

    cv2.waitKey(0)
    cv2.destroyAllWindows()