【问题标题】:Find the coordinates of red pixel in an image查找图像中红色像素的坐标
【发布时间】:2020-04-28 13:36:31
【问题描述】:

Input picture

上面的图片是我正在使用的示例输入,我想找到该图像中所有红色像素的坐标并将其存储在一个列表中,然后,稍后迭代该列表并围绕每个我们使用 OpenCV 的 cv2.circle 函数在图像中找到的坐标。我正在执行以下操作:

coord = []

for i in range(img.shape[0]):
    for j in range(img.shape[1]):
        if img[i,j,0]!=0 and img[i,j,1]!=0 and img[i,j,2]!=255:
            img[i,j,0]=0
            img[i,j,1]=0
            img[i,j,2]=0
        else:
            img[i,j,0]=0
            img[i,j,1]=0
            img[i,j,2]=255  
            coord.append([i,j])

for l in range(len(coord)):
    px=coord[l][0]
    py=coord[l][1]
    cv2.circle(img,(px,py),5,(0,255,255),1)

但执行上述操作并不是在所有坐标上都画一个圆圈。我猜坐标的存储和访问它们有问题。谁能指出错误并帮助我。

I am getting the following output which isn't correct

【问题讨论】:

    标签: python image opencv coordinates


    【解决方案1】:

    这里的主要问题是,当写回这些圆圈时,您的 pxpy 被调换了。你必须这样做(py, px)

    但是,此外,为了更快地找到红色像素(在我的机器上快 135 倍!),请结合使用

    • cv2.inRange(生成二值掩码图,匹配像素为1,不匹配为0)
    • np.argwhere(返回值为非零的矩阵的索引)
    import cv2
    import numpy as np
    
    img = cv2.imread("RvegM.png")
    red_pixels = np.argwhere(cv2.inRange(img, (0, 0, 250), (0, 0, 255)))
    for px, py in red_pixels:
        cv2.circle(img, (py, px), 5, (0, 255, 255), 1)
    cv2.imwrite("out.png", img)
    

    out.png 最终看起来像这样:

    【讨论】:

    【解决方案2】:

    for 循环让您整天都在那儿!使用环形内核进行形态卷积会快几英里。我可以在 ImageMagick 中向您展示如何快速做到这一点,但您也可以使用 OpenCV 做到这一点。

    这是基本命令:

    magick stars.png -morphology convolve ring:3.5,4.5 result.png
    

    我将再次运行它,这一次,请 ImageMagick 向我展示内核 - 希望你能看到 1 形成一个内半径为 3.5 像素、外半径为 4.5 像素的环:

    convert stars.png -define morphology:showkernel=1 -morphology convolve ring:3.5,4.5 result.png
    

    输出

    Kernel "Ring" of size 9x9+4+4 with values from 1 to 1
    Forming a output range from 0 to 32 (Sum 32)
     0: nan     nan       1       1       1       1       1     nan     nan
     1: nan       1       1     nan     nan     nan       1       1     nan
     2:   1       1     nan     nan     nan     nan     nan       1       1
     3:   1     nan     nan     nan     nan     nan     nan     nan       1
     4:   1     nan     nan     nan     nan     nan     nan     nan       1
     5:   1     nan     nan     nan     nan     nan     nan     nan       1
     6:   1       1     nan     nan     nan     nan     nan       1       1
     7: nan       1       1     nan     nan     nan       1       1     nan
     8: nan     nan       1       1       1       1       1     nan     nan
    

    Anthony Thyssen here 对形态学的迷人主题及其工作原理进行了出色的描述。


    这是相同技术的 OpenCV Python 版本:

    #!/usr/bin/env python3
    
    import cv2
    from skimage.draw import circle_perimeter
    import numpy as np
    
    # Load image
    im = cv2.imread('stars.png')
    
    # Ring shape structuring element 9x9 with a central circle radius 4 of 1s
    selem = np.zeros((9, 9), dtype=np.uint8)
    rr, cc = circle_perimeter(4, 4, 4)
    selem[rr, cc] = 1
    
    # Do the morphology just on red channel
    dilated = cv2.dilate(im[...,2], selem, iterations=1)
    
    # Put modified red channel back into original image and save
    im[:,:,2] = dilated
    cv2.imwrite('result.png', im)
    

    结果同上。

    【讨论】:

    • 如果不显示相关的 OpenCV 代码,我不会说“一样”...
    • @AKX 给我们一个机会 :-) 我只是希望说服 OP 考虑一种不同的方式,然后再在慢循环上投入太多精力!我将在 OpenCV 版本上工作...
    • 我确实喜欢提醒我们所有形态过滤器的想法,但不要误会我的意思! :)
    • @MarkSetchell 感谢您的解决方案!
    【解决方案3】:

    你的条件写得不好。首先,最好在一个范围内搜索,如果像素值

    对于红色,我们可以检查 B 和 G 通道的值是否小于 220。

    coord = []
    
    for i in range(img.shape[0]):
        for j in range(img.shape[1]):
            if img[i,j,0]<10 and img[i,j,1]<10 and img[i,j,2]>220:
                img[i,j,0]=0
                img[i,j,1]=0
                img[i,j,2]=255
                coord.append([i,j])
            else:
                img[i,j,0]=0
                img[i,j,1]=0
                img[i,j,2]=0
    
    for l in range(len(coord)):
        px=coord[l][0]
        py=coord[l][1]
        cv2.circle(img,(py,px),5,(0,255,255),1)
    

    【讨论】:

    • OP 确实有一个只有两种颜色的图像,所以这不会改变这种情况。
    • 您仍然可以拥有具有不同像素范围的图像,但它们可能看起来好像只存在两种颜色。图像最常被压缩,假设像素恰好是 0 和 255 值是不明智的,因此我认为这是更好的方法。最后,如果只有两种颜色,这也可以工作,所以我看不出有什么害处。
    • @ZabirAlNazi 我真的需要这个问题的帮助,你能帮帮我吗? stackoverflow.com/questions/61216402/…
    • @ZabirAlNazi 谢谢!
    猜你喜欢
    • 1970-01-01
    • 2020-02-12
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    • 2015-11-16
    • 2022-01-26
    • 2018-08-16
    相关资源
    最近更新 更多