在openCV中使用approxPolyDP()检测矩形不准确
作为包含一系列要处理的图像的程序的一部分,我首先需要先检测一个绿色矩形。我正在尝试编写一个不使用颜色遮罩的程序,因为图像上的照明/眩光会使找到合适的 HSV 范围变得困难。
(ps:我已经有两个基于这个“程序”的问题,但这个问题与那些无关。这不是跟进,我想解决一个单独的问题。)
我使用了标准的矩形检测技术:利用 findContours() 和 approxPolyDp() 方法。我添加了一些摆脱不必要矩形的约束(例如 aspectRatio>2.5: 因为我想要的矩形显然是“最宽的”并且 area>1500,以丢弃随机的小矩形)。
import numpy as np
import cv2 as cv
img = cv.imread("t19.jpeg")
width=0
height=0
start_x=0
start_y=0
end_x=0
end_y=0
output = img.copy()
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
#threshold
th = cv.adaptiveThreshold(gray,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C,cv.THRESH_BINARY,9,2)
cv.imshow("th",th)
#rectangle detection
contours, _ = cv.findContours(th, cv.RETR_TREE, cv.CHAIN_APPROX_NONE)
for contour in contours:
approx = cv.approxPolyDP(contour, 0.01* cv.arcLength(contour, True), True)
cv.drawContours(img, [approx], 0, (0, 0, 0), 5)
x = approx.ravel()[0]
y = approx.ravel()[1]
x1 ,y1, w, h = cv.boundingRect(approx)
a=w*h
if len(approx) == 4 and x>15 :
aspectRatio = float(w)/h
if aspectRatio >= 2.5 and a>1500:
print(x1,y1,w,h)
width=w
height=h
start_x=x1
start_y=y1
end_x=start_x+width
end_y=start_y+height
cv.rectangle(output, (start_x,start_y), (end_x,end_y), (0,0,255),3)
cv.putText(output, "rectangle "+str(x1)+" , " +str(y1-5), (x1, y1-5), cv.FONT_HERSHEY_COMPLEX, 0.5, (0, 0, 0))
cv.imshow("op",output)
print("start",start_x,start_y)
print("end", end_x,end_y)
print("width",width)
print("height",height)
它对所有图像都完美无缺,除了一个:
我使用自适应阈值来创建阈值,该阈值由 findContours() 方法使用。我尝试显示阈值和输出,它看起来像这样:
其他图像的阈值看起来也相似……所以我无法确定矩形检测过程中到底出了什么问题。
我尝试过的一些调整:
- 更改自适应参数方法中的最后两个参数。我尝试了 11,1 、 9,1 ,对于它们两个,阈值中的矩形看起来更突出:但在这种情况下,输出根本没有检测到矩形。
- 我已经忽略了 otsu 阈值,因为它不适用于我的大约 4 个测试图像。
我究竟可以在矩形检测程序中调整什么来检测这个矩形?
我还要求,如果可能的话,只对这个方法稍作修改,而不是一些全新的方法。正如我所提到的,这种方法对我所有的其他测试图像都非常有效,如果新建议的方法对这个图像有效而对其他图像失败,那么我会发现自己回到这里问为什么它失败了。
编辑:abss 建议的方法适用于该图像,但失败了:
4
1、远
其他测试图片:
1、正常
2
3
9,part1
9,part2
回答
您可以通过在阈值后添加这行代码来轻松完成
kernel = cv.getStructuringElement(cv.MORPH_RECT,(3,3))
th = cv.morphologyEx(th,cv.MORPH_OPEN,kernel)
这将消除图像中的噪声。您可以查看此链接以进一步了解morphologyEx https://docs.opencv.org/master/d9/d61/tutorial_py_morphological_ops.html
我得到的结果如下所示