標(biāo)題: python+opencv識(shí)別紅燈 [打印本頁(yè)]

作者: 5555jj    時(shí)間: 2020-3-7 13:13
標(biāo)題: python+opencv識(shí)別紅燈
# -*- coding: utf-8 -*-

#width = 256, 192
#YSU1100W fast-straight
#YSU1000W fast-left
#YSU0100W fast-right
#YSU1101W slow-s
#YSU1001W s-l
#YSU0101W s-r
#YSU0010W find


import numpy as np     
import cv2
import serial
import time



#設(shè)定紅色閾值,HSV空間  
redLower = np.array([0, 0, 230])  
redUpper = np.array([10, 255, 237])  
#初始化質(zhì)心
center = 0
#初始化串口
ser = serial.Serial("/dev/ttyUSB0",9600)
# s = 0
#打開(kāi)攝像頭
camera = cv2.VideoCapture(0)
camera.set(3, 320)
camera.set(4, 240)   
#遍歷每一幀,檢測(cè)信標(biāo)燈  
while True:
    # s = ser.read(8)
    # # 如果讀到單片機(jī)傳過(guò)來(lái)的信號(hào),倒車
    # if s:
    #     ser.write("YSU0000W".encode())
    #     print("back")
    #     time.sleep(3)
    #     s = 0  
    #讀取幀  
    (ret, frame) = camera.read()  
    #判斷是否成功打開(kāi)攝像頭  
    if not ret:  
        # print ('No Camera')
        break  
    #轉(zhuǎn)到HSV空間  
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)  
    #根據(jù)閾值構(gòu)建掩膜 黑白 亮的為閾值內(nèi)區(qū)域
    mask = cv2.inRange(hsv, redLower, redUpper)  
    #腐蝕操作  iterations:迭代次數(shù)
    mask = cv2.erode(mask, None, iterations=1)  
    #膨脹操作,其實(shí)先腐蝕再膨脹的效果是開(kāi)運(yùn)算,去除噪點(diǎn)  
    mask = cv2.dilate(mask, None, iterations=14)  

    #根據(jù)灰度值化為二值圖
    # GrayImage=cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)  
    # ret, gray=cv2.threshold(GrayImage, 230, 255, cv2.THRESH_BINARY)
    #把紅色分的二值圖和灰度二值圖疊加
    # andout = cv2.bitwise_and(mask, gray)

    #檢測(cè)尋找輪廓 cv2.RETR_EXTERNAL 只得到最外面的輪廓  
    #cv2.findContours()  opencv3會(huì)返回三個(gè)值,分別是img, countours, hierarchy
    cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]  
    #初始化圓形輪廓質(zhì)心  
    center = None  
    #如果存在輪廓  
    if len(cnts) > 0:  
        #找到面積最大的輪廓  
        c = max(cnts, key = cv2.contourArea)  
        #確定面積最大的輪廓的最小外接圓  
        ((x, y), radius) = cv2.minEnclosingCircle(c)  
        #計(jì)算輪廓的矩  
        M = cv2.moments(c)  
        #計(jì)算質(zhì)心
        try:  
            center = (int(M["m10"]/M["m00"]), int(M["m01"]/M["m00"]))   
        except:
            continue
        #只有當(dāng)半徑大于1時(shí),才執(zhí)行  
        if radius >= 1:
            #畫(huà)輪廓圓:img,center,radius,color 厚度:負(fù)值就是實(shí)心
            cv2.circle(frame, (int(x), int(y)), int(radius), (0, 255, 255), 1)  
            #在質(zhì)心中間畫(huà)半徑為5的點(diǎn)
            cv2.circle(frame, center, 5, (0, 0, 255), -1)  
            #最關(guān)鍵的值pos,相對(duì)于畫(huà)面中心的x方向像素差  
            pos = center[0]-160
            # print("x=%s"%pos)
            # print(radius)

            try:
                #通過(guò)x坐標(biāo)控制串口
                # if radius >= 60:
                #     t = 0
                #     while True:
                #         t += 0.05
                #         if t >= 0.4:
                #             break
                #         ser.write("YSU1101W".encode())
                #         time.sleep(0.05)
                #減速 拐角大
                if radius >= 100:
                    #向左轉(zhuǎn)
                    if pos < -50:
                        ser.write("YSU1001W".encode())
                    #直線
                    elif -50 <= pos <= 50:
                        ser.write("YSU1101W".encode())
                    #向右轉(zhuǎn)
                    else:
                        ser.write("YSU0101W".encode())

                # 正常速度,拐角大
                elif 50 <= radius < 100:
                    if pos < -45:
                        ser.write("YSU0001W".encode())
                    elif -45 <= pos <= 45:
                        ser.write("YSU1100W".encode())
                    else:
                        ser.write("YSU0110W".encode())

                #正常速度,拐角小
                else:
                     #向左轉(zhuǎn)
                    if pos < -30:
                        ser.write("YSU1000W".encode())
                    #直線
                    elif - 30<= pos <= 30:
                        ser.write("YSU1100W".encode())
                    #向右轉(zhuǎn)
                    else:
                        ser.write("YSU0100W".encode())
            except:
                continue
        else:
           ser.write("YSU0010W".encode())

    else:
        ser.write("YSU0010W".encode())


    #cv2.imshow('Frame', frame)  
    #鍵盤(pán)檢測(cè),檢測(cè)到esc鍵退出  
    k = cv2.waitKey(1)&0xFF  
    if k == 27:  
        break  

#攝像頭釋放  
camera.release()  
#銷毀所有窗口  
# cv2.destroyAllWindows()


#關(guān)閉串口
ser.close()






歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1