2022-5-2 16:39:27 只看该作者
52639浏览
查看: 52639|回复: 8
打印 上一主题 下一主题

[项目] 树莓派电容式触摸屏试用——瞳孔跟踪

[复制链接]
本帖最后由 云天 于 2022-5-2 16:39 编辑

【项目背景】
4月份获得了试用树莓派5寸TFT电容式触摸屏的机会,到手后,因工作原因,一直没有去过。这两天有点时间,看了一下Mediapipe官网,发现了“MediaPipe Iris”功能,


可惜,MediaPipe SDK的 python版本是不支持虹膜检测。
这个难不住我。


【项目设计】
先通过MediaPipe的人脸landmark提供了468个点位的人脸点云数据,

根据编号,很容筛选出左眼与右眼所在的区域所有点,然后完成区域的截取。


再使用Opencv的cv2.findContours实现瞳孔识别与跟踪。

【程序代码】
1、加载Mediapipe和OpenCV库
  1. import cv2 as cv2
  2. import  mediapipe as mp
  3. import numpy as np
复制代码
2、人脸landmark检测代码如下:
  1. # 导入可视化函数和可视化样式
  2. mp_drawing=mp.solutions.drawing_utils
  3. #mp_drawing_styles=mp.solutions.drawing_styles
  4. # 导入三维人脸关键点检测模型
  5. mp_face_mesh=mp.solutions.face_mesh
  6. drawing_spec = mp_drawing.DrawingSpec(thickness=1, circle_radius=1)
  7. cap = cv2.VideoCapture(0)
  8. with mp_face_mesh.FaceMesh(
  9.     max_num_faces=4,
  10.     min_detection_confidence=0.5,
  11.     min_tracking_confidence=0.5) as face_mesh:
  12.   while cap.isOpened():
  13.     success, frame = cap.read()
  14.     if not success:
  15.       print("Ignoring empty camera frame.")
  16.       # If loading a video, use 'break' instead of 'continue'.
  17.       break
  18.     h, w, c = frame.shape
  19.     # image = cv2.resize(frame, (w //2, h//2))
  20.     # frame = cv2.flip(frame, 1)
  21.     image = np.copy(frame)
  22.     h2, w2, c2 = image.shape
  23.     # To improve performance, optionally mark the image as not writeable to
  24.     # pass by reference.
  25.     image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
  26.     results = face_mesh.process(image)
  27.     # Draw the face mesh annotations on the image.
  28.     image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
  29.     left_eyes = []
  30.     right_eyes = []
  31.     if results.multi_face_landmarks:
  32.       for face_landmarks in results.multi_face_landmarks:
  33.         for idx, landmark in enumerate(face_landmarks.landmark):
  34.          
  35.           if idx == 246 or idx == 159 or idx == 158  or idx == 145 or idx == 153 or idx == 190:  # left
  36.           #if idx == 53 or idx == 111:  # left
  37.             x1 = np.int(landmark.x * w2)
  38.             y1 = np.int(landmark.y * h2)
  39.             left_eyes.append((x1, y1))
  40.             #cv2.circle(image, (x1, y1), 4, (255, 0, 255), 4, cv2.LINE_AA)
  41.           if idx ==374 or idx == 380  or idx == 385 or idx == 386 or idx == 390  or idx == 414: # right
  42.           #if idx == 276 or idx == 340: # right
  43.             x1 = np.int(landmark.x * w2)
  44.             y1 = np.int(landmark.y * h2)
  45.             right_eyes.append((x1, y1))
  46.             #cv2.circle(image, (x1, y1), 4, (0, 255, 255), 4, cv2.LINE_AA)
  47.         if len(right_eyes)+len(left_eyes)==12:
  48.          #矩形边框(Bounding Rectangle)是说,用一个最小的矩形,把找到的形状包起来。  
  49.          right_box = cv2.boundingRect(np.asarray(right_eyes))
  50.         
  51.          left_box = cv2.boundingRect(np.asarray(left_eyes))
  52.          
  53.          detect_iris(image, right_box, left_box)
  54.     cv2.imshow('MediaPipe Face Mesh', image)
  55.     if cv2.waitKey(5) & 0xFF == 27:
  56.       cv2.imwrite("D:/iris_detect_result.png", image)
  57.       break
  58. cap.release()
  59. cv2.waitKey(0)
  60. cv2.destroyAllWindows()
复制代码


3、虹膜l检测代码如下:
  1. def detect_iris(image, right_box, left_box):
  2.    
  3.   left_roi = image[left_box[1]:left_box[1] + left_box[3], left_box[0]:left_box[0] + left_box[2]]
  4.   cv2.imshow('left_eye', left_roi)
  5.   lh, lw, lc = left_roi.shape
  6.   right_roi = image[right_box[1]:right_box[1]+right_box[3],right_box[0]:right_box[0]+right_box[2]]
  7.   cv2.imshow('right_eye', right_roi)
  8.   rh, rw, rc = right_roi.shape
  9.   if rh>0 and lh>0:
  10.     rows, cols, _ =right_roi.shape   #保存视频尺寸以备用
  11.     gray_roi = cv2.cvtColor(right_roi, cv2.COLOR_BGR2GRAY)   #转灰度
  12.     gray_roi = cv2.GaussianBlur(gray_roi, (7, 7), 0)    #高斯滤波一次
  13.     _, threshold = cv2.threshold(gray_roi, 30, 255, cv2.THRESH_BINARY_INV)  #二值化,依据需要改变阈值
  14.     contours, _ = cv2.findContours(threshold, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) #画连通域
  15.     contours = sorted(contours, key=lambda x: cv2.contourArea(x), reverse=True)
  16.     for cnt in contours:
  17.         (x, y, w, h) = cv2.boundingRect(cnt)
  18.         cv2.circle(right_roi, (x + int(w/2), y + int(h/2)), int(h/2), (0, 0, 255), 3)
  19.         break
  20.     rows, cols, _ =left_roi.shape   #保存视频尺寸以备用
  21.     gray_roi = cv2.cvtColor(left_roi, cv2.COLOR_BGR2GRAY)   #转灰度
  22.     gray_roi = cv2.GaussianBlur(gray_roi, (7, 7), 0)    #高斯滤波一次
  23.     _, threshold = cv2.threshold(gray_roi, 30, 255, cv2.THRESH_BINARY_INV)  #二值化,依据需要改变阈值
  24.     contours, _ = cv2.findContours(threshold, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) #画连通域
  25.     contours = sorted(contours, key=lambda x: cv2.contourArea(x), reverse=True)
  26.     for cnt in contours:
  27.         (x, y, w, h) = cv2.boundingRect(cnt)
  28.         cv2.circle(left_roi, (x + int(w/2), y + int(h/2)), int(h/2), (0, 0, 255), 3)
  29.         break
复制代码

【硬件连接】

【测试图片】






【演示视频】


沙发

 初级技匠

发表于 2022-5-7 13:28:38

貌似懂了电影里的特效之一~
回复

使用道具 举报

板凳

 初级技匠

发表于 2022-5-7 13:31:19

占个板凳  
回复

使用道具 举报

地板

水晶  初级技师

发表于 2022-5-10 16:04:03

666666666666666
回复

使用道具 举报

5#

macCosmo  初级技师

发表于 2022-5-16 11:27:52

666,很科幻
回复

使用道具 举报

6#

盐焗海盐  见习技师

发表于 2022-5-21 13:08:47

6666666666666666666
回复

使用道具 举报

7#

盐焗海盐  见习技师

发表于 2022-5-23 10:37:59

大写的佩服!!!!!
回复

使用道具 举报

8#

大熊小明  学徒

发表于 2022-6-15 16:44:28

666666666666
回复

使用道具 举报

9#

派大星ym  高级技师

发表于 2022-8-1 13:38:00

,,
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2022 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail