树莓派:基于opencv+Python的颜色形状识别(红色、蓝色的圆形、矩形、三角形)

树莓派:基于opencv+Python的颜色形状识别(红色、蓝色的圆形、矩形、三角形),第1张

树莓派:基于opencv+Python的颜色形状识别(红色、蓝色的圆形、矩形、三角形

要求 :分辨出一个随机颜色(红色,蓝色)的图形(圆形,矩形,三角形)

思路 : HSV色块识别+轮廓提取+同一高度面积识别

一、HSV模型

HSV(Hue, Saturation, Value)是根据颜色的直观特性由A. R. Smith在1978年创建的一种颜色空间, 也称六角锥体模型(Hexcone Model)。这个模型中颜色的参数分别是:色调(H),饱和度(S),明度(V)。


HSV色彩空间

注意:红色的H空间有两部分,需要将两部分融合后提取轮廓。

二、提取轮廓后,固定高度下分别检测圆形、正方形、三角形的面积阈值。

示例代码如下:

# encoding=utf-8
import cv2 as cv
import numpy as np
import time
import serial


def analysis(frame):
    global red_triangle
    global red_rectangle
    global red_circle
    global blue_triangle
    global blue_rectangle
    global blue_circle

    h,w,ch = frame.shape
    result = np.zeros((h, w, ch), dtype=np.uint8)
    kernel = np.ones((5, 5), np.uint8)
    
    l_red1 = np.array([[0,43,46]])
    h_red1 = np.array([10,255,255])
    l_red2 = np.array([[160,43,46]])
    h_red2 = np.array([180,255,255])
    
    l_blue = np.array([[100,43,46]])
    h_blue = np.array([124,255,255])
    
    
    
    try:
        
        red_img=frame.copy()
        hsv = cv.cvtColor(red_img, cv.COLOR_BGR2HSV) 
        binary=cv.inRange(hsv,l_red1,h_red1)
        binary3=cv.inRange(hsv,l_red2,h_red2)
        binary = cv.dilate(binary, kernel, iterations=1)#膨胀
        binary3 = cv.dilate(binary3, kernel, iterations=1)
        binary4=cv.addWeighted(binary,1,binary3,1,0)#两部分红色融合
        cv.imshow('binary4:', binary4)
        contours,binary1=cv.findContours(binary4,1,1)
        draw_img=red_img.copy()
        red_copy=cv.drawContours(draw_img,contours,-1,(255,0,0),2)
        cv.imshow('red_img:', red_copy)
        cnt=contours[0]
                           
        p1 = cv.arcLength(cnt, True)
        area1 = cv.contourArea(cnt)
        print("area1",area1)
        print("p1",p1)
        
        
        if 0 <= area1 <=30000:
                print('R3')
                ser.write(("SR3E").encode())
            
        elif 30000 < area1 <= 35000:
                print('R1')
                ser.write(("SR1E").encode())
                
        elif 35000 < area1 <= 60000:
                print('R2')
                ser.write(("SR2E").encode())
   
    except:
        pass
    
    try:
        
        blue_img=frame.copy()
        hsv1 = cv.cvtColor(blue_img, cv.COLOR_BGR2HSV)
        binary1=cv.inRange(hsv1,l_blue,h_blue)
        binary1 = cv.dilate(binary1, kernel, iterations=1)
        contours1,binary2=cv.findContours(binary1,1,1)
        draw_img=blue_img.copy()
        blue_copy=cv.drawContours(draw_img,contours1,-1,(255,0,0),2)
        cv.imshow('blue_img:', blue_copy)
        cv.imshow('binary1:', binary1)
        cnt=contours1[0]
                           
        p2 = cv.arcLength(cnt, True)
        area2= cv.contourArea(cnt)
        print("area2",area2)
        print("p2",p2)
        
        if 0 <= area2 <=26000:
                print('B3')
                ser.write(("SB3E").encode())
                
        elif 26000 < area2 <= 35000:
                print('B1')
                ser.write(("SB1E").encode())
                
        elif 35000 < area2 <= 60000:
                print('B2')
                ser.write(("SB2E").encode())
                
        
    except:
        pass
    
       
#串口通信
if __name__ == "__main__":
    ser = serial.Serial("/dev/ttyAMA0", 57600)
    #color_str = ''
    red_triangle = 0
    red_rectangle = 0
    red_circle = 0
    blue_triangle = 0
    blue_rectangle = 0
    blue_circle = 0
    #shape_color = []
    

cap = cv.VideoCapture('/dev/video0')
while (True):
    ret, src = cap.read()
    analysis(src)
    if cv.waitKey(1) & 0xFF == ord('q'):
        break 
           

# 清空接收缓冲区
ser.flushInput()
cap.release()
cv.destroyAllWindows()
ser.close()

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5689631.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存