1

我试图检测车牌黑色像素最多的 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)

图像需要检测 的车牌 图像示例lp1 lp2 lp3 lp4

4

0 回答 0