liuwenzhe 6 months ago
parent 94f4de5b2e
commit baff77c028

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Before

Width:  |  Height:  |  Size: 239 KiB

After

Width:  |  Height:  |  Size: 239 KiB

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

@ -3,7 +3,9 @@ import cv2
from matplotlib import pyplot as plt from matplotlib import pyplot as plt
import os import os
import numpy as np import numpy as np
import tkinter as tk
from tkinter import ttk
from PIL import ImageTk, Image
# plt显示彩色图片 # plt显示彩色图片
def plt_show0(img): def plt_show0(img):
@ -27,11 +29,14 @@ def gray_guss(image):
return gray_image return gray_image
# 读取待检测图片 # 读取待检测图片
origin_image = cv2.imread('../chepai1.jpg') origin_image = cv2.imread('../xiangA.jpg')
# 复制一张图片,在复制图上进行图像操作,保留原图 # 复制一张图片,在复制图上进行图像操作,保留原图
image = origin_image.copy() image = origin_image.copy()
# 图像去噪灰度处理 # 图像去噪灰度处理
gray_image = gray_guss(image) gray_image = gray_guss(image)
# x方向上的边缘检测增强边缘信息 # x方向上的边缘检测增强边缘信息
Sobel_x = cv2.Sobel(gray_image, cv2.CV_16S, 1, 0) Sobel_x = cv2.Sobel(gray_image, cv2.CV_16S, 1, 0)
absX = cv2.convertScaleAbs(Sobel_x) absX = cv2.convertScaleAbs(Sobel_x)
@ -39,27 +44,35 @@ image = absX
# 图像阈值化操作——获得二值化图 # 图像阈值化操作——获得二值化图
ret, image = cv2.threshold(image, 0, 255, cv2.THRESH_OTSU) ret, image = cv2.threshold(image, 0, 255, cv2.THRESH_OTSU)
# 显示灰度图像 # 显示灰度图像
plt_show(image) plt_show(image)
# 形态学(从图像中提取对表达和描绘区域形状有意义的图像分量)——闭操作 # 形态学(从图像中提取对表达和描绘区域形状有意义的图像分量)——闭操作
kernelX = cv2.getStructuringElement(cv2.MORPH_RECT, (30, 10)) kernelX = cv2.getStructuringElement(cv2.MORPH_RECT, (30, 10))
image = cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernelX,iterations = 1) image = cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernelX,iterations = 1)
# 显示灰度图像 # 显示灰度图像
plt_show(image) plt_show(image)
# 腐蚀erode和膨胀dilate # 腐蚀erode和膨胀dilate
kernelX = cv2.getStructuringElement(cv2.MORPH_RECT, (50, 1)) kernelX = cv2.getStructuringElement(cv2.MORPH_RECT, (50, 1))
kernelY = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 20)) kernelY = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 20))
#x方向进行闭操作抑制暗细节 #x方向进行闭操作抑制暗细节
image = cv2.dilate(image, kernelX) image = cv2.dilate(image, kernelX)
image = cv2.erode(image, kernelX) image = cv2.erode(image, kernelX)
#y方向的开操作 #y方向的开操作
image = cv2.erode(image, kernelY) image = cv2.erode(image, kernelY)
image = cv2.dilate(image, kernelY) image = cv2.dilate(image, kernelY)
# 中值滤波(去噪) # 中值滤波(去噪)
image = cv2.medianBlur(image, 21) image = cv2.medianBlur(image, 21)
# 显示灰度图像 # 显示灰度图像
plt_show(image) plt_show(image)
# 获得轮廓 # 获得轮廓
contours, hierarchy = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) contours, hierarchy = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
@ -77,11 +90,12 @@ for item in contours:
#车牌字符分割 #车牌字符分割
# 图像去噪灰度处理 # 图像去噪灰度处理
gray_image = gray_guss(image) gray_image = gray_guss(image)
# 图像阈值化操作——获得二值化图 # 图像阈值化操作——获得二值化图
ret, image = cv2.threshold(gray_image, 0, 255, cv2.THRESH_OTSU) ret, image = cv2.threshold(gray_image, 0, 255, cv2.THRESH_OTSU)
plt_show(image) plt_show(image)
#膨胀操作,使“”字膨胀为一个近似的整体,为分割做准备 #膨胀操作,使“”字膨胀为一个近似的整体,为分割做准备
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2)) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
image = cv2.dilate(image, kernel) image = cv2.dilate(image, kernel)
plt_show(image) plt_show(image)
@ -90,6 +104,7 @@ plt_show(image)
contours, hierarchy = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) contours, hierarchy = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
words = [] words = []
word_images = [] word_images = []
#对所有轮廓逐一操作 #对所有轮廓逐一操作
for item in contours: for item in contours:
word = [] word = []
@ -98,14 +113,21 @@ for item in contours:
y = rect[1] y = rect[1]
weight = rect[2] weight = rect[2]
height = rect[3] height = rect[3]
word.append(x) word.append(x)
word.append(y) word.append(y)
word.append(weight) word.append(weight)
word.append(height) word.append(height)
words.append(word) words.append(word)
# 排序车牌号有顺序。words是一个嵌套列表 # 排序车牌号有顺序。words是一个嵌套列表
words = sorted(words,key=lambda s:s[0],reverse=False) words = sorted(words,key=lambda s:s[0],reverse=False)
i = 0 i = 0
#word中存放轮廓的起始点和宽高 #word中存放轮廓的起始点和宽高
for word in words: for word in words:
# 筛选字符的轮廓 # 筛选字符的轮廓
@ -113,8 +135,8 @@ for word in words:
i = i+1 i = i+1
splite_image = image[word[1]:word[1] + word[3], word[0]:word[0] + word[2]] splite_image = image[word[1]:word[1] + word[3], word[0]:word[0] + word[2]]
word_images.append(splite_image) word_images.append(splite_image)
print(i) #print(i)
print(words) #print(words)
for i,j in enumerate(word_images): for i,j in enumerate(word_images):
plt.subplot(1,7,i+1) plt.subplot(1,7,i+1)
@ -124,9 +146,12 @@ plt.show()
#模版匹配 #模版匹配
# 准备模板(template[0-9]为数字模板;) # 准备模板(template[0-9]为数字模板;)
template = ['0','1','2','3','4','5','6','7','8','9', template = ['0','1','2','3','4','5','6','7','8','9',
'A','B','C','D','E','F','G','H','J','K','L','M','N','P','Q','R','S','T','U','V','W','X','Y','Z', 'A','B','C','D','E','F','G','H','J','K',
'','','','','','','','','','','','','','','','','','','', 'L','M','N','P','Q','R','S','T','U','V',
'','','','','','','','','','','',''] 'W','X','Y','Z','','','','','',
'','','','','','','','','',
'','','','','','','','','',
'','','','','','','','']
# 读取一个文件夹下的所有图片,输入参数是文件名,返回模板文件地址列表 # 读取一个文件夹下的所有图片,输入参数是文件名,返回模板文件地址列表
def read_directory(directory_name): def read_directory(directory_name):
@ -234,16 +259,18 @@ def template_matching(word_images):
word_images_ = word_images.copy() word_images_ = word_images.copy()
# 调用函数获得结果 # 调用函数获得结果
result = template_matching(word_images_) result = template_matching(word_images_)
print(result) #print(result)
# "".join(result)函数将列表转换为拼接好的字符串,方便结果显示 # "".join(result)函数将列表转换为拼接好的字符串,方便结果显示
print( "".join(result)) #print( "".join(result))
from PIL import ImageFont, ImageDraw, Image from PIL import ImageFont, ImageDraw, Image
height,weight = origin_image.shape[0:2] height,weight = origin_image.shape[0:2]
print(height) #print(height)
print(weight) #print(weight)
image_1 = origin_image.copy() image_1 = origin_image.copy()
cv2.rectangle(image_1, (int(0.2*weight), int(0.75*height)), (int(weight*0.9), int(height*0.95)), (0, 255, 0), 5) cv2.rectangle(image_1, (int(0.2*weight), int(0.75*height)), (int(weight*0.9), int(height*0.95)), (0, 255, 0), 5)
@ -257,6 +284,26 @@ draw = ImageDraw.Draw(img_pil)
#绘制文字信息 #绘制文字信息
draw.text((int(0.2*weight)+25, int(0.75*height)), "".join(result), font = font, fill = (255, 255, 0)) draw.text((int(0.2*weight)+25, int(0.75*height)), "".join(result), font = font, fill = (255, 255, 0))
bk_img = np.array(img_pil) bk_img = np.array(img_pil)
print(result) #print(result)
print( "".join(result)) print( "".join(result))
plt_show0(bk_img) plt_show0(bk_img)
# 使用PIL将numpy数组转换为Image对象
image_tk = Image.fromarray(cv2.cvtColor(bk_img, cv2.COLOR_BGR2RGB))
# 初始化Tkinter窗口
root = tk.Tk()
root.title("车牌识别结果")
# 将Image对象转换为Tkinter支持的PhotoImage对象
photo_image = ImageTk.PhotoImage(image_tk)
# 创建标签以显示图像
label = ttk.Label(root, image=photo_image)
label.pack() # 将标签添加到窗口中并自动调整大小
# 防止Tkinter在图像数据被垃圾回收时删除图像
label.image = photo_image
# 运行Tkinter事件循环
root.mainloop()

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Loading…
Cancel
Save