适合刚学习一周opencv的小白入手的基于颜色识别的箭头轮廓绘制

加粗样式

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

本人新手刚学习了两周上手练习的项目


一、实现效果

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

二、实现代码

1.引入库

代码如下(示例):

import cv2
import numpy as np

2.定义函数

代码如下(示例):

def distance_to_base(point,base_x,base_y):
    x, y = point
    return np.sqrt((x - base_x)**2 + (y - base_y)**2)


def triangle_centroid(point1, point2, point3):
    # 计算每个坐标轴上的平均值
    centroid_x = (point1[0] + point2[0] + point3[0]) / 3.0
    centroid_y = (point1[1] + point2[1] + point3[1]) / 3.0
    return (centroid_x, centroid_y)



def get_zhongxin(cx,cy,approx):
    base_x = cx
    base_y = cy

# 对每个轮廓中的点进行距离计算,并存储为 (point, distance) 的元组
    contours_with_distances = []

    for point in approx:
        distance = distance_to_base(point[0],cx,cy)
        contours_with_distances.append((point[0], distance))

# 根据距离对轮廓进行排序
    sorted_contours = sorted(contours_with_distances, key=lambda x: x[1], reverse=True)


# 三角形的三个顶点坐标
    p1=sorted_contours[2][0]
    p2=sorted_contours[3][0]
    p3=sorted_contours[4][0]
    point1 = (p1[0],p1[1])
    point2 = (p2[0],p2[1])
    point3 = (p3[0],p3[1])

# 计算重心坐标
    centroid = triangle_centroid(point1, point2, point3)
    dstx=int(centroid[0])
    dsty=int(centroid[1])
    
    return dstx,dsty

3.完整代码

cap = cv2.VideoCapture(0)
red=[0,0,255]
redlower=np.array((169, 130, 100), dtype=np.uint8)
redupper=np.array((179,255,255), dtype=np.uint8)


while True:

    ret,frame = cap.read()
    
    if ret==True:
        hsv_frame=cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
       
        mask=cv2.inRange(hsv_frame,redlower, redupper)
        mask_detect= np.zeros(frame.shape[:2],np.uint8)
        mask_detect[0:250,100:400] = 255
        frame_detect_area = cv2.bitwise_and(mask,mask,mask=mask_detect)
        
        kernel = np.ones((3,3),np.uint8)
        frame_open = cv2.morphologyEx(frame_detect_area,cv2.MORPH_OPEN,kernel)
        
        zero,contours,_= cv2.findContours(frame_open, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
        for cnt in contours:
            
            length=cv2.arcLength(cnt,True)
            epsilon= 0.03*length##需要调参
            approx = cv2.approxPolyDP(cnt, epsilon, True)
            
            if (length>230) and (len(approx)==7) : ##需要调参
                x, y, w, h = cv2.boundingRect(approx)  
                cv2.rectangle(frame,(int(x),int(y)),(int(x+w),int(y+h)),(255,0,0),2)
                
                ellipse = cv2.fitEllipse(approx)
                cv2.ellipse(frame,  ellipse,[255,0,0],2) 

                
                M = cv2.moments(approx)
                if M['m00'] != 0:
                    cx = int(M['m10']/M['m00'])
                    cy = int(M['m01']/M['m00'])
                else:
                    cx=0
                    cy=0
                
                dstx,dsty=get_zhongxin(cx,cy,approx)
                
                cv2.drawContours(frame,[approx], -1, (0,255,0), 2)
                cv2.circle(frame,(cx,cy),5, (0,255,255), -1)
                cv2.circle(frame,(dstx,dsty),5, (255,0,255), -1)
                
                
                if (dsty-cy)<=0:
                    cv2.putText(frame,"UP+Angle:"+str(int(ellipse[2])),(x+int(0.5*w),y), cv2.FONT_HERSHEY_SIMPLEX,0.5, (0,0,255),1,cv2.LINE_AA)
                else:
                    cv2.putText(frame,"DOWN+Angle:"+str(int(ellipse[2])),(x+int(0.5*w),y), cv2.FONT_HERSHEY_SIMPLEX,0.5, (0,0,255),1,cv2.LINE_AA)
                

        
        cv2.line(frame, (100,0), (400,0), (0,0,255), 3,cv2.LINE_AA)
        cv2.line(frame, (100,0), (100,250), (0,0,255), 3,cv2.LINE_AA)
        cv2.line(frame, (400,0), (400,250), (0,0,255), 3,cv2.LINE_AA)
        cv2.line(frame, (100,250), (400,250), (0,0,255), 3,cv2.LINE_AA)
        
        
        
        cv2.imshow("Video",frame)
        
    key=cv2.waitKey(10)
    if key==27:
        break
        
cap.release()
cv2.destroyAllWindows()

总结

此代码对于不同的箭头可能识别不准确,需要对代码中一些参数重新调参以适应自己的箭头

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值