携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第27天,点击查看活动详情
项目需求
自己也是一时心血来潮,想着把自己以前的东西串以下,借用一个例子,将以往的知识点串一次。这次需要串的知识点有:目标的检测+目标测距+鼠标移动
需要完成的构想功能点如下描述:运行程序可以打开摄像头,摄像头显示画面可以检测出是否有人脸,当存在人脸的时候将其框住,并测定人脸距离摄像头的距离,当人脸移动的时候鼠标能够跟着移动。
需求拆分
根据项目需求,我将功能点拆分如下几点:
- 借用OpenCv中的xml进行人脸检测(详细可见往期链接:juejin.cn/post/707483… );
- 使用单目相机进行“张氏标定”后得FX&FY计算目标物距离镜头距离(详细可见往期链接:juejin.cn/post/711974… )
- 使用pymouse进行鼠标坐标点控制移动(详细可见往期链接:juejin.cn/post/713348… )
验证调试
由于上述各功能点我已全部实现,现在需要的是将上述功能点进行“搭积木”并进行调试优化,其中人脸检测部分可直接见我在功能拆分中的部分
format_image(image)...
进行距离测试的时候,需要自己先行获取自己摄像头的焦距,我这里采用了矩形框计算距离(除了必相机的焦距还需要指导自己人脸的宽高值,其单位为米),代码部分如下:
def GetDistens(w, h):
FX = 1321.395754
FY = 1308.603399
Face_x = 0.15
Face_y = 0.22
Distensx = (FX * Face_x) / w
Distensy = (FY * Face_y) / h
Distens = (Distensx + Distensy) / 2
return Distens
使用的是pymouse进行鼠标的移动,大家需要注意的一点就是还有pymouse配套的库,大家可以自行搜索,代码如下:
def MoveMouse(x, y, w, h):
labx = (x+w)
laby = (y+h)
labx , laby = int(labx), int(laby)
m = PyMouse()
m.move(labx , laby ) # 鼠标移动到(x,y)位置
大家需要注意的是进行在图像中进行putText过程中需要调整一下排列的位置,还有就是只有在含有目标的时候才会有目标距离显示。主程序如下:
if __name__ == "__main__":
capture = cv2.VideoCapture(1)
fps = 0.0
while (True):
t1 = time.time()
ref, frame = capture.read()
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# 进行检测
(p_image, face_coor) = format_image(frame)
if face_coor is not None:
# 获取人脸的坐标,并用矩形框出
[x, y, w, h] = face_coor
Distens = GetDistens(w,h)
cv2.putText(frame, "Distens= %.2f" % (Distens), (0, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 1)
MoveMouse(x, y, w, h)
cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 1)
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
fps = (fps + (1. / (time.time() - t1))) / 2
cv2.putText(frame, "FPS= %.2f" % (fps), (0, 20), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 1)
cv2.imshow("video", frame)
c = cv2.waitKey(1) & 0xff
if c == 27:
capture.release()
break
capture.release()
cv2.destroyAllWindows()
结果展示
今天先欠下一张鼠标跟着人脸移动的动图,掘金还不能上传视频,后期补偿给大家,喜欢的可以点个赞再走。