查找图像中红色像素的坐标

Find the coordinates of red pixel in an image

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

你的条件写的不好。首先,最好在一个范围内搜索,如果像素值<10我们可以认为它是黑色的。

对于红色,我们可以检查 B 和 G 通道的值是否小于 < 10(您可以更改它),R 通道的值是否 > 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)

你会在那里呆一整天 for 循环!使用环核进行形态学卷积会快很多。我可以向您展示如何在 ImageMagick 中快速完成,但您也可以使用 OpenCV.

进行同样的操作

基本命令如下:

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

我会再 运行 一次,这一次,请 ImageMagick 向我展示内核 - 希望你能看到 1s 形成一个内半径为 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)

结果同上

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

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

  • cv2.inRange(生成二值mask图像,匹配像素为1,不匹配像素为0)
  • np.argwhere(其中 returns 值为非零的矩阵的索引)
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 最终看起来像这样: