找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1523|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

python+opencv識別紅燈

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:704010 發(fā)表于 2020-3-7 13:13 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
# -*- 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
#打開攝像頭
camera = cv2.VideoCapture(0)
camera.set(3, 320)
camera.set(4, 240)   
#遍歷每一幀,檢測信標(biāo)燈  
while True:
    # s = ser.read(8)
    # # 如果讀到單片機(jī)傳過來的信號,倒車
    # if s:
    #     ser.write("YSU0000W".encode())
    #     print("back")
    #     time.sleep(3)
    #     s = 0  
    #讀取幀  
    (ret, frame) = camera.read()  
    #判斷是否成功打開攝像頭  
    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)  
    #膨脹操作,其實先腐蝕再膨脹的效果是開運(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)

    #檢測尋找輪廓 cv2.RETR_EXTERNAL 只得到最外面的輪廓  
    #cv2.findContours()  opencv3會返回三個值,分別是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)  
        #計算輪廓的矩  
        M = cv2.moments(c)  
        #計算質(zhì)心
        try:  
            center = (int(M["m10"]/M["m00"]), int(M["m01"]/M["m00"]))   
        except:
            continue
        #只有當(dāng)半徑大于1時,才執(zhí)行  
        if radius >= 1:
            #畫輪廓圓:img,center,radius,color 厚度:負(fù)值就是實心
            cv2.circle(frame, (int(x), int(y)), int(radius), (0, 255, 255), 1)  
            #在質(zhì)心中間畫半徑為5的點(diǎn)
            cv2.circle(frame, center, 5, (0, 0, 255), -1)  
            #最關(guān)鍵的值pos,相對于畫面中心的x方向像素差  
            pos = center[0]-160
            # print("x=%s"%pos)
            # print(radius)

            try:
                #通過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)  
    #鍵盤檢測,檢測到esc鍵退出  
    k = cv2.waitKey(1)&0xFF  
    if k == 27:  
        break  

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


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

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表