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

Posted

技术标签:

【中文标题】如何从python中的图像中获取特定像素(蓝色)的x,y坐标?【英文标题】:How to fetch x,y coordinates of specific pixels(blue colored) from an image in python? 【发布时间】:2021-11-17 19:28:28 【问题描述】:

我的任务是从代码生成的分段图像(蓝点)中获取 x,y 坐标。我如何自动化这个过程?我的最终结果应该是第二张图像中产生的这些蓝点的 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')
#     cv2_imshow(full_mask)
#     cv2_imshow(result)
    #print(full_mask)
    #print(result) 
    cv2.waitKey(0)
    cv2.destroyAllWindows()

【问题讨论】:

这个问题已经在***.com/questions/51646047/…得到解答 【参考方案1】:

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

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


编辑:您添加的代码甚至没有运行,但我将您的第二个屏幕截图作为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()

【讨论】:

@AMANDEEPKAUR 您发布的代码似乎没有运行。拥有应用代码的原始图像会很好,而不仅仅是屏幕截图。 不,问题不在于倒置坐标,因为基本事实基于这种缩放。即使尝试了您的代码,我也无法获得正确的坐标。是因为图片大小不同吗?我已经上传了原始图像和掩码代码,你可以试试它是否适用于你吗?帮助将不胜感激,因为我一直坚持这个问题陈述! 我再次更新了我的答案,向您展示它的样子。 非常感谢!现在可以正常使用了! 这是因为您得到了具有该阈值的不相交的像素簇 - 在第一张图片中它们不存在,因为使用了较小的分辨率(您的屏幕截图)。如果您愿意,我建议在阈值处理之前应用平滑(低通)滤波器,或者在阈值处理之后应用形态闭合操作。【参考方案2】:

具有上述所有更改的最终代码已在下面实现。在阈值之前使用中值滤波器,我可以限制检测到的轮廓数量。接下来,我可以使用索引值访问特定的 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()

【讨论】:

正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于如何从python中的图像中获取特定像素(蓝色)的x,y坐标?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 SDL_Surface 获取特定像素的颜色?

从 2d 图像像素获取 3d 坐标系中的 x,y

如何为使用 python 保存的 tiff 图像设置像素大小,以便将像素高度和宽度设置为 ImageJ 中的特定值?

从背景中的窗口获取像素颜色

如何从 kinect 深度图像中获取深度强度,因为它表示像素到传感器的距离

如何在openCV Python中选择统一着色图的特定部分?