joe*_*lsa 3 c++ opencv image-processing
我的图像中有一个高反射率的球,如下所示:
什么是实时检测球的稳健方法?(5-10 帧/秒)
我尝试了几种分割算法,但它们无法将球与背景分开,而是将球切成碎片,因为球本身有许多不同的区域。
由于反射性质,简单的圆形霍夫变换效果不佳。这同样适用于任何简单的阈值或形态学操作。
您对处理一般反光表面有什么建议吗?
HoughCircles的建议很棒,只要您大致了解球在框架中的移动方式,以及您所占的最小、最大半径:
import numpy as np
import cv2
import cv2.cv as cv
img = cv2.imread('wcEXm.jpg',0)
#Method 1: Hough Circles
img = cv2.medianBlur(img,5)
cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)
# HoughCircles(image, method, dp, minDist[, circles[, param1[, param2[, minRadius[, maxRadius]]]]])
circles = cv2.HoughCircles(img,cv.CV_HOUGH_GRADIENT,dp=1,minDist=50,param1=127,param2=30,minRadius=50,maxRadius=150)
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
# draw the outer circle
cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),2)
# draw the center of the circle
cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3)
cv2.imshow('detected circles',cimg)
Run Code Online (Sandbox Code Playgroud)
另一种选择是使用findContours()。通过正确的选项和一些过滤(例如dilate(),erode()),您可以将球从背景中分割出来,并且宽度和高度之间的比率(更接近正方形)将有所帮助。
然而,如果您对球的大小不感兴趣,只知道它在哪里,那么有一个巧妙的小东西可能会大大简化这一过程。你的球是反光的,甚至开始检测你将需要光源,因此,即使颜色/环境看起来不同,球也会有一个亮点。假设光源不在画面中,您的反光球可能是场景中下一个最亮的物体:
import cv2
img = cv2.imread('wcEXm.jpg',0)
minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(img)
cv2.circle(img, maxLoc, 20, (0,192,0),10)
Run Code Online (Sandbox Code Playgroud)
就 RaspberryPi 上的性能而言,我建议如下:
minMaxLoc()或其他处理灰度图像的函数,您可以使用'yuv'颜色空间并简单地使用 Y(亮度)通道来节省一些时间,而无需从 RGB 转换为亮度/灰度更新: 另一件事可能会有所帮助,那就是Canny 边缘检测,因为场景很简单,球会很突出:
edges = cv2.Canny(img,100,200)
Run Code Online (Sandbox Code Playgroud)