加粗样式
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
本人新手刚学习了两周上手练习的项目
一、实现效果
二、实现代码
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()
总结
此代码对于不同的箭头可能识别不准确,需要对代码中一些参数重新调参以适应自己的箭头