diff --git a/main(final).py b/main(final).py deleted file mode 100644 index 74d570e..0000000 --- a/main(final).py +++ /dev/null @@ -1,334 +0,0 @@ -import numpy as np -import cv2 -import matplotlib.pyplot as plt -from matplotlib import font_manager -import ddddocr -import threadsafe_tkinter as tk -from tkinter import filedialog -font_path = "C:/Users/Lenovo/Downloads/OPPOSans3.0/OPPOSans-Regular.ttf" - -# 动态添加字体到 matplotlib 的字体列表 -font = font_manager.FontProperties(fname=font_path) - - - - -class Get_license(): - - #图像拉伸函数 - def stretch(self, img): - - maxi = float(img.max()) - mini = float(img.min()) - - for i in range(img.shape[0]): - for j in range(img.shape[1]): - img[i, j] = (255 / (maxi - mini) * img[i, j] - (255 * mini) / (maxi - mini)) - - return img - - #二值化处理函数 - def dobinaryzation(self, img): - # 使用OpenCV的自动阈值方法 - ret, thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) - return thresh - - #寻找矩形的轮廓 - def find_rectangle(self, contour): - - y, x = [],[] - - for p in contour: - y.append(p[0][0]) - x.append(p[0][1]) - - return [min(y), min(x), max(y), max(x)] - - #定位车牌号 - def locate_license(self, img, afterimg): - - contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) - - #找出最大的三个区域 - block = [] - for c in contours: - #找出轮廓的左上点和右下点 - #由此计算它的面积和长度比 - r = self.find_rectangle(c) - a = (r[2] - r[0]) * (r[3] - r[1]) #面积 - s = (r[2] - r[0]) * (r[3] - r[1]) #长度比 - - block.append([r, a, s]) - - #选出面积最大的3个区域 - block = sorted(block, key=lambda b: b[1])[-3:] - - #使用颜色识别判断找出最像车牌的区域 - maxweight, maxindex = 0, -1 - for i in range(len(block)): - b = afterimg[block[i][0][1]:block[i][0][3], block[i][0][0]:block[i][0][2]] - hsv = cv2.cvtColor(b, cv2.COLOR_BGR2HSV) - lower = np.array([100, 50, 50]) - upper = np.array([140, 255, 255]) - mask = cv2.inRange(hsv, lower, upper) - - # 计算mask中白色像素(即HSV范围内的像素)的数量 - weight = np.sum(mask == 255) # 或者简单地使用 np.count_nonzero(mask) - - # 选出最大权值的区域 - if weight > maxweight: - maxindex = i - maxweight = weight - - return block[maxindex][0] - - #预处理函数 - def find_license(self, img): - - m = 400 * img.shape[0] / img.shape[1] - - #压缩图像 - img = cv2.resize(img, (400, int(m)), interpolation=cv2.INTER_CUBIC) - - #BGR转换为灰度图像 - gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) - - #灰度拉伸 - stretchedimg = self.stretch(gray_img) - - '''进行开运算,用来去除噪声''' - r = 16 - h = w = r * 2 + 1 - kernel = np.zeros((h, w), np.uint8) - cv2.circle(kernel, (r, r), r, 1, -1) - - openingimg = cv2.morphologyEx(stretchedimg, cv2.MORPH_OPEN, kernel) - - strtimg = cv2.absdiff(stretchedimg, openingimg) - - #图像二值化 - binaryimg = self.dobinaryzation(strtimg) - - #canny边缘检测 - canny = cv2.Canny(binaryimg, binaryimg.shape[0], binaryimg.shape[1]) - - '''消除小的区域,保留大块的区域,从而定位车牌''' - #进行闭运算 - kernel = np.ones((5, 17), np.uint8) - closingimg = cv2.morphologyEx(canny, cv2.MORPH_CLOSE, kernel) - - #进行开运算 - openingimg = cv2.morphologyEx(closingimg, cv2.MORPH_OPEN, kernel) - - #再次进行开运算 - #kernel = np.ones((5, 5), np.uint8) - #openingimg=cv2.morphologyEx(openingimg,cv2.MORPH_CLOSE,kernel) - #openingimg = cv2.morphologyEx(openingimg, cv2.MORPH_OPEN, kernel) - - #消除小区域,定位车牌位置 - rect = self.locate_license(openingimg, img) - - return rect, img - #图像分割函数 - def cut_license(self, afterimg, rect): - - #转换为宽度和高度 - rect[2] = rect[2] - rect[0] - rect[3] = rect[3] - rect[1] - rect_copy = tuple(rect.copy()) - #创建掩膜 - mask = np.zeros(afterimg.shape[:2], np.uint8) - #创建背景模型 大小只能为13*5,行数只能为1,单通道浮点型 - bgdModel = np.zeros((1, 65), np.float64) - #创建前景模型 - fgdModel = np.zeros((1, 65), np.float64) - #分割图像 - cv2.grabCut(afterimg, mask, rect_copy, bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_RECT) - mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8') - img_show = afterimg * mask2[:, :, np.newaxis] - - return img_show - - -class Segmentation(): - def __init__(self, cutimg): - - #1、读取图像,并把图像转换为灰度图像并显示 - - img_gray = cv2.cvtColor(cutimg, cv2.COLOR_BGR2GRAY) #转换了灰度化 - - #2、将灰度图像二值化,设定阈值是100 - self.img_thre = img_gray - cv2.threshold(img_gray, 150 - , 255, cv2.THRESH_BINARY_INV, self.img_thre) - - #cv2.waitKey(0) - - #3、保存黑白图片 - cv2.imwrite('thre_res.jpg', self.img_thre) - - #4、分割字符 - self.white = [] #记录每一列的白色像素总和 - self.black = [] #黑色 - self.height = self.img_thre.shape[0] - self.width = self.img_thre.shape[1] - self.white_max = 0 - self.black_max = 0 - #计算每一列的黑白色像素总和 - for i in range(self.width): - white_count = 0 #这一列白色总数 - black_count = 0 #这一列黑色总数 - for j in range(self.height): - if self.img_thre[j][i] == 255: - white_count += 1 - if self.img_thre[j][i] == 0: - black_count += 1 - self.white_max = max(self.white_max, white_count) - self.black_max = max(self.black_max, black_count) - self.white.append(white_count) - self.black.append(black_count) - - self.arg = False #False表示白底黑字;True表示黑底白字 - if self.black_max > self.white_max: - self.arg = True - - def heibai(self): - return self.img_thre - - - def find_end(self, start_): - end_ = start_ + 1 - for m in range(start_ + 1, self.width - 1): - if (self.black[m] if self.arg else self.white[m]) > ( - 0.85 * self.black_max if self.arg else 0.85 * self.white_max): - end_ = m - break - return end_ - - def display(self): - #img_list = [] - n = 1 - plt.figure() - img_num = 0 - while n < self.width - 2: - n += 1 - if (self.white[n] if self.arg else self.black[n]) > ( - 0.15 * self.white_max if self.arg else 0.15 * self.black_max): - #上面这些判断用来辨别是白底黑字还是黑底白字 - - start = n - end = self.find_end(start) - n = end - - if end - start > 5: - cj = self.img_thre[1:self.height, start:end] - img_num += 1 - cj = cv2.cvtColor(cj, cv2.COLOR_RGB2BGR) - - plt.figure(2) - plt.subplot(2, 4, img_num) - plt.title('{}'.format(img_num)) - plt.imshow(cj) - plt.show() - return self.img_thre - - -if __name__ == '__main__': - - def select_image(): - # 弹出文件选择对话框,限制文件类型为图片 - file_path = filedialog.askopenfilename() - if file_path: - # 将文件路径显示在标签上 - img = cv2.imread(file_path) - img1 = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) - # 绘图 - plt.figure(1) - plt.suptitle('车牌识别', fontproperties=font) - plt.subplot(2, 3, 1) - plt.title('原始图像', fontproperties=font) - plt.imshow(img1) - - # 预处理图像 - license = Get_license() - rect, afterimg = license.find_license(img) - afterimg = cv2.cvtColor(afterimg, cv2.COLOR_RGB2BGR) - - plt.subplot(2, 3, 2) - plt.title('预处理后图像', fontproperties=font) - plt.imshow(afterimg) - - # 车牌号打框 - cv2.rectangle(afterimg, (rect[0], rect[1]), (rect[2], rect[3]), (0, 255, 0), 1) - x1, y1, x2, y2 = int(rect[0]), int(rect[1]), int(rect[2]), int(rect[3]) - - plt.subplot(2, 3, 3) - plt.title('车牌框出', fontproperties=font) - plt.imshow(afterimg) - - # 背景去除 - cutimg = license.cut_license(afterimg, rect) - plt.subplot(2, 3, 4) - plt.title('车牌背景去除', fontproperties=font) - plt.imshow(cutimg) - # print(int(_rect[0]), int(_rect[3]), int(_rect[2]), int(_rect[1])) - - # 开始分割车牌 - # cutimg = cutimg[140:165, 151:240] - cutimg = cutimg[y1 + 3:y2 - 3, x1 - 1:x2 - 3] - # cutimg = cutimg[int(_rect[0]):int(_rect[3]),int(_rect[2]):int(_rect[1])] - - height, width = cutimg.shape[:2] - cutimg1 = cv2.resize(cutimg, (2 * width, 2 * height), interpolation=cv2.INTER_CUBIC) - plt.subplot(2, 3, 5) - plt.title('分割车牌与背景', fontproperties=font) - plt.imshow(cutimg) - - # 字符切割 - seg = Segmentation(cutimg) - plt.subplot(2, 3, 6) - img_hei = seg.heibai() - img_hei = cv2.cvtColor(img_hei, cv2.COLOR_RGB2BGR) - plt.title('车牌二值化处理', fontproperties=font) - plt.imshow(img_hei) - seg.display() - plt.show() - - # 打印车牌 - ocr = ddddocr.DdddOcr() - with open('thre_res.jpg', 'rb') as f: - image = f.read() - res = ocr.classification(image) - print(res) - - - - - # 创建根窗口 - root = tk.Tk() - root.title('车牌识别程序') - root.geometry('600x450') - # 创建一个标签用于显示图片路径 - label = tk.Label(root, text='未选择图片') - label.pack(pady=20) # 使用pack布局管理器,并添加一些垂直填充 - - - def exit_app(): - # 退出应用程序的函数 - root.destroy() - # 创建一个按钮,点击时会调用select_image函数 - button = tk.Button(root, text='选择图片', command=select_image) - button.pack() - button_exit = tk.Button(root, text='退出', command=exit_app) - button_exit.pack(pady=30) - # 启动事件循环 - root.mainloop() - - - - - - - - -