python - openCV多边形检测
问题描述
(所有图像都是这种格式:绿色矩形和蓝色圆圈)。圆圈代表数字的二进制表示。任务是检测圆圈后输出十进制数。
我的方法是先找到绿色矩形(我没有使用颜色遮罩,原因稍后解释)并获得它的宽度和高度。
接下来,我根据对称性推断圆的中心必须w/8,3w/8,5w/8
与7w/8
矩形的左边缘相距一定距离。(水平)。
所以,我使用HoughCircles()
了方法,然后尝试用(2x-1)w/8
. 显然,每个圆圈的十进制等值由exp=2^(4-x).
所以,我用来n+=2**exp
获得十进制表示。
我还使用矩形的坐标来近似 HoughCircles() 方法的适当 minRadius 和 maxRadius 值,以便不检测不必要的圆。
import numpy as np
import cv2 as cv
img = cv.imread("7.jpeg")
img_height,img_w,c=img.shape
n=0 #stores the decimal rep.
width=0 #dimensions of the rectangle
height=0
start_x=0 #starting coordinates of the rectangle
start_y=0
end_x=0 #ending '''''''
end_y=0
minr=0 #for the houghCircles() method
maxr=0
mind=0
output = img.copy()
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
_, th = cv.threshold(gray, 240, 255, cv.THRESH_BINARY)
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]
if len(approx) == 4 and x>15 :
x1 ,y1, w, h = cv.boundingRect(approx)
aspectRatio = float(w)/h
if aspectRatio <= 0.95 or aspectRatio >= 1.05:
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(x)+" , " +str(y-5), (x, y-5), cv.FONT_HERSHEY_COMPLEX, 0.5, (0, 0, 0))
minr=int(17*width/192)
maxr=int(7*width/64)
mind=int(width//5)
print("start",start_x,start_y)
print("width",width)
print("height",height)
print("minr", minr)
print("maxr",maxr)
print("mind",mind)
gray = cv.medianBlur(gray, 5)
circles = cv.HoughCircles(gray, cv.HOUGH_GRADIENT, 1, mind,param1=50, param2=30, minRadius=minr, maxRadius=maxr)
detected_circles = np.uint16(np.around(circles))
for (x, y ,r) in detected_circles[0, :]:
if(y>start_y and x>start_x):
print("center ", x,y)
idx= int (((x-start_x)*8)//width)
exp=int(4- (0.5* (idx+1)))
n+= 2**exp
cv.circle(output, (x, y), r, (0, 0, 0), 3)
cv.circle(output, (x, y), 2, (0, 255, 255), 3)
print(n)
cv.imshow('output',output)
cv.waitKey(0)
cv.destroyAllWindows()
对于这种类型的所有图像,这非常有效。但是,有一个小缺点:
测试图像的格式非常“漂亮”:所有图像都具有固定的宽度和高度,完全直立,每个图像中矩形和圆形的所有颜色在所有图像中都具有完全相同的阴影,等等。
然而,我们应该让代码更通用一点:为了也容纳“不太好”的图像。例如,这种风格的图像:
基本上相同的格式,但背景照明 + 支架不是完全直立的,这使得概括代码更具挑战性,我觉得。这就是我避免使用 HSV 颜色遮罩的原因,因为不会有一组适合所有图像的更高和更低的值。
但是,我尝试做的也失败了:它无法正确检测到矩形。我希望它能够检测到多个矩形,但是它在那些根本没有矩形的位置(而不是在有矩形的位置)检测矩形。
如何调整我的代码以使其更通用,以便正确处理第二种类型的图像?
解决方案
推荐阅读
- c++ - 查找标记为 Extern C 的 Visual Studio 标准库函数的源代码
- python - 如何在 ML.NET 上加载和运行 Intel-Tensorflow 模型
- nexus3 - wget nexus3 repo 链接返回 HTML 而不是 JSON
- python - 如何在 Bert 分类中获得预测准确度分数
- linux - 无法从第一个脚本/bash 自动运行第二个脚本/bash
- c++ - 如何在Arduino中从索引n打印char数组
- php - 如何将 JSON 数据从 CodeIgniter 返回到 Google Apps 脚本?
- swagger-ui - Swagger UI 禁用试用按钮
- javascript - 显示 none 不能使用 Ajax 动态处理 Id
- google-calendar-api - Google 助理模块不显示我的日历