作为包含一系列要处理的图像的程序的一部分,我首先需要先检测一个绿色矩形。我正在尝试编写一个不使用颜色遮罩的程序,因为图像上的照明/眩光会使找到合适的 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)
Run Code Online (Sandbox Code Playgroud)
它对所有图像都完美无缺,除了一个:
我使用自适应阈值来创建阈值,该阈值由 findContours() 方法使用。我尝试显示阈值和输出,它看起来像这样:
其他图像的阈值看起来也相似……所以我无法确定矩形检测过程中到底出了什么问题。
我尝试过的一些调整:
我究竟可以在矩形检测程序中调整什么来检测这个矩形?
我还要求,如果可能的话,只对这个方法稍作修改,而不是一些全新的方法。正如我所提到的,这种方法对我所有的其他测试图像都非常有效,如果新建议的方法对这个图像有效而对其他图像失败,那么我会发现自己回到这里问为什么它失败了。
编辑:abss 建议的方法适用于该图像,但失败了:
其他测试图片:
您可以通过在阈值后添加这行代码来轻松完成
kernel = cv.getStructuringElement(cv.MORPH_RECT,(3,3))
th = cv.morphologyEx(th,cv.MORPH_OPEN,kernel)
Run Code Online (Sandbox Code Playgroud)
这将消除图像中的噪声。您可以查看此链接以进一步了解morphologyEx https://docs.opencv.org/master/d9/d61/tutorial_py_morphological_ops.html
我对您的代码进行了一些修改,以便它适用于您的所有测试图像。您可能需要根据绿色的 HSV 颜色范围过滤一些误报(因为您的目标始终是绿色阴影)。或者,您可以考虑这样一个事实:您的 ROI 轮廓的子层次结构将是外部轮廓的 > 0.4 倍左右。以下是修改内容:
检查您可能拥有的所有其他测试图像并相应地修改参数。
img = cv2.imread("/path/to/your_image")
width=0
height=0
start_x=0
start_y=0
end_x=0
end_y=0
output = img.copy()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gw, gs, gw1, gs1, gw2, gs2 = (3,1.0,7,3.0, 3, 2.0)
img_blur = cv2.GaussianBlur(gray, (gw, gw), gs)
g1 = cv2.GaussianBlur(img_blur, (gw1, gw1), gs1)
g2 = cv2.GaussianBlur(img_blur, (gw2, gw2), gs2)
ret, thg = cv2.threshold(g2-g1, 127, 255, cv2.THRESH_BINARY)
contours, hier = cv2.findContours(thg, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
img_cpy = img.copy()
width=0
height=0
start_x=0
start_y=0
end_x=0
end_y=0
for i in range(len(contours)):
if hier[0][i][2] == -1:
continue
x ,y, w, h = cv2.boundingRect(contours[i])
a=w*h
aspectRatio = float(w)/h
if aspectRatio >= 2.5 and a>600:
approx = cv2.approxPolyDP(contours[i], 0.05* cv2.arcLength(contours[i], True), True)
if len(approx) == 4 and x>15 :
width=w
height=h
start_x=x
start_y=y
end_x=start_x+width
end_y=start_y+height
cv2.rectangle(img_cpy, (start_x,start_y), (end_x,end_y), (0,0,255),3)
cv2.putText(img_cpy, "rectangle "+str(x)+" , " +str(y-5), (x, y-5), cv2.FONT_HERSHEY_COMPLEX, 0.5, (0, 0, 0))
plt.imshow(img_cpy)
print("start",start_x,start_y)
print("end", end_x,end_y)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
176 次 |
| 最近记录: |