简体   繁体   English

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

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

My task is to get the x,y coordinates from the segmented image(blue dots) as produced by the code.我的任务是从代码生成的分割图像(蓝点)中获取 x、y 坐标。 How do I automate this process?我如何自动化这个过程? My end results should be a zip of x,y coordinates of these blue dots as produced in the second image.我的最终结果应该是第二张图片中生成的这些蓝点的 x、y 坐标的 zip。 在此处输入图像描述

Code to generate the blue points:生成蓝点的代码:

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

This is rather straightforward to do by computing the connected components of a binary image.通过计算二值图像的连通分量可以很简单地做到这一点。

First you'd have to threshold your image to get a binary image that segments the dots.首先,您必须对图像设置阈值以获得分割点的二值图像。 You can do this for instance with cv2.threshold .例如,您可以使用cv2.threshold执行此操作。 Then you can use cv2.connectedComponentsWithStats , this will - among other things - return a list of the centroids for all the components.然后你可以使用cv2.connectedComponentsWithStats ,这将 - 除其他事项外 - 返回所有组件的质心列表。 One of them will be the background though, but among the returned values there is an integer arrray of the same size where all components have a different label. So you can look up the label of the component of the background and remove that from the centroid coordinates.其中之一将是背景,但在返回值中有一个相同大小的 integer 数组,其中所有组件都有不同的 label。因此您可以查找背景组件的 label 并将其从质心中删除坐标。


EDIT: The code you added does not even run, but I feed it your second screenshot as a mask.png and use the mentioned commands as follows, and the plot the centroids over the image:编辑:您添加的代码甚至没有运行,但我将您的第二个屏幕截图作为mask.png提供给它,并按如下方式使用提到的命令,以及图像上的centroids plot:

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: Appending following snipped to your newest version results in this: 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()

The final code with all the above-suggested changes has been implemented below.具有所有上述建议更改的最终代码已在下面实现。 Using the median filter before the threshold, I am able to limit the number of contours detected.在阈值之前使用中值滤波器,我能够限制检测到的轮廓数量。 Next I am able to access the specific x,y coordinates by using the index values.接下来,我可以使用索引值访问特定的 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()

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM