Trying to modify OpenCV contour results in error

时间:2019-01-09 22:24:34

标签: python opencv

I am trying to make a custom algorithm to straighten contours, however the way I am currently doing things crashes my program.

The program itself is:

import numpy as np
import cv2
import copy
from matplotlib import pyplot as plt


def IsInLine(point, origin, dir):
    if dir[0][0] == 0 or dir[0][1] == 0:
        return False
    t1 = (point[0][0] - origin[0][0]) / dir[0][0]
    t2 = (point[0][1] - origin[0][1]) / dir[0][1]

    if abs(t1 - t2) < 10:
        return True
    else:
        return False

def StraightenContour(contour):

    new_contour = []
    if len(contour) < 100:
        return

    for i in range(0, len(contour)):
        line1 = contour[i-1] - contour[i-2]
        line2 = contour[(i+2)%len(contour)] - contour[(i+1)%len(contour)]

        if IsInLine(contour[i], contour[i-1], line1) and IsInLine(contour[i], contour[(i+2)%len(contour)], line2):
            new_contour.append([[0,0]])

    print(contour)
    return contour


img = cv2.imread('Kitchen.png')
imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(img, 100, 200)

kernel = np.ones((5,5),np.uint8)
edges = cv2.morphologyEx(
    edges, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5)), iterations = 5)

ret, thresh = cv2.threshold(edges, 127, 255, 0)
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

img_area = im2.shape[0] * im2.shape[1]
for contour in contours:
    contour = StraightenContour(contour)
    if cv2.contourArea(contour) / img_area > 0.22:
        cv2.drawContours(img, [contour], 0, (0, 255, 0), 3)
    else:
        cv2.drawContours(img, [contour], 0, (0, 0, 255), 3)

cv2.imshow('image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

The problem specifically occurs when I try to return the original contour at the end of StraightenContour()

My program crashes with message:

Traceback (most recent call last):
  File "cexp.py", line 79, in <module>
    if cv2.contourArea(contour) / img_area > 0.22:
cv2.error: OpenCV(3.4.5) /io/opencv/modules/imgproc/src/shapedescr.cpp:272: error: (-215:Assertion failed) npoints >= 0 && (depth == CV_32F || depth == CV_32S) in function 'contourArea'

if instead I modify the line such that:

 contour = StraightenContour(contour)

Becomes: StraightenContour(contour)

No such problem occurs.

I am very confused as I am not even touching the contour, just returning it.

I need to either solve this issue, or find a way to delete points from a contour.

Thanks in advance.

1 个答案:

答案 0 :(得分:1)

将输出保存为contour = StraightenContour(contour)之类时,如果轮廓小于100,则可能返回NULL。

对NULL的下一个操作将产生该错误。尝试通过在print(len(contour))函数的开头放置StraightenContour(contour)进行调试,并且最有可能的轮廓将小于100,从而使函数返回NULL。

如果您没有将StraightenContour(contour)的输出保存在可变轮廓中,则当len(contour)<100不会在返回时在任何地方保存NULL,其余代码将正常运行。 >

解决方案是简单地return contour,当其长度小于100时。也许您可能想通过进行一些实验来找到最佳值来考虑将100更改为其他值。