遮罩以过滤关注区域(OpenCV)

时间:2020-04-08 13:38:03

标签: python-3.x opencv

我需要一个遮罩,使此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()

1 个答案:

答案 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()

图片:

mask(解决方案):
enter image description here

img
enter image description here

gray
enter image description here

dark_mask
enter image description here

thresh
enter image description here