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.
答案 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更改为其他值。