博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
机器学习进阶-案例实战-停车场车位识别
阅读量:5846 次
发布时间:2019-06-18

本文共 15256 字,大约阅读时间需要 50 分钟。

第一步:去除背景

第二步:进行灰度化

第三步:使用cv2.canny进行边缘检测

第四步:进行图像区域的选择

第五步:使用霍夫曼进行直线检测

第六步:对删选出的直线进行画图操作

第七步:找出每一列车的x1, y1, x2, y2 

第八步:根据gap间隔,找出每一列车所在的(x1, y1, x2, y2)

第九步:使用keras获得的car1.h5权重参数,使用model.predict进行预测操作, 对图片进行预测, 进行画图操作

第十步:对视频进行预测

主函数:part_test

from __future__ import divisionimport matplotlib.pyplot as pltimport cv2import os, globimport numpy as npfrom PIL import Imagefrom keras.applications.imagenet_utils import preprocess_inputfrom keras.models import load_modelfrom keras.preprocessing import imagefrom Parking import Parkingimport picklecwd = os.getcwd()def img_process(test_images,park):    # 第一步:去除背景    white_yellow_images = list(map(park.select_rgb_white_yellow, test_images))    park.show_images(white_yellow_images)    #第二步:进行灰度化    gray_images = list(map(park.convert_gray_scale, white_yellow_images))    park.show_images(gray_images)    # 第三步:进行边缘检测    edge_images = list(map(lambda image: park.detect_edges(image), gray_images))    park.show_images(edge_images)    # 第四步:筛选图像区域    roi_images = list(map(park.select_region, edge_images))    park.show_images(roi_images)    # 第五步:使用hough检测图像中的直线信息    list_of_lines = list(map(park.hough_lines, roi_images))    # 第六步:对直线进行筛选并进行画图操作    line_images = []    for image, lines in zip(test_images, list_of_lines):        line_images.append(park.draw_lines(image, lines))     park.show_images(line_images)    # 第七步:找出每一列车的(x1, y1, x2, y2)    rect_images = []    rect_coords = []    for image, lines in zip(test_images, list_of_lines):        new_image, rects = park.identify_blocks(image, lines)        rect_images.append(new_image)        rect_coords.append(rects)            park.show_images(rect_images)    # 找出每一列框中每一列车对应的位置    delineated = []    spot_pos = []    for image, rects in zip(test_images, rect_coords):        new_image, spot_dict = park.draw_parking(image, rects)        delineated.append(new_image)        spot_pos.append(spot_dict)            park.show_images(delineated)    final_spot_dict = spot_pos[1]    print(len(final_spot_dict))    # 将图片的位置信息进行储存    with open('spot_dict.pickle', 'wb') as handle:        pickle.dump(final_spot_dict, handle, protocol=pickle.HIGHEST_PROTOCOL)    # 将图片进行保存    park.save_images_for_cnn(test_images[0],final_spot_dict)        return final_spot_dictdef keras_model(weights_path):        model = load_model(weights_path)    return modeldef img_test(test_images,final_spot_dict,model,class_dictionary):    for i in range (len(test_images)):        predicted_images = park.predict_on_image(test_images[i],final_spot_dict,model,class_dictionary)def video_test(video_name,final_spot_dict,model,class_dictionary):    name = video_name    cap = cv2.VideoCapture(name)    park.predict_on_video(name,final_spot_dict,model,class_dictionary,ret=True)            if __name__ == '__main__':    test_images = [plt.imread(path) for path in glob.glob('test_images/*.jpg')]    weights_path = 'car1.h5'    video_name = 'parking_video.mp4'    class_dictionary = {}    class_dictionary[0] = 'empty'    class_dictionary[1] = 'occupied'    park = Parking()    park.show_images(test_images)    final_spot_dict = img_process(test_images,park)    # 使用权重参数构建模型    model = keras_model(weights_path)    # 第九步:使用model进行模型的预测    img_test(test_images,final_spot_dict,model,class_dictionary)    # 第十步:对视频进行预测    video_test(video_name,final_spot_dict,model,class_dictionary)

调用函数

import matplotlib.pyplot as pltimport cv2import os, globimport numpy as npclass Parking:        def show_images(self, images, cmap=None):        cols = 2        rows = (len(images)+1)//cols                plt.figure(figsize=(15, 12))        for i, image in enumerate(images):            plt.subplot(rows, cols, i+1)            cmap = 'gray' if len(image.shape)==2 else cmap            plt.imshow(image, cmap=cmap)            plt.xticks([])            plt.yticks([])        plt.tight_layout(pad=0, h_pad=0, w_pad=0)        plt.show()        def cv_show(self,name,img):        cv2.imshow(name, img)        cv2.waitKey(0)        cv2.destroyAllWindows()    def select_rgb_white_yellow(self,image):         #过滤掉背景        lower = np.uint8([120, 120, 120])        upper = np.uint8([255, 255, 255])        # lower_red和高于upper_red的部分分别变成0,lower_red~upper_red之间的值变成255,相当于过滤背景        white_mask = cv2.inRange(image, lower, upper)        self.cv_show('white_mask',white_mask)                masked = cv2.bitwise_and(image, image, mask = white_mask)        self.cv_show('masked',masked)        return masked    def convert_gray_scale(self,image):        return cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)    def detect_edges(self,image, low_threshold=50, high_threshold=200):        return cv2.Canny(image, low_threshold, high_threshold)        def filter_region(self,image, vertices):        """                剔除掉不需要的地方        """        mask = np.zeros_like(image)        if len(mask.shape)==2:            cv2.fillPoly(mask, vertices, 255)            self.cv_show('mask', mask)            return cv2.bitwise_and(image, mask)        def select_region(self,image):        """                手动选择区域        """        # first, define the polygon by vertices        rows, cols = image.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]        vertices = np.array([[pt_1, pt_2, pt_3, pt_4, pt_5, pt_6]], dtype=np.int32)         point_img = image.copy()               point_img = cv2.cvtColor(point_img, cv2.COLOR_GRAY2RGB)        for point in vertices[0]:            cv2.circle(point_img, (point[0],point[1]), 10, (0,0,255), 4)        self.cv_show('point_img',point_img)                        return self.filter_region(image, vertices)        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 = 10            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)            # 计算数量            self.cv_show('new_image', new_image)            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        def assign_spots_map(self,image, spot_dict, make_copy = True, color=[255, 0, 0], thickness=2):        if make_copy:            new_image = np.copy(image)        for spot in spot_dict.keys():            (x1, y1, x2, y2) = spot            cv2.rectangle(new_image, (int(x1),int(y1)), (int(x2),int(y2)), color, thickness)        return new_image        def save_images_for_cnn(self,image, spot_dict, folder_name ='cnn_data'):        for spot in spot_dict.keys():            (x1, y1, x2, y2) = spot            (x1, y1, x2, y2) = (int(x1), int(y1), int(x2), int(y2))            #裁剪            spot_img = image[y1:y2, x1:x2]            spot_img = cv2.resize(spot_img, (0,0), fx=2.0, fy=2.0)             spot_id = spot_dict[spot]                        filename = 'spot' + str(spot_id) +'.jpg'            print(spot_img.shape, filename, (x1,x2,y1,y2))                        cv2.imwrite(os.path.join(folder_name, filename), spot_img)    def make_prediction(self,image,model,class_dictionary):        #预处理        img = image/255.            #转换成4D tensor        image = np.expand_dims(img, axis=0)            # 用训练好的模型进行训练        class_predicted = model.predict(image)        inID = np.argmax(class_predicted[0])        label = class_dictionary[inID]        return label    def predict_on_image(self,image, spot_dict , model,class_dictionary,make_copy=True, color = [0, 255, 0], alpha=0.5):        if make_copy:            new_image = np.copy(image)            overlay = np.copy(image)        self.cv_show('new_image',new_image)        cnt_empty = 0        all_spots = 0        for spot in spot_dict.keys():            all_spots += 1            (x1, y1, x2, y2) = spot            (x1, y1, x2, y2) = (int(x1), int(y1), int(x2), int(y2))            spot_img = image[y1:y2, x1:x2]            spot_img = cv2.resize(spot_img, (48, 48))                         label = self.make_prediction(spot_img,model,class_dictionary)            if label == 'empty':                cv2.rectangle(overlay, (int(x1),int(y1)), (int(x2),int(y2)), color, -1)                cnt_empty += 1                        cv2.addWeighted(overlay, alpha, new_image, 1 - alpha, 0, new_image)                        cv2.putText(new_image, "Available: %d spots" %cnt_empty, (30, 95),        cv2.FONT_HERSHEY_SIMPLEX,        0.7, (255, 255, 255), 2)                cv2.putText(new_image, "Total: %d spots" %all_spots, (30, 125),        cv2.FONT_HERSHEY_SIMPLEX,        0.7, (255, 255, 255), 2)        save = False                if save:            filename = 'with_marking.jpg'            cv2.imwrite(filename, new_image)        self.cv_show('new_image',new_image)                return new_image            def predict_on_video(self,video_name,final_spot_dict, model,class_dictionary,ret=True):           cap = cv2.VideoCapture(video_name)        count = 0        while ret:            ret, image = cap.read()            count += 1            if count == 5:                count = 0                                new_image = np.copy(image)                overlay = np.copy(image)                cnt_empty = 0                all_spots = 0                color = [0, 255, 0]                 alpha=0.5                for spot in final_spot_dict.keys():                    all_spots += 1                    (x1, y1, x2, y2) = spot                    (x1, y1, x2, y2) = (int(x1), int(y1), int(x2), int(y2))                    spot_img = image[y1:y2, x1:x2]                    spot_img = cv2.resize(spot_img, (48,48))                         label = self.make_prediction(spot_img,model,class_dictionary)                    if label == 'empty':                        cv2.rectangle(overlay, (int(x1),int(y1)), (int(x2),int(y2)), color, -1)                        cnt_empty += 1                    cv2.addWeighted(overlay, alpha, new_image, 1 - alpha, 0, new_image)                    cv2.putText(new_image, "Available: %d spots" %cnt_empty, (30, 95),                cv2.FONT_HERSHEY_SIMPLEX,                0.7, (255, 255, 255), 2)                    cv2.putText(new_image, "Total: %d spots" %all_spots, (30, 125),                cv2.FONT_HERSHEY_SIMPLEX,                0.7, (255, 255, 255), 2)                cv2.imshow('frame', new_image)                if cv2.waitKey(10) & 0xFF == ord('q'):                    break        cv2.destroyAllWindows()        cap.release()

 

转载于:https://www.cnblogs.com/my-love-is-python/p/10435787.html

你可能感兴趣的文章
爬虫去重(只是讲了去重的策略,没有具体讲实现过程,反正就是云里雾里)...
查看>>
Team Name
查看>>
[LeetCode] Palindrome Linked List 回文链表
查看>>
UVA - 825Walking on the Safe Side(dp)
查看>>
评论:人才流失强力折射出现实畸形人才观
查看>>
ios的google解析XML框架GDataXML的配置及使用
查看>>
netty-当一个客户端连接到来的时候发生了什么
查看>>
在51CTO三年年+了,你也来晒晒
查看>>
js控制图片等比例缩放
查看>>
Openstack API常用命令
查看>>
关于k-means聚类算法的matlab实现
查看>>
跟随我在oracle学习php(8)
查看>>
UVA-10212 The Last Non-zero Digit. 分解质因子+容斥定理
查看>>
Kotlin的语法糖(一)基础篇
查看>>
亚信安全参加第六届全国等保技术大会 态势感知助力“等保2.0”落地
查看>>
大数据公司Palantir融得7亿美元 曾追踪拉登
查看>>
建立备份策略的重要性
查看>>
发力IoT领域 Marvell注重生态系统发展
查看>>
你应该知道的 RPC 原理
查看>>
Ubuntu安装词典
查看>>