我试图检测车牌黑色像素最多的 ROI
下面是车牌上的代码。它基于如何从图像中识别车辆牌照/车牌 (ANPR) 的问题?.
我稍微修改了一下b
import cv2
import numpy as np
import imutils
import sys
import glob
import math
import time
import os
def validate_contour(contour, img, aspect_ratio_range, area_range):
rect = cv2.minAreaRect(contour)
img_width = img.shape[1]
img_height = img.shape[0]
box = cv2.boxPoints(rect)
box = np.int0(box)
X = rect[0][0]
Y = rect[0][1]
angle = rect[2]
width = rect[1][0]
height = rect[1][1]
angle = (angle + 180) if width < height else (angle + 90)
output = False
if (width > 0 and height > 0) and ((width < img_width / 2.0) and (height < img_width / 2.0)):
aspect_ratio = float(width) / height if width > height else float(height) / width
if (aspect_ratio >= aspect_ratio_range[0] and aspect_ratio <= aspect_ratio_range[1]):
if ((height * width > area_range[0]) and (height * width < area_range[1])):
box_copy = list(box)
point = box_copy[0]
del (box_copy[0])
dists = [((p[0] - point[0]) ** 2 + (p[1] - point[1]) ** 2) for p in box_copy]
sorted_dists = sorted(dists)
opposite_point = box_copy[dists.index(sorted_dists[1])]
tmp_angle = 90
if abs(point[0] - opposite_point[0]) > 0:
tmp_angle = abs(float(point[1] - opposite_point[1])) / abs(point[0] - opposite_point[0])
tmp_angle = rad_to_deg(math.atan(tmp_angle))
if tmp_angle <= 45:
output = True
return output
def deg_to_rad(angle):
return angle * np.pi / 180.0
def rad_to_deg(angle):
return angle * 180 / np.pi
def enhance(img):
kernel = np.array([[-1, 0, 1], [-2, 0, 2], [1, 0, 1]])
return cv2.filter2D(img, -1, kernel)
img = cv2.imread('13.jpg')
input_image = imutils.resize(img, width=500)
raw_image = np.copy(input_image)
img_original = input_image.copy()
img_mask = input_image.copy()
lic_plate = input_image.copy()
contoured = input_image.copy()
gray = cv2.cvtColor(img_original, cv2.COLOR_BGR2GRAY)
gray = enhance(gray)
gray = cv2.GaussianBlur(gray, (5, 5), 0)
gray = cv2.Sobel(gray, -1, 1, 0)
h, sobel = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
se = cv2.getStructuringElement(cv2.MORPH_RECT, (16, 4))
binary = cv2.morphologyEx(sobel, cv2.MORPH_CLOSE, se)
ed_img = np.copy(binary)
contours, _ = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
for contour in contours:
aspect_ratio_range = (2.2, 12) # minimum 2.2 , max 12
area_range = (500, 18000)
rectangles = cv2.minAreaRect(contour) # rect = ((center_x,center_y),(width,height),angle)
boxes = cv2.boxPoints(rectangles) # Find four vertices of rectangle from above rect
boxes = np.int0(boxes) # Round the values and make it integers
# print(box)
all_area = cv2.drawContours(contoured, [boxes], 0, (127, 0, 255), 2)
if validate_contour(contour, binary, aspect_ratio_range, area_range):
rect = cv2.minAreaRect(contour)
box = cv2.boxPoints(rect)
box = np.int0(box)
Xs = [i[0] for i in box]
Ys = [i[1] for i in box]
x1 = min(Xs)
x2 = max(Xs)
y1 = min(Ys)
y2 = max(Ys)
angle = rect[2]
if angle < -45:
angle += 90
W = rect[1][0]
H = rect[1][1]
aspect_ratio = float(W) / H if W > H else float(H) / W
center = ((x1 + x2) / 2, (y1 + y2) / 2)
size = (x2 - x1, y2 - y1)
M = cv2.getRotationMatrix2D((size[0] / 2, size[1] / 2), angle, 1.0);
tmp = cv2.getRectSubPix(ed_img, size, center)
tmp = cv2.warpAffine(tmp, M, size)
TmpW = H if H > W else W
TmpH = H if H < W else W
tmp = cv2.getRectSubPix(tmp, (int(TmpW), int(TmpH)), (size[0] / 2, size[1] / 2))
__, tmp = cv2.threshold(tmp, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
sortedplate = cv2.drawContours(img_mask, [box], 0, (127, 0, 255), 2)
white_pixels = 0
for x in range(tmp.shape[0]):
for y in range(tmp.shape[1]):
if tmp[x][y] == 255:
white_pixels += 1
edge_density = float(white_pixels) / (tmp.shape[0] * tmp.shape[1])
tmp = cv2.getRectSubPix(raw_image, size, center)
tmp = cv2.warpAffine(tmp, M, size)
TmpW = H if H > W else W
TmpH = H if H < W else W
tmp = cv2.getRectSubPix(tmp, (int(TmpW), int(TmpH)), (size[0] / 2, size[1] / 2))
# getRectSubPix( = Retrieves a pixel rectangle from an image with sub-pixel accuracy.
if edge_density > 0.5:
cv2.drawContours(input_image, [box], 0, (127, 0, 255), 2)
cv2.imshow('original', img_original)
cv2.imshow('sobel', sobel)
cv2.imshow('binary', binary)
cv2.imshow("all contours", all_area)
cv2.imshow("sorted", sortedplate)
cv2.imshow("detected", lic_plate)
cv2.waitKey(0)