python - 为简单环形目标上的弹孔分配分数
问题描述
我目前正在开展一个项目,以检测和评分简单环形目标上的弹孔。我现在拥有的代码根据轮廓的中心为孔分配一个分数。这是我正在使用的目标1
如果轮廓与较高区域的边界重叠,我希望它被分配更高的分数,无论中心在哪里。一个例子如下所示:
] 2
我的程序的代码和输出如下所示,其中分数分别分配给中心而不是重叠边界:
from cv2 import cv2
import numpy as np
import imutils
def centroid(contour):
M = cv2.moments(contour)
cx = int(round(M['m10']/M['m00']))
cy = int(round(M['m01']/M['m00']))
centre = (cx, cy)
return centre
def getScore(scoreboundaries, HoleDist): #function to assign a score to each hole
score = 0
if scoreboundaries[0]>HoleDist:
score = 10
for i in range(1, len(scoreboundaries)):
if scoreboundaries[i-1]<=HoleDist<scoreboundaries[i]:
score = len(scoreboundaries) - i
return score
default = cv2.imread("3.jpg")
img = cv2.resize(default,(640,640))
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h,s,v = cv2.split(hsv)
v_mask = cv2.inRange(v, 0, 155)
cnts = cv2.findContours(v_mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
for c in cnts:
if cv2.contourArea(c) > 10000:
cv2.drawContours(img, [c], -1, (0, 255, 0), 2)
area_max = cv2.contourArea(c)
radius_max = np.sqrt(area_max / np.pi)
section_size = radius_max / 9
centre_v_mask = cv2.inRange(v, 215, 255)
cnts = cv2.findContours(centre_v_mask.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
for c in cnts:
if cv2.contourArea(c) > 10:
centre_coords = centroid(c)
h_mask = cv2.inRange(h, 0, 30)
h_mask = cv2.medianBlur(h_mask, 11)
cnts = cv2.findContours(h_mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
holes = []
HoleDists = []
scoreboundaries = []
for i in range(1,10): #calculate other rings
cv2.circle(img, centre_coords, int(i*(section_size)), (255, 0, 0), 1)
scoreboundaries.append(int(i*(section_size)))
for c in cnts: #plot bullet holes
if cv2.contourArea(c) > 1:
x,y,w,h = cv2.boundingRect(c)
pts =[(x, y), (x+w, y), (x, y+h), (x+w, y+h)]
centre_holes = centroid(c)
pts.append(centre_holes)
pointscore = 0
for pt in pts:
X = pt[0]
Y = pt[1]
HoleDist = np.sqrt((X-centre_coords[0])**2 + (Y - centre_coords[1])**2)
HoleDists.append(HoleDist)
score = getScore(scoreboundaries, HoleDist)
if score>pointscore:
pointScore = score
cv2.circle(img, (centre_holes), 1, (0, 0, 255), -1)
cv2.rectangle(img, (x,y),(x+w,y+h),(0,0,255),2)
cv2.drawContours(img, [c], -1, (0, 255, 0), 1)
cv2.putText(img, "Score: " + str(pointScore), (centre_holes[0] - 20, centre_holes[1] + 20),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
cv2.imshow('frame', img)
cv2.waitKey(0)
我想知道我哪里出错了。感谢所有帮助,谢谢。
解决方案
这是一个经典的 Python 错误。您在以下几行大写pointscore
:
pointScore = score
cv2.putText( img, "Score: " + str(pointScore) ....
所以你真的只是使用你看到的最后一个分数,因为pointscore
总是0
和pointScore = score
。
这是修复了这两个错别字的图片。还要记住,OpenCV 轮廓只是一组连接在一起的点。如果需要,您可以使用相同的评分代码来迭代轮廓点。
如果你想换成使用轮廓点,这是一个很小的变化。
改变这个:
for pt in pts:
X = pt[0]
Y = pt[1]
对此:
for pt in c:
pt = pt[0] # contour points have an extra pair of brackets [[x,y]]
X = pt[0]
Y = pt[1]
推荐阅读
- command - CQRS - Command Store persisting rule
- javascript - 复选框和文本显示
- c++ - macOS application file association
- r - r data.table grep error with large file but not with example
- pyspark - How to load all records that were already published from Kafka?
- c# - 用于输入 url 以插入 url 的 xpath
- javascript - 冲突:多个块将资产发射到相同的文件名 ./plugin.min.css
- unix - 如何使用 AWK 将文件名中的数字附加到 csv 的前面
- jenkins - Jenkins:即使构建失败,管道也总是返回“SUCCESS”
- java - Collections.sort() 不使用 compareTo Override 进行排序