欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

停车场车位识别

程序员文章站 2022-03-08 08:08:37
1. 新手学了3个月的cv,做了个小项目,最后识别率不是很高,以后有空在改。...

整个代码主要分为以下几步:(1)对图像预处理

                                                 (2)抠出每个停车位的图,以及其地址

                                                   (3)使用keras训练一个2分类的模型,卷积网络选择vgg,为了节省时间,采用keras提供的api,并冻结前10层。

                                                          (4)从视频中取出每一帧,挨个训练,实现实时

停车场车位识别

 

 

def imggg():
    #读入一张原始图
    img=cv2.imread("../test_images/scene1410.jpg")
    #实现2值化操作,将在(120,255)以内的变成变成白色,将以外的变成黑色
    low=np.uint8([120,120,120])
    upper=np.uint8([255,255,255])
    white_img=cv2.inRange(img,low,upper)
    print(white_img.shape)
    cv2.imshow("111",white_img)
    cv2.waitKeyEx(0)
    cv2.destroyAllWindows()
    #与原图进行与运算,求出原图
    img=cv2.bitwise_and(img,img,mask=white_img)
    print(img.shape)
    cv2.imshow("111",img)
    cv2.waitKeyEx(0)
    cv2.destroyAllWindows()
    img=cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
    #边缘检测
    img=cv2.Canny(img,100,200)
    cv2.imshow("111",img)
    cv2.waitKeyEx(0)
    cv2.destroyAllWindows()
    cv2.imwrite("canny.jpg",img)

 以上主要是将图像2值化并边缘检测,为了后面的调用霍夫曼直线做准备停车场车位识别

(2)制作一个mask,将停车场从图中抠出来

        (1)先认为的选取图中的6个点,该6个点组成的一个多边形将停车场包围。

          (2)生成一张和原始图同样大小的mask图,使用fillpoly()函数将上述6个点内填充为白色

               (3)使用bitwith_and ()将原图与mask做mask运算,即可提取出停车场

停车场车位识别

停车场车位识别 

 停车场车位识别

import cv2
import numpy as np
img1=cv2.imread("../test_images/scene1380.jpg")
img=cv2.imread("canny.jpg",0)
img=img.astype("uint8")
rows, cols = img.shape[:2]
pt_1 = [cols*0.05, rows*0.90]
pt_2 = [cols*0.05, rows*0.70]
pt_3 = [cols*0.30, rows*0.55]
pt_4 = [cols*0.6, rows*0.15]
pt_5 = [cols*0.90, rows*0.15]
pt_6 = [cols*0.90, rows*0.90]
#注意这里采用的是int32类型,一定要指明,否则会报错
point=np.array([pt_1,pt_2,pt_3,pt_4,pt_5,pt_6],dtype=np.int32)
print(point)
for i in point:
    img1=cv2.circle(img1,(i[0],i[1]),10,(0,0,255))
cv2.imshow("111",img1)
cv2.waitKey(0)
cv2.destroyAllWindows()
#填充图形
zreos=np.zeros((rows,cols))
cv2.imshow("111",zreos)
cv2.waitKeyEx(0)

print(zreos.shape)
# cv2.destroyAllWindows()
mask=cv2.fillPoly(zreos,[point],255)
cv2.imshow("111",mask)
cv2.waitKey(0)
cv2.destroyAllWindows()
print(img.shape)
print(mask.shape)
#一定要指明是uint8,不说又报错。
mask=mask.astype("uint8")
img4=cv2.bitwise_and(img,img,mask=mask)
cv2.imshow("111",img4)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite("mask_aprk.jpg",img4)

 (3)提取出停车场后下一步就是要标识每一个停车位的位置,采用霍夫直线检测,这里需要反复的调整大小,同时也要注意图中除了停车线,还有许多其他的线,要将其他的线剔除(本段代码较长,逻辑比较复杂,就不细讲了)

        (1)lines = cv2.HoughLinesP(edges,0.1,np.pi/180,15,minLineLength=9,maxLineGap=4)

                 1.霍夫变换是将坐标空间转换为霍夫空间,在霍夫空间中,笛卡尔坐标系中的每个点都是一条曲线,同一条直线上的点会过一个定点

                 2.cv中的霍夫空间是有极坐标系构成

                3.各个参数分别代表 图片,像素精度,角度精度,最少多少个焦点可被判断为一条直线,相隔几个点能被判断为一条直线

      

    def hough_lines(self,image):
        #输入的图像需要是边缘检测后的结果
        #minLineLengh(线的最短长度,比这个短的都被忽略)和MaxLineCap(两条直线之间的最大间隔,小于此值,认为是一条直线)
        #rho距离精度,theta角度精度,threshod超过设定阈值才被检测出线段
        return cv2.HoughLinesP(image, rho=0.1, theta=np.pi/10, threshold=15, minLineLength=9, maxLineGap=4)
        
    def draw_lines(self,image, lines, color=[255, 0, 0], thickness=2, make_copy=True):
        # 过滤霍夫变换检测到直线
        if make_copy:
            image = np.copy(image) 
        cleaned = []
        for line in lines:
            for x1,y1,x2,y2 in line:
                if abs(y2-y1) <=1 and abs(x2-x1) >=25 and abs(x2-x1) <= 55:
                    cleaned.append((x1,y1,x2,y2))
                    cv2.line(image, (x1, y1), (x2, y2), color, thickness)
        print(" No lines detected: ", len(cleaned))
        return image

 停车场车位识别

 可以看到,识别并不是很精准,这是由于汽车的存在导致的干扰。

 

    def identify_blocks(self,image, lines, make_copy=True):
        if make_copy:
            new_image = np.copy(image)
        #Step 1: 过滤部分直线
        cleaned = []
        for line in lines:
            for x1,y1,x2,y2 in line:
                if abs(y2-y1) <=1 and abs(x2-x1) >=25 and abs(x2-x1) <= 55:
                    cleaned.append((x1,y1,x2,y2))
        
        #Step 2: 对直线按照x1进行排序
        import operator
        list1 = sorted(cleaned, key=operator.itemgetter(0, 1))
        
        #Step 3: 找到多个列,相当于每列是一排车
        clusters = {}
        dIndex = 0
        clus_dist = 5
    
        for i in range(len(list1) - 1):
            distance = abs(list1[i+1][0] - list1[i][0])
            if distance <clus_dist:
                if not dIndex in clusters.keys(): clusters[dIndex] = []
                clusters[dIndex].append(list1[i])
                clusters[dIndex].append(list1[i + 1]) 
    
            else:
                dIndex += 1
        
        #Step 4: 得到坐标
        rects = {}
        i = 0
        for key in clusters:
            all_list = clusters[key]
            cleaned = list(set(all_list))
            if len(cleaned) > 5:
                cleaned = sorted(cleaned, key=lambda tup: tup[1])
                avg_y1 = cleaned[0][1]
                avg_y2 = cleaned[-1][1]
                avg_x1 = 0
                avg_x2 = 0
                for tup in cleaned:
                    avg_x1 += tup[0]
                    avg_x2 += tup[2]
                avg_x1 = avg_x1/len(cleaned)
                avg_x2 = avg_x2/len(cleaned)
                rects[i] = (avg_x1, avg_y1, avg_x2, avg_y2)
                i += 1
        
        print("Num Parking Lanes: ", len(rects))
        #Step 5: 把列矩形画出来
        buff = 7
        for key in rects:
            tup_topLeft = (int(rects[key][0] - buff), int(rects[key][1]))
            tup_botRight = (int(rects[key][2] + buff), int(rects[key][3]))
            cv2.rectangle(new_image, tup_topLeft,tup_botRight,(0,255,0),3)
        return new_image, rects

  def draw_parking(self,image, rects, make_copy = True, color=[255, 0, 0], thickness=2, save = True):
        if make_copy:
            new_image = np.copy(image)
        gap = 15.5
        spot_dict = {} # 字典:一个车位对应一个位置
        tot_spots = 0
        #微调
        adj_y1 = {0: 20, 1:-10, 2:0, 3:-11, 4:28, 5:5, 6:-15, 7:-15, 8:-10, 9:-30, 10:9, 11:-32}
        adj_y2 = {0: 30, 1: 50, 2:15, 3:10, 4:-15, 5:15, 6:15, 7:-20, 8:15, 9:15, 10:0, 11:30}
        
        adj_x1 = {0: -8, 1:-15, 2:-15, 3:-15, 4:-15, 5:-15, 6:-15, 7:-15, 8:-10, 9:-10, 10:-10, 11:0}
        adj_x2 = {0: 0, 1: 15, 2:15, 3:15, 4:15, 5:15, 6:15, 7:15, 8:10, 9:10, 10:10, 11:0}
        for key in rects:
            tup = rects[key]
            x1 = int(tup[0]+ adj_x1[key])
            x2 = int(tup[2]+ adj_x2[key])
            y1 = int(tup[1] + adj_y1[key])
            y2 = int(tup[3] + adj_y2[key])
            cv2.rectangle(new_image, (x1, y1),(x2,y2),(0,255,0),2)
            num_splits = int(abs(y2-y1)//gap)
            for i in range(0, num_splits+1):
                y = int(y1 + i*gap)
                cv2.line(new_image, (x1, y), (x2, y), color, thickness)
            if key > 0 and key < len(rects) -1 :        
                #竖直线
                x = int((x1 + x2)/2)
                cv2.line(new_image, (x, y1), (x, y2), color, thickness)
            # 计算数量
            if key == 0 or key == (len(rects) -1):
                tot_spots += num_splits +1
            else:
                tot_spots += 2*(num_splits +1)
                
            # 字典对应好
            if key == 0 or key == (len(rects) -1):
                for i in range(0, num_splits+1):
                    cur_len = len(spot_dict)
                    y = int(y1 + i*gap)
                    spot_dict[(x1, y, x2, y+gap)] = cur_len +1        
            else:
                for i in range(0, num_splits+1):
                    cur_len = len(spot_dict)
                    y = int(y1 + i*gap)
                    x = int((x1 + x2)/2)
                    spot_dict[(x1, y, x, y+gap)] = cur_len +1
                    spot_dict[(x, y, x2, y+gap)] = cur_len +2   
        
        print("total parking spaces: ", tot_spots, cur_len)
        if save:
            filename = 'with_parking.jpg'
            cv2.imwrite(filename, new_image)
        return new_image, spot_dict
    

 又懒了,大家自己看,直接上结果

停车场车位识别

每个停车位的位置已经被获得,接下来,只要将图片抠出来即可。到这图像处理工作算是完成了,接下来就是训练模型的事了,有空在写。

 

本文地址:https://blog.csdn.net/qq_38669789/article/details/111110281

相关标签: 深度学习