我需要一个遮罩,使此image中的圆圈从背景中突出,接收到二进制图像,其中白色是感兴趣的区域(圆圈),黑色是其他所有区域。因此,我可以在视频捕获中应用此蒙版,在那里可能只看到球体。 注意:背景通常为白色。
我已经使用简单的算法使用阈值或inRange创建了代码,即通过用户手动选择的内容标记圆的区域,从而删除了最小和最大rgb值,从而创建了一个要应用的参数在inRange或阈值中。但是,由于背景通常是白色且清晰,与球体的颜色非常相似,因此二进制掩码会包含背景,从而使代码失败。 还有其他方法吗?
import cv2
import numpy as np
ix,iy = 0,0
def selection_area(event,x,y,flags,param):
global ix,iy
global vx,vy
if event == cv2.EVENT_LBUTTONDBLCLK:
cv2.rectangle(img,(x-5,y-5),(x+5,y+5),(255,255,0),-1)
if ix!=0 and iy!=0:
cv2.rectangle(img,(x,y),(ix,iy),(255,0,0),1)
vx=[x,ix]
vy=[y,iy]
ix,iy = x,y
def analyzeRGB(cimg):
b=[];g=[];r=[];
for j in cimg:
for i in j:
b.append(i[0])
g.append(i[1])
r.append(i[2])
lower_blue= np.array([min(b),min(g),min(r)])
upper_blue= np.array([max(b),max(g),max(r)])
return lower_blue,upper_blue
cap = cv2.VideoCapture(0)
while(True):
ret, frame = cap.read()
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
img=frame
break
cap.release()
cv2.destroyAllWindows()
cv2.imshow('Analyze',img)
cv2.setMouseCallback('Analyze',selection_area)
while(1):
cv2.imshow('Analyze',img)
k = cv2.waitKey(20) & 0xFF
if k == ord('q'):
print (vx,vy)
break
cv2.destroyAllWindows()
cut = img[min(vy)+5:max(vy)-5,min(vx)+5:max(vx)-5]
cv2.imshow("Cut",cut)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.waitKey(0)
filter_RGB =analyzeRGB(cut)
img = cv2.inRange(img, filter_RGB[0],filter_RGB[1])
cv2.imshow("Ready",img)
cv2.imshow("Cut",cut)
cv2.waitKey(0)
cv2.destroyAllWindows()
cap = cv2.VideoCapture(0)
while(True):
ret, frame = cap.read()
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY);
frame =cv2.inRange(frame,filter_RGB[0],filter_RGB[1])
cv2.imshow("Frame",frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
答案 0 :(得分:0)
找到球是具有挑战性的,因为颜色接近背景,而且是手。
球的反射和不均匀性使其更具挑战性。
如果您知道球的确切半径,则可以使用cv2.HoughCircles
搜索具有确切半径的圆。
我的解决方案使用cv2.HoughCircles
,但首先“清除”图像。
有一个很好的变化,即该解决方案过于针对您所发布的图像,不适用于一般情况。
该解决方案使用以下阶段:
cv2.adaptiveThreshold
-查找强度接近背景强度的边缘。cv2.HoughCircles
查找圈子。这是代码:
import cv2
import numpy as np
# Read input image
img = cv2.imread('ball_in_hand.png')
# Convert to gray
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Apply median filter
gray = cv2.medianBlur(gray, 5)
# Apply adaptive threshold with gaussian size 15x15
thresh = cv2.adaptiveThreshold(gray, 255, adaptiveMethod=cv2.ADAPTIVE_THRESH_MEAN_C, thresholdType=cv2.THRESH_BINARY, blockSize=15, C=0)
# Use threshold for finding dark pixels - needs to be masked
_, dark_mask = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# Mask the dark pixels.
thresh = thresh & dark_mask
# Use "opening" morphological operation - cleaning up.
thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5)))
rows, cols = thresh.shape
# Use HoughCircles for finding circles
circles = cv2.HoughCircles(thresh, cv2.HOUGH_GRADIENT, 1, minDist=rows//8, param1=50, param2=30, minRadius=rows//8, maxRadius=rows//2)
# mask will be the desired mask (filled circle)
mask = np.zeros_like(gray)
# Iterate circles
for c in circles[0,:]:
# Draw green circle on the image for testing
cv2.circle(img, (c[0], c[1]), c[2], (0, 255, 0), 2)
# Draw filled circle for creating the mask
cv2.circle(mask, (c[0], c[1]), c[2], 255, cv2.FILLED)
# Show images for testing
cv2.imshow('img', img)
cv2.imshow('gray', gray)
cv2.imshow('thresh', thresh)
cv2.imshow('dark_mask', dark_mask)
cv2.imshow('mask', mask)
cv2.waitKey(0)
cv2.destroyAllWindows()
图片: