【问题标题】:openCV problem with detecting contours of shapes fully完全检测形状轮廓的openCV问题
【发布时间】:2019-05-29 21:25:33
【问题描述】:

我正在做这个大学项目,我尝试在使用 openCV 的 Android 应用程序的屏幕截图上检测 UI 元素。我并不期望这种 UI 元素的检测有 100% 的准确度。

这是我下面的代码。我将图像转换为灰度,应用高斯模糊,然后使用自适应阈值将图像转换为二进制。之后我使用查找轮廓方法。

ap = argparse.ArgumentParser()
ap.add_argument("-i","--image", help = "path to an image", required = 
True)
args = vars(ap.parse_args())

image = cv2.imread(args["image"])
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

cv2.imshow("gray",gray)
cv2.waitKey(0)


blurred = cv2.GaussianBlur(gray, (5,5), 0)
thresh = cv2.adaptiveThreshold(blurred, 255, 
cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 11, 4)

cv2.imshow("thresh",thresh)
cv2.waitKey(0)
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, 
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)

cv2.drawContours(image, cnts, -1, (0,255,0), 1)

cv2.imshow("contours", image)
cv2.waitKey(0)

for c in cnts:

    area = cv2.contourArea(c)
    print(area)
    if area > 50:
        M = cv2.moments(c)


        cX = int(M['m10'] / M['m00'])
        cY = int(M['m01'] / M['m00'])



        #cv2.drawContours(image, [c], -1, (0,255,0), 2)  # draw contours on image 

        (x,y,w,h) = cv2.boundingRect(c) # for each contour get a 
bounding rectangle 
        mask = np.zeros(image.shape[:2], dtype = "uint8")    # find 
shape of the image dimensions and set up a mask 
        mask[y: y + h, x: x + w] = 255      # convert region of 
interest into white 
        to_display = cv2.bitwise_and(image,image, mask = mask)  # carry 
out bitwise and 
        #cv2.putText(image, 'center', (c))

        cv2.imshow("Image", to_display)
        cv2.waitKey(0)

这是我正在运行我的代码的屏幕截图。

最左边的屏幕截图表示应用阈值后的图像。

中间的图像代表我绘制轮廓后得到的图像。

当我检查每个单独的轮廓时,最后一张图像显示。轮廓覆盖线但不封装矩形。

我有几个问题。

1) 是否可以筛选出白色矩形的轮廓。我必须对我的代码进行哪些更改才能实现这一目标?

2) 我试图筛选出不重要的轮廓,例如。这些话,我在想我是否可以使用 getArea() 函数来帮助我。这个想法是我会设置一个最小轮廓大小来过滤掉占单词的较小轮廓。

这是我尝试在此屏幕截图中识别“对象”的另一张图片。

我在这里遇到了同样的问题,我无法识别白色矩形。我只是识别矩形的边界。

感谢任何形式的帮助,因为我还是 openCv 的新手

处理前的原图:

【问题讨论】:

  • 能否提供处理前的应用图片?
  • @J.D 你好我已经添加了原始截图

标签: opencv object-detection opencv-contour


【解决方案1】:

没有必要模糊。事实上,我让它变得更难了。简单的阈值处理最适合硬转换。第二张图最简单。灰色背景上有白色物品。通过只选择非常白的值,项目被选中。

结果:

代码:

# load image
img = cv2.imread("app.png")
# convert to gray
img2 =  cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# crate a mask that hold only white values (above 250) 
ret,thresh1 = cv2.threshold(img2,250,255,cv2.THRESH_BINARY)
# find contours in mask
im2, contours, hierarchy = cv2.findContours(thresh1, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# select large contours (menu items only)
for cnt in contours:
    print(cv2.contourArea(cnt))
    if cv2.contourArea(cnt) > 5000:
        # draw a rectangle around the items
        x,y,w,h = cv2.boundingRect(cnt)
        cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0),3)
        #cv2.drawContours(img, [cnt], 0, (0,255,0), 3) #also works, but has issues with letters at the last item
#show image
cv2.imshow("img", img)
#cv2.imshow("mask", thresh) # shows mask
cv2.waitKey(0)
cv2.destroyAllWindows()  

第一张图片更复杂,因为它被一条非常细的红线分割开来。在 HSV 颜色空间中选择颜色更容易。接下来的红色值用于创建遮罩,去除一些噪声,然后检测轮廓。

结果:

# load image
img = cv2.imread("app2.png")
# convert to HSV
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) 
# set lower and upper color limits
lower_val = np.array([0,0,0])
upper_val = np.array([20,50,255])
# Threshold the HSV image 
mask = cv2.inRange(hsv, lower_val, upper_val)
# remove noise
kernel =  np.ones((1,2),np.uint8)
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
kernel =  np.ones((1,5),np.uint8)
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
# find contours in mask
im2, contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# select large contours (menu items only)
for cnt in contours:
    print(cv2.contourArea(cnt))
    if cv2.contourArea(cnt) > 1000:
        # draw a rectangle around the items
        x,y,w,h = cv2.boundingRect(cnt)
        cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0),3)
#show image
cv2.imshow("img", img)
cv2.imshow("mask", mask) 
cv2.waitKey(0)
cv2.destroyAllWindows()   

【讨论】:

  • 嗨@J.D 感谢您的回答!请问 cv2.contourArea() 函数是否准确?因为我看到的一些区域看起来比以前的区域小,但它们的区域更大?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多