Я пробую этот код из 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) утверждение не выполнено в функции 'contourArea'
OpenCV Контуры в Python: как решить 'индекс списка вне диапазона'
(- 215: утверждение не выполнено) npoints> = 0 && (глубина == CV_32F || глубина == CV_32S) в функции 'contourArea'
Код выглядит следующим образом : -
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