我正在尝试制作一个能够检测物体方向的计算机视觉脚本。它在大多数情况下都有效,但似乎它无法在某些图像上获得相同的成功。
此脚本依赖于模糊和Canny边缘检测来查找轮廓。
工作示例:
对于失败的部分,它有两条相同形状的线条,它完全忽略了其他形状之一。
主要代码:
import cv2
from imgops import imutils
import CVAlgo
z = 'am'
path = 'images/pca.jpg'
#path = 'images/pca2.jpg'
img = cv2.imread(path)
imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img = imutils.resize(img, height = 600)
imgray = imutils.resize(img, height = 600)
final = img.copy()
thresh, imgray = CVAlgo.filtering(img, imgray, z)
__ , contours, hierarchy = cv2.findContours(thresh.copy(),cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
# Iterate through all contours
test = CVAlgo.cnt_gui(final, contours)
#cv2.imwrite('1.jpg', final)
cv2.imshow('thresh', thresh)
cv2.imshow('contours', final)
cv2.waitKey(0)
CVAlgo.py
import cv2
from numpy import *
from pylab import *
from imgops import imutils
import math
def invert_img(img):
img = (255-img)
return img
def canny(imgray):
imgray = cv2.GaussianBlur(imgray, (11,11), 200)
canny_low = 0
canny_high = 100
thresh = cv2.Canny(imgray,canny_low,canny_high)
return thresh
def cnt_gui(img, contours):
cnts = sorted(contours, key = cv2.contourArea, reverse = True)
for i in range(0,len(cnts)):
sel_cnts = sorted(contours, key = cv2.contourArea, reverse = True)[i]
area = cv2.contourArea(sel_cnts)
if area < 1000:
continue
# get orientation angle and center coord
center, axis,angle = cv2.fitEllipse(sel_cnts)
hyp = 100 # length of the orientation line
# Find out coordinates of 2nd point if given length of line and center coord
linex = int(center[0]) + int(math.sin(math.radians(angle))*hyp)
liney = int(center[1]) - int(math.cos(math.radians(angle))*hyp)
# Draw orienation
cv2.line(img, (int(center[0]),int(center[1])), (linex, liney), (0,0,255),5)
cv2.circle(img, (int(center[0]), int(center[1])), 10, (255,0,0), -1)
return img
def filtering(img, imgray, mode):
imgray = cv2.medianBlur(imgray, 11)
thresh = cv2.Canny(imgray,75,200)
return thresh, imgray
有谁知道问题是什么?有谁知道如何改进这个脚本?
答案 0 :(得分:1)
未检测到的形状太靠近黑色背景,因此其轮廓已与白色物体区域的轮廓合并。您在其中一个对象中找到的第二个方向实际上是外轮廓的方向。为了避免这种情况,您可以使用来自cv2.dilate的cv2.dilate函数在阈值处理后扩展或关闭二进制图像。
答案 1 :(得分:1)
我有个建议。因为你已经提取了每个对象 将图像作为轮廓,尝试将椭圆拟合到每个图像中。
然后找到每个椭圆的长轴。
现在找到这些长轴的方向角。