我正在尝试https://github.com/longphungtuan94/ALPR_System中的这段代码,并解决了opencv版本不匹配的大多数问题。但一直无法解决此错误:-
line 61, in segment_characters_from_plate
c = max(cnts, key=cv2.contourArea)
cv2.error: OpenCV(4.2.0) /io/opencv/modules/imgproc/src/shapedescr.cpp:315: error: (-215:Assertion failed) npoints >= 0 && (depth == CV_32F || depth == CV_32S) in function 'contourArea'
曾尝试过什么(但都没有成功):-
OpenCV(4.0.0) assertion failed in function 'contourArea'
OpenCV Contours in Python: How to solve 'list index out of range'
代码如下:-
import cv2
import numpy as np
import imutils
from skimage.filters import threshold_local
from skimage import measure
def sort_contours_left_to_right(character_contours):
"""
Sort contours from left to right
"""
i = 0
boundingBoxes = [cv2.boundingRect(c) for c in character_contours]
(character_contours, boundingBoxes) = zip(*sorted(zip(character_contours, boundingBoxes),
key=lambda b:b[1][i], reverse=False))
return character_contours
def segment_characters_from_plate(plate_img, fixed_width):
"""
extract the Value component from the HSV color space and apply adaptive thresholding
to reveal the characters on the license plate
"""
V = cv2.split(cv2.cvtColor(plate_img, cv2.COLOR_BGR2HSV))[2]
T = threshold_local(V, 29, offset=15, method='gaussian')
thresh = (V > T).astype('uint8') * 255
thresh = cv2.bitwise_not(thresh)
# resize the license plate region to a canoncial size
plate_img = imutils.resize(plate_img, width=fixed_width)
thresh = imutils.resize(thresh, width=fixed_width)
bgr_thresh = cv2.cvtColor(thresh, cv2.COLOR_GRAY2BGR)
bgr_thresh = np.uint8(bgr_thresh)
# perform a connected components analysis and initialize the mask to store the locations
# of the character candidates
labels = measure.label(thresh, neighbors=8, background=0)
charCandidates = np.zeros(thresh.shape, dtype='uint8')
# loof over the unique components
characters = []
for label in np.unique(labels):
# if this is the background label, ignore it
if label == 0:
continue
# otherwise, construct the label mask to display only connected components for the
# current label, then find contours in the label mask
labelMask = np.zeros(thresh.shape, dtype='uint8')
labelMask[labels == label] = 255
cnts = cv2.findContours(labelMask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if imutils.is_cv2() else cnts[1]
# ensure at least one contour was found in the mask
if len(cnts) > 0:
# grab the largest contour which corresponds to the component in the mask, then
# grab the bounding box for the contour
c = max(cnts, key=cv2.contourArea)
(boxX, boxY, boxW, boxH) = cv2.boundingRect(c)
# compute the aspect ratio, solodity, and height ration for the component
aspectRatio = boxW / float(boxH)
solidity = cv2.contourArea(c) / float(boxW * boxH)
heightRatio = boxH / float(plate_img.shape[0])
# determine if the aspect ratio, solidity, and height of the contour pass
# the rules tests
keepAspectRatio = aspectRatio < 1.0
keepSolidity = solidity > 0.15
keepHeight = heightRatio > 0.5 and heightRatio < 0.95
# check to see if the component passes all the tests
if keepAspectRatio and keepSolidity and keepHeight and boxW > 14:
# compute the convex hull of the contour and draw it on the character
# candidates mask
hull = cv2.convexHull(c)
cv2.drawContours(charCandidates, [hull], -1, 255, -1)
_, contours, hier = cv2.findContours(charCandidates, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
if contours:
contours = sort_contours_left_to_right(contours)
characters = []
addPixel = 4 # value to be added to each dimension of the character
for c in contours:
(x,y,w,h) = cv2.boundingRect(c)
if y > addPixel:
y = y - addPixel
else:
y = 0
if x > addPixel:
x = x - addPixel
else:
x = 0
temp = bgr_thresh[y:y+h+(addPixel*2), x:x+w+(addPixel*2)]
characters.append(temp)
return characters
else:
return None
答案 0 :(得分:0)
cv2.findContours
的方法签名随每个主要版本而变化。是
contours, hierarchy = cv2.findContours(...)
image, contours, hierarchy = cv2.findContours(...)
现在,(第一个)问题是以下代码:
cnts = cnts[0] if imutils.is_cv2() else cnts[1]
如果使用的版本是OpenCV 2.x.x,则仅检查cnts[1]
是否也用于OpenCV 4.x.x,此处也应为cnts[0]
。最好将imutils
版本检查替换为以下内容:
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
在方法签名进一步更改之前,这将适用于所有主要版本的OpenCV。
请注意,这里还会发生另一个错误:
_, contours, hier = cv2.findContours(...)
这特定于OpenCV 3.x.x,因此最好也相应地更改该行。
希望有帮助!