为我所热爱的一切
本科大二在读,学习以开发为主,人工智能为辅。
最近打算着手练习几个opencv的项目,本来去年就开始接触opencv了,但是因为自己的一些原因学无所成,大二这一年我要起飞!起飞!
po上项目博主的原文
这位博主讲的非常清楚,推荐给大家我做的也只是照猫画虎,通过实战来认识opencv
现在还是个小菜鸟,希望大佬们不吝赐教
原图(网上找的,侵删)
预处理图片
# 图像预处理
def preprocess(imgArr):
# 转成灰度图片
img = cv2.cvtColor(imgArr, cv2.COLOR_BGR2GRAY)
# 转成模糊图片
img = cv2.blur(img, (3, 3))
# 转成边缘图片
img = cv2.Canny(img, 100, 500)
"""对于边缘检测来说,到canny为止更加清晰"""
# 设置内核
# 好耶*斜体样式*!我找到了最棒的那个参数!
kernel = np.ones((32, 32), np.uint8)
# 膨胀图片
# img = cv2.dilate(img, kernel)
# 腐蚀图片
# img = cv2.erode(img, kernel)
# 使用开运算和闭运算使图像边缘成为一个整体
img_edge1 = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
img_edge2 = cv2.morphologyEx(img_edge1, cv2.MORPH_OPEN, kernel)
# hierarchy都包含4个整型数据,分别表示:后一个轮廓的序号、前一个轮廓的序号、子轮廓的序号、父轮廓的序号。(暂时还不明白也没用到,慢慢来)
contours, hierarchy = cv2.findContours(img_edge2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
return img, img_edge2, contours
图像预处理后
进行开运算和闭运算之后
轮廓筛选
def select(contours, Min_Area=2000):
# 用来存放符合比例的轮廓
temp_contours = []
for contour in contours:
# 不知道这里是不是要和图片的比例有一定关系,待会儿回过头来看(我就先不改了,我就是懒)
if cv2.contourArea(contour) > Min_Area:
temp_contours.append(contour)
car_plate = []
for temp_contour in temp_contours:
# 得到最小外接矩形的(中心(x,y), (宽,高), 旋转角度)
rect_tupple = cv2.minAreaRect(temp_contour)
# 到目前为止筛选到3个轮廓
# print(len(rect_tupple))
# 这个元组中的第一个元素就是最小外接矩形的中心坐标
rect_width, rect_height = rect_tupple[1]
# 调整宽高
if rect_width < rect_height:
rect_width, rect_height = rect_height, rect_width
# 计算宽高比
aspect_ratio = rect_width / rect_height
# 车牌的宽高比正常在2~5.5之间
if 2 < aspect_ratio < 5.5:
car_plate.append(temp_contour)
# 下面两句代码没有用到
# 获取最小外接矩形的四个坐标(浮点型)
rect_vertices = cv2.boxPoints(rect_tupple)
# 将坐标转换为整型
rect_vertices = np.int0(rect_vertices)
# 根据车牌特征筛选后,只剩下一个满足条件的轮廓
# print(len(car_plate))
return car_plate
定位
# 定位函数
def segment(imgArr, car_plates):
if len(car_plates) == 1:
for car_plate in car_plates:
# car_plate是一个三维数组
row_min, col_min = np.min(car_plate[:, 0, :], axis=0)
row_max, col_max = np.max(car_plate[:, 0, :], axis=0)
# print(row_min, row_max, col_min, col_max)
# 用矩形圈出车牌的轮廓
# cv2.rectangle(image, start_point, end_point, color, thickness)
"""
这里进行了参数的调整,我也是第一次做实战,不知道参数能不能随便调
因为这里参数调整之后的效果是更好的
如果不合适的话请指教
原来的语句(供参考)
cv2.rectangle(imgArr, (row_min, col_min), (row_max, col_max), (0, 255, 0), 2)
card_img = imgArr[row_min: col_max, col_min-15: row_max]
这里需要调整参数应该也是我前面有的地方写的不好
请大家指教
"""
cv2.rectangle(imgArr, (row_min-8, col_min), (row_max, col_max), (0, 255, 0), 2)
# 这里刚刚犯了一个比较愚蠢的错误,因为显示图片的命名问题以为自己的函数使用有问题,以后多注意
card_img = imgArr[row_min: col_max, col_min-15: row_max]
return imgArr, card_img
最终的效果
在注释上加了一点自己的理解,字符识别的内容我一般用不到就省略了(还不是因为我懒),这份代码复用性很高,在之后的学习中应该也能经常用到。
这份代码我自己写的地方并没有很多,但确实通过这次实战学到了一些函数的用法和一些筛选的技巧,星光不问赶路人,奋斗12个月,我要进字节



