python3+opencv

# -*- coding: utf-8 -*-
# [email protected]
import sys
import cv2
import numpy as np

def preprocess(gray):
    # # 直方图均衡化
    # equ = cv2.equalizeHist(gray)
    # 高斯平滑
    gaussian = cv2.GaussianBlur(gray, (3, 3), 0, 0, cv2.BORDER_DEFAULT)
    cv2.imwrite('c:/img/gaussian.jpg',gaussian)
    # 中值滤波
    median = cv2.medianBlur(gaussian, 5)
    cv2.imwrite('c:/img/median.jpg', median)
    # Sobel算子,X方向求梯度
    sobel = cv2.Sobel(median, cv2.CV_8U, 1, 0, ksize=3)
    cv2.imwrite('c:/img/sobel.jpg', sobel)
    # 二值化
    # ret, binary = cv2.threshold(sobel, 127, 255, cv2.THRESH_BINARY|cv2.THRESH_OTSU)
    ret, binary = cv2.threshold(sobel, 127, 255, cv2.THRESH_BINARY)
    cv2.imwrite('c:/img/binary.jpg', binary)

    ret, thresh2 = cv2.threshold(sobel, 127, 255, cv2.THRESH_BINARY_INV)
    cv2.imwrite('c:/img/thresh2.jpg', thresh2)
    ret, thresh3 = cv2.threshold(sobel, 127, 255, cv2.THRESH_TRUNC)
    cv2.imwrite('c:/img/thresh3.jpg', thresh3)
    ret, thresh4 = cv2.threshold(sobel, 127, 255, cv2.THRESH_TOZERO)
    cv2.imwrite('c:/img/thresh4.jpg', thresh4)
    ret, thresh5 = cv2.threshold(sobel, 127, 255, cv2.THRESH_TOZERO_INV)
    cv2.imwrite('c:/img/thresh5.jpg', thresh5)

    # 膨胀和腐蚀操作的核函数
    element1 = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 1))
    element2 = cv2.getStructuringElement(cv2.MORPH_RECT, (21, 7))
    # 膨胀一次,让轮廓突出
    dilation = cv2.dilate(binary, element2, iterations=1)
    cv2.imwrite('c:/img/dilation.jpg', dilation)
    # 腐蚀一次,去掉细节
    erosion = cv2.erode(dilation, element1, iterations=1)
    cv2.imwrite('c:/img/erosion.jpg', erosion)
    # 再次膨胀,让轮廓明显一些
    dilation2 = cv2.dilate(erosion, element2, iterations=3)
    cv2.imwrite('c:/img/dilation2.jpg', dilation2)
    # cv2.imshow('dilation2', dilation2)
    # cv2.waitKey(0)
    return dilation2
def findPlateNumberRegion(img):
    region = []
    # 查找轮廓
    _a,contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    # 筛选面积小的
    for i in range(len(contours)):
        cnt = contours[i]
        # 计算该轮廓的面积
        area = cv2.contourArea(cnt)
        # 面积小的都筛选掉
        if (area < 1):
            continue
        # 轮廓近似,作用很小
        epsilon = 0.001 * cv2.arcLength(cnt, True)
        approx = cv2.approxPolyDP(cnt, epsilon, True)
        # 找到最小的矩形,该矩形可能有方向
        rect = cv2.minAreaRect(cnt)
        print ("rect is: ",rect)
        # box是四个点的坐标
        box = cv2.boxPoints(rect)
        box = np.int0(box)
        # 计算高和宽
        height = abs(box[0][1] - box[2][1])
        width = abs(box[0][0] - box[2][0])
        # 车牌正常情况下长高比在2.7-5之间
        ratio = float(width) / float(height)
        print(ratio)
        # if (ratio > 20 or ratio < 2):
        #     continue
        region.append(box)
    return region
def detect(img):
    # 转化成灰度图
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    cv2.imwrite('c:/img/gray.jpg',gray)
    # 形态学变换的预处理
    dilation = preprocess(gray)
    # 查找车牌区域
    region = findPlateNumberRegion(dilation)
    print('----------------------------------------------------------')
    print(len(region))
    # 用绿线画出这些找到的轮廓
    v=0
    for box in region:
        v+=1
        cv2.drawContours(img, [box], 0, (0, 255, 0), 2)
        ys = [box[0, 1], box[1, 1], box[2, 1], box[3, 1]]
        xs = [box[0, 0], box[1, 0], box[2, 0], box[3, 0]]
        ys_sorted_index = np.argsort(ys)
        xs_sorted_index = np.argsort(xs)

        x1 = box[xs_sorted_index[0], 0]
        x2 = box[xs_sorted_index[3], 0]

        y1 = box[ys_sorted_index[0], 1]
        y2 = box[ys_sorted_index[3], 1]

        img_org2 = img.copy()
        img_plate = img_org2[y1:y2, x1:x2]
        cv2.imwrite("c:/img/"+str(v)+".jpg",img_plate)

    # 带轮廓的图片
    cv2.imwrite('c:/img/0.jpg', img)
    cv2.imwrite('c:/img/contours.png', img)
    # cv2.imshow('带轮廓的图片',img)
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()
if __name__ == '__main__':
    imagePath = 'c:/1.jpg'
    img = cv2.imread(imagePath)
    detect(img)

你可能感兴趣的:(python3+opencv)