一.实现效果(效果不好 能用 ):
二.py流程图
三.方法2. py代码
import cv2 #cv2库
import os
import tkinter.filedialog #tk 是ugi库 选择文件对话框的格式打开和保存图片库
import numpy as np #NumPy系统是Python的一种开源的数值计算扩展
import matplotlib.pyplot as plt #pyplot是常用的画图模块
from matplotlib import pyplot as plt
from PIL import Image #图像处理模块
#文件对话框:
default_dir=r"文件路径"
path=tkinter.filedialog.askopenfilename(title=u'选择文件',initialdir=(os.path.expanduser((default_dir))))
#path='C:\\Users\\Administrator\\Desktop\\demo\\py\\4\\car.jpg'
def show_pic(path):
#读入图
initial_img = cv2.imread(path) #(600, 800, 3) 行,列,通道数
#initial_RGB = cv2.cvtColor(initial_img,cv2.COLOR_BGR2RGB)
#灰度处理图像
Gray_img = cv2.cvtColor(initial_img,cv2.COLOR_BGR2GRAY)
#高斯去燥
Gaussian = cv2.GaussianBlur(Gray_img, (5,5), 0, 0, cv2.BORDER_DEFAULT)
#中值滤波
Median = cv2.medianBlur(Gaussian, 5)
#双边滤波
#Test = cv2.bilateralFilter(Gray_img,9,25,25)
cv2.imwrite('C:\\Users\\Administrator\\Desktop\\demo\\py\\4\\111.jpg',Median)
'''
#sobel算子 轮廓
# Sobel算子 XY方向求梯度
x = cv2.Sobel(Median, cv2.CV_8U, 1, 0, ksize = 3) #X方向
y = cv2.Sobel(Median, cv2.CV_8U, 0, 1, ksize = 3) #Y方向
absX = cv2.convertScaleAbs(x) # 转回uint8
absY = cv2.convertScaleAbs(y)
Sobel = cv2.addWeighted(absX, 0.5, absY, 0.5,0)
'''
#Canny边缘处理
Canny = cv2.Canny(Median, 50, 200)
#Otsu大津算法自适应阈值二值化
ret, Binary = cv2.threshold(Canny,170, 255, cv2.THRESH_OTSU|cv2.THRESH_BINARY)
#建立一个椭圆核函数,闭操作
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (25, 25))
#执行图像形态学, 细节直接查文档,很简单
closed = cv2.morphologyEx(Binary, cv2.MORPH_CLOSE, kernel)
closed = cv2.erode(closed, None, iterations=4)
closed = cv2.dilate(closed, None, iterations=4)
#提取轮廓
contours,_ = cv2.findContours(closed.copy(),cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#画出轮廓排序,cv2.contourArea 计算轮廓面积,将最大的那组轮廓挑出来
c = sorted(contours, key=cv2.contourArea, reverse=True)[0]
#compute the rotated bounding box of the largest contour
rect = cv2.minAreaRect(c) #画出轮廓的最小外接矩形
Box = np.int0(cv2.boxPoints(rect)) #获取最小外接矩形的4个顶点
#按照Box画出轮廓
Final_img = cv2.drawContours(initial_img.copy(),[Box], -1, (255, 255, 255), -1)
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)
hight = y2 - y1
width = x2 - x1
crop_img = initial_img.copy()[y1:y1+hight, x1:x1+width]
#img2 =cv2.imread('C:\\Users\\Administrator\\Desktop\\demo\\py\\4\\car.jpg')
#img_plate = path[y1:y2, x1:x2]
#return crop_img
img2 = cv2.imread('C:\\Users\\Administrator\\Desktop\\demo\\py\\4\\car.jpg') #获取原图给img2
# # 截取图像
img_plate = img2[y1:y2, x1:x2]
cv2.imwrite('C:\\Users\\Administrator\\Desktop\\demo\\py\\4\\222.jpg', crop_img) #输出‘222.jpg’裁剪过的图片
cv2.imshow("12",crop_img )
cv2.waitKey(0)
print("Crop_img1")
print(crop_img)
#cv2.imshow('Mask', path)
#cv2.imwrite('C:\\Users\\Administrator\\Desktop\\demo\\py\\4\\7.jpg',path)
#cv2.imwrite('C:\\Users\\Administrator\\Desktop\\demo\\py\\4\\7' + '.jpg', path)
#cv.imwrite("C:\\Users\\Administrator\\Desktop\\demo\\py\\4\\7.jpeg",crop_img)
#print("Path2")
#print(path)
show_pic(path)
方法2测试图片:
四.方法1.1.py代码
import cv2
import numpy as np
import matplotlib.pyplot as plt
#1、imread加载图片
img = cv2.imread('C:\\Users\\Administrator\\Desktop\\demo\\py\\1\\image.jpg')
cv2.imwrite('C:\\Users\\Administrator\\Desktop\\demo\\py\\1\\1yuantu.jpg', img)
#2、将图像转换为灰度图
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imwrite('C:\\Users\\Administrator\\Desktop\\demo\\py\\1\\2huitu.jpg', img)
#
#2、高斯平滑模糊
#GaussianBlur(InputArray img, OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, int borderType=BORDER_DEFAULT )
#Size ksize必须为正奇数
img = cv2.GaussianBlur(img, (3, 3), 0, 0, cv2.BORDER_DEFAULT)
#3、中值滤波(池化),消除噪音数据,medianBlur(InputArray src, OutputArray dst, int ksize) ksize必须为奇数
img = cv2.medianBlur(img, 5)
cv2.imwrite('C:\\Users\\Administrator\\Desktop\\demo\\py\\1\\3zhaoyin.jpg', img)
#4、利用Sobel方法可以进行sobel边缘检测,突出边缘
img = cv2.Sobel(img, cv2.CV_8U, 1, 0, ksize=3)
cv2.imwrite('C:\\Users\\Administrator\\Desktop\\demo\\py\\1\\4bianyuan.jpg', img)
#图像的二值化就是将图像上的像素点的灰度值设置为0或255,这样将使整个图像呈现出明显的黑白效果,<150的全为黑,>150的全为白
ret, binary = cv2.threshold(img, 150, 255, cv2.THRESH_BINARY)
#膨胀,让轮廓突出
element1 = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 7))
img = cv2.dilate(binary, element1, iterations=1)
cv2.imwrite('C:\\Users\\Administrator\\Desktop\\demo\\py\\1\\5lunkuo.jpg', img)
#腐蚀
element2 = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 1))
img = cv2.erode(img, element2, iterations=1)
#膨胀,让轮廓更明显
img = cv2.dilate(img, element1, iterations=3)
cv2.imwrite('C:\\Users\\Administrator\\Desktop\\demo\\py\\1\\6pengzhang.jpg', img)
###############################################
# 查找轮廓(img: 原始图像,contours:矩形坐标点,hierarchy:图像层次)
contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cv2.imwrite('C:\\Users\\Administrator\\Desktop\\demo\\py\\1\\7pengzhang.jpg', img)
max_ratio = -1
ratios = []
num = 0
for i in range(len(contours)):
cnt = contours[i]
#计算轮廓面积
area = cv2.contourArea(cnt)
if area < 1000:
continue
#四边形的最小外接矩形,得到最小外接矩形的(中心(x,y), (宽,高), 旋转角度)
rect = cv2.minAreaRect(cnt)
# 矩形的四个坐标(顺序不定,但是一定是一个左下角、左上角、右上角、右下角这种循环顺序(开始是哪个点未知))
box = cv2.boxPoints(rect)
# 转换为long类型
box = np.int0(box)
# 计算长宽高
height = abs(box[0][1] - box[2][1])
weight = abs(box[0][0] - box[2][0])
ratio = float(weight) / float(height)
# 正常的车牌宽高比在2.7~5之间
if ratio > max_ratio:
max_box = box
if ratio > 5.5 or ratio < 2:
continue
num +=1
ratios.append((max_box,ratio))
#返回就是车牌的矩阵的四个点的坐标
box = ratios[0][0]
#print(box)
#print(box[0,1])
ys = [box[0, 1], box[1, 1], box[2, 1], box[3, 1]]
#print(ys)
xs = [box[0, 0], box[1, 0], box[2, 0], box[3, 0]]
ys_sorted_index = np.argsort(ys)
#print(ys_sorted_index)
xs_sorted_index = np.argsort(xs)
# 获取x上的坐标
x1 = box[xs_sorted_index[0], 0]
#print(x1)
x2 = box[xs_sorted_index[3], 0]
#print(x2)
# 获取y上的坐标
y1 = box[ys_sorted_index[0], 1]
#print(y1)
y2 = box[ys_sorted_index[3], 1]
#print(y2)
#
img2 = cv2.imread('C:\\Users\\Administrator\\Desktop\\demo\\py\\1\\image.jpg')
# # 截取图像
img_plate = img2[y1:y2, x1:x2]
cv2.imwrite('C:\\Users\\Administrator\\Desktop\\demo\\py\\1\\8.jpg', img_plate)
print(img_plate)
cv2.imshow("12",img_plate )
cv2.waitKey(0)
五.方法1.2.py代码
# -*- coding: utf-8 -*-
import cv2
import numpy as np
# 读取图片
imagePath = 'C:\\Users\\Administrator\\Desktop\\demo\\py\\1\\image.jpg'
img = cv2.imread(imagePath)
# 转化成灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 利用Sobel边缘检测生成二值图
sobel = cv2.Sobel(gray, cv2.CV_8U, 1, 0, ksize=3)
# 二值化
ret, binary = cv2.threshold(sobel, 0, 255, cv2.THRESH_OTSU + cv2.THRESH_BINARY)
# 膨胀、腐蚀
element1 = cv2.getStructuringElement(cv2.MORPH_RECT, (30, 9))
element2 = cv2.getStructuringElement(cv2.MORPH_RECT, (24, 6))
# 膨胀一次,让轮廓突出
dilation = cv2.dilate(binary, element2, iterations=1)
# 腐蚀一次,去掉细节
erosion = cv2.erode(dilation, element1, iterations=1)
# 再次膨胀,让轮廓明显一些
dilation2 = cv2.dilate(erosion, element2, iterations=2)
# 查找轮廓和筛选文字区域
region = []
contours, hierarchy = cv2.findContours(dilation2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for i in range(len(contours)):
cnt = contours[i]
# 计算轮廓面积,并筛选掉面积小的
area = cv2.contourArea(cnt)
if (area < 1000):
continue
# 找到最小的矩形
rect = cv2.minAreaRect(cnt)
print ("rect is: ")
print (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])
# 根据文字特征,筛选那些太细的矩形,留下扁的
if (height > width * 1.3):
continue
region.append(box)
cv2.imwrite('C:\\Users\\Administrator\\Desktop\\demo\\py\\1\\1.jpg', img)
# 绘制轮廓
for box in region:
cv2.drawContours(img, [box], 0, (0, 255, 0), 2)
cv2.imshow('img', img)
cv2.imwrite('C:\\Users\\Administrator\\Desktop\\demo\\py\\1\\2.jpg', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# box = region[0][0]
#print(box)
#print(box[0,1])
# ys = [box[0, 1], box[1, 1], box[2, 1], box[3, 1]]
#print(ys)
# xs = [box[0, 0], box[1, 0], box[2, 0], box[3, 0]]
# ys_sorted_index = np.argsort(ys)
#print(ys_sorted_index)
# xs_sorted_index = np.argsort(xs)
# 获取x上的坐标
#x1 = box[xs_sorted_index[0], 0]
#print(x1)
# x2 = box[xs_sorted_index[3], 0]
#print(x2)
# 获取y上的坐标
#y1 = box[ys_sorted_index[0], 1]
#print(y1)
#y2 = box[ys_sorted_index[3], 1]
#print(y2)
#img2 = cv2.imread('C:\\Users\\Administrator\\Desktop\\demo\\py\\1\\image.jpg')
# # 截取图像
#img_plate =img2[y1:y2, x1:x2]
#cv2.imwrite('C:\\Users\\Administrator\\Desktop\\demo\\py\\1\\10.jpg', img_plate)
#cv2.imshow('img', img)
#cv2.waitKey(0)
#cv2.destroyAllWindows()
方法1-1.2测试图片:
六.
图片有部分是手拍,有部分是网图,代码核心是看的别人的 时间很长了 忘了 对原作者说声抱歉。