Bootstrap

交通标志定位与识别python和opencv

基于模板匹配的交通标志定位与识别

最近在用python和opencv做交通标志的定位和检测,本案例只能检测出限速标志的交通标志,第一次写博客,写的不好请见谅.
博主也是刚刚接触机器视觉的学习,后期会继续发布一些这方面的内容,希望我们可以互相学习,共同进步,

先说一下代码的运行效果吧
这里是一张图片的原图和运行以后的结果
在这里插入图片描述
在这里插入图片描述

1.导入需要模块,先创建一个变量a后面会用到

import cv2 as cv
import numpy as np
import os
a=0

2,加载图片

src=cv.imread('tim.jpg')

在这里插入图片描述
3,提取红色和蓝色部分,这张图片只有红色的部分,但是有的图片上的交通标志是蓝色的,所以这里就提取了红蓝两种颜色**

hsv = cv.cvtColor(src,cv.COLOR_BGR2HSV)
low_hsv=np.array([0,43,46])
high_hsv=np.array([10,255,255])
low_hsv2=np.array([100,43,46])
high_hsv2=np.array([124,255,255])
mask=cv.inRange(hsv,lowerb=low_hsv,upperb=high_hsv)
mask2=cv.inRange(hsv,lowerb=low_hsv2,upperb=high_hsv2)
print(type(mask))
red_blue=cv.bitwise_or(mask,mask2)
cv.imshow('red_blue',red_blue)

在这里插入图片描述
4,对图像进行一些形态学操作把一些白色的小点去掉,把轮廓边缘变得更加清晰

#高斯模糊
mohu=cv.GaussianBlur(red_blue,(5,5),0)
#二值处理
thresh=cv.threshold(mohu,0,255,cv.THRESH_BINARY | cv.THRESH_OTSU)[1]
#闭运算

ker=np.ones((5,5),np.uint8)
close=cv.morphologyEx(thresh,cv.MORPH_CLOSE,ker)
cv.imshow('close',close)

在这里插入图片描述
5,找到上面图像的所有外轮廓,可以看到上面图像上有很多的轮廓,我们需要分别获得他们的外接矩形,然后根据矩形的面积和矩形的长宽比例来选择合适的轮廓,然后在原图上把这些轮廓的外接矩形截取下来,对他们进行一些形态学操作,提取到矩形中间的数字和我们的模板进行匹配,模板文件夹我放在最后了,下面是代码

contours,hierarchy=cv.findContours(close,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_NONE)
print('总轮廓=',len(contours))
for i in contours:
    # print(cv.contourArea(i),cv.arcLength(i,True))#计算轮廓面积和周长
    
    #获取轮廓外接矩形左上角坐标(x,y)和矩形的宽高
    #然后提取宽高比例在0.8到1.3和面积大于200的轮廓
    #x,y,w,h=cv.boundingRect(i)
    if  0.8 <=w/h<=1.3:
        if w*h<200:
            pass
        else:
            #裁剪矩形并保存图片
            a+=1
            img=src[y:y+h,x:x+w]
            #放大到指定尺寸
            img=cv.resize(img,(500,460))
            cv.rectangle(src,(x-5,y-5),(x+w+5,y+h+5),(0,255,0),2)
            # 对截取矩形图片处理
            gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
            ret, thresh = cv.threshold(gray, 70, 255, cv.THRESH_BINARY_INV)

            # 开闭运算
            ker = np.ones((6, 6), np.uint8)
            close = cv.morphologyEx(thresh, cv.MORPH_CLOSE, ker)

            # 掩码
            h, w = gray.shape[0], gray.shape[1]
            point1 = [0.15 * w, h / 4]
            point2 = [0.15 * w, 4 * h / 5]
            point3 = [0.83 * w, 4 * h / 5]
            point4 = [0.83 * w, h / 4]
            list1 = np.array([[point1, point2, point3, point4]], dtype=np.int32)
            mask = np.zeros_like(gray)
            mask = cv.fillConvexPoly(mask, list1, 255)
            mask1 = cv.bitwise_and(mask, thresh)


            # 开运算
            ker = np.ones((6, 6), np.uint8)
            mask1 = cv.morphologyEx(mask1, cv.MORPH_OPEN, ker)

            # 闭运算
            ker = np.ones((5, 5), np.uint8)
            mask1 = cv.morphologyEx(mask1, cv.MORPH_CLOSE, ker)

            # 找外轮廓,
            contours1, hierarchy1 = cv.findContours(mask1, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_NONE)
            a = len(contours1)

            #cv.drawContours(src, contours1, -1, (0, 255, 0), 3)
            if 0<a<=3:
                print('单个矩形内的轮廓', a)
                list3=[]
                for i,element in enumerate(contours1):
                    x2, y2, w2, h2 = cv.boundingRect(element)
                    # print('x2,y2,w2,h2=', x2, y2, w2, h2)
                    # dist1[str(i)]=x2
                    list3.append(x2)
                # print('list3=',min(list3))
                # print(type(element))

                # 轮廓外接矩形
                # boundingboxes = [cv.boundingRect(c) for c in close]  # 返回外接矩形的四个值x,y,h,w
                list2 = []#存放轮廓列表
                for lk in contours1:
                    x1, y1, w1, h1 = cv.boundingRect(lk)
                    roi = mask1[y1:y1 + h1, x1:x1 + w1]
                    roi = cv.resize(roi, (60, 90))
                    #把roi变成三通道图像
                    roi=cv.cvtColor(roi,cv.COLOR_GRAY2BGR)

                    list2.append(roi)
                    #cv.imshow('a4',list2[0])

                    #遍历模板,进行模板匹配
                    filename = os.listdir(r'D:\图片处理\muban')
                    scores = []
                    for i in range(9):
                        src1 = cv.imread('muban/' + filename[i])
                        # gray=cv.cvtColor(src,cv.COLOR_BGR2GRAY)
                        # ret,thresh=cv.threshold(gray,70,255,cv.THRESH_BINARY)
                        result = cv.matchTemplate(src1, roi, cv.TM_CCOEFF)
                        (_, score, _, _) = cv.minMaxLoc(result)
                        scores.append(score)
                    print('得分列表:',scores)
                    x3 = np.argmax(scores)  # x是列表最大值所对应的下标
                    y3=scores[x3]
                    print('最可能取值:', x3,'分数=',scores[x3])
                    if y3>158063248:

                        print('x1=',x1,list3)
                        if x1==min(list3):

                            cv.putText(src,'limt:'+str(x3),(x,y+20),cv.FONT_HERSHEY_DUPLEX,1,(255,0,0),2)

                        elif x1==max(list3):

                            cv.putText(src, 'limt:'+'  '+str(x3), (x,y+20), cv.FONT_HERSHEY_DUPLEX, 1, (255,0,0), 2)
                        else:
                            cv.putText(src, 'limt:' +' '+ str(x3), (x, y + 20), cv.FONT_HERSHEY_DUPLEX, 1,
                                       (255,0,0), 2)
                    else:pass
            else:pass

    else:pass

# cv.imshow('img',img)
# cv.imshow('mask1',mask1)
cv.imshow('src',src)

cv.waitKey(0)
cv.destroyAllWindows()
            

这是最终的运行结果
这是最终的运行结果

模板文件夹好像没法上传上来,你们可以自己做一个模板
模板大概就是下面图片的样子
在这里插入图片描述

模板匹配识别交通标志有太多限制,必须保证交通标志非常清晰的情况下才可以识别。
使用卷积神经网络就没有这么多限制了,准确率还很高,有兴趣可以查看我的另一篇基于卷积神经网络的交通标志识别:博客地址

;