要求 :分辨出一个随机颜色(红色,蓝色)的图形(圆形,矩形,三角形)
思路 : 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()
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)