2

我正在尝试制作一个检测对象方向的计算机视觉脚本。它在大多数情况下都有效,但似乎无法对某些图像取得同样的成功。

该脚本依靠模糊和 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

有谁知道问题是什么?有人知道我可以如何改进这个脚本吗?

4

2 回答 2

2

未检测到的形状太接近黑色背景,因此其轮廓已与白色对象区域的轮廓合并。您在其中一个对象中找到的第二个方向实际上是外轮廓的方向。为了规避其中的一些问题,您可以在使用 cv2.dilate 函数从以下位置进行阈值处理后扩大或关闭二值图像:cv2.dilate

于 2015-12-26T17:57:35.823 回答
1
  1. 我有一个建议。由于您已将图像中的每个对象提取为轮廓,因此请尝试为每个对象拟合一个椭圆。

  2. 然后找到每个椭圆的长轴。

  3. 现在找到这些主轴的方向角。

于 2017-01-19T14:10:07.500 回答