瞳孔检测眼动追踪python实现(基于dlib)

效果展示:
原图:(图片来自 b站up 借我300去洗牙)
在这里插入图片描述

dlib实现的特征点检测
在这里插入图片描述
瞳孔检测结果

完整代码:

# encoding:utf-8import dlib
import numpy as np
import cv2def rect_to_bb(rect): # 获得人脸矩形的坐标信息x = rect.left()y = rect.top()w = rect.right() - xh = rect.bottom() - yreturn (x, y, w, h)def shape_to_np(shape, dtype="int"): # 将包含68个特征的的shape转换为numpy array格式coords = np.zeros((68, 2), dtype=dtype)for i in range(0, 68):coords[i] = (shape.part(i).x, shape.part(i).y)return coordsdef resize(image, width=1200):  # 将待检测的image进行resizer = width * 1.0 / image.shape[1]dim = (width, int(image.shape[0] * r))resized = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)return resizeddef feature():image_file = r"F:\project_python\facenet\2.PNG"detector = dlib.get_frontal_face_detector()predictor = dlib.shape_predictor(r"F:\project_python\facenet\shape_predictor_68_face_landmarks.dat")image = cv2.imread(image_file)image = resize(image, width=1200)gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)rects = detector(gray, 1)shapes = []for (i, rect) in enumerate(rects):shape = predictor(gray, rect)shape = shape_to_np(shape)shapes.append(shape)(x, y, w, h) = rect_to_bb(rect)cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)cv2.putText(image, "Face: {}".format(i + 1), (x - 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)count1 = 0count2 = 0# encoding:utf-8import dlib
import numpy as np
import cv2def rect_to_bb(rect): # 获得人脸矩形的坐标信息x = rect.left()y = rect.top()w = rect.right() - xh = rect.bottom() - yreturn (x, y, w, h)def shape_to_np(shape, dtype="int"): # 将包含68个特征的的shape转换为numpy array格式coords = np.zeros((68, 2), dtype=dtype)for i in range(0, 68):coords[i] = (shape.part(i).x, shape.part(i).y)return coordsdef resize(image, width=1200):  # 将待检测的image进行resizer = width * 1.0 / image.shape[1]dim = (width, int(image.shape[0] * r))resized = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)return resizeddef feature():image_file = r"F:\project_python\facenet\2.PNG"detector = dlib.get_frontal_face_detector()predictor = dlib.shape_predictor(r"F:\project_python\facenet\shape_predictor_68_face_landmarks.dat")image = cv2.imread(image_file)image = resize(image, width=1200)gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)rects = detector(gray, 1)shapes = []for (i, rect) in enumerate(rects):shape = predictor(gray, rect)shape = shape_to_np(shape)shapes.append(shape)(x, y, w, h) = rect_to_bb(rect)cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)cv2.putText(image, "Face: {}".format(i + 1), (x - 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)count1 = 0count2 = 0image1=image.copy()eyes=[]eyes2=[]for shape in shapes:left_eye=[]right_eye=[]left_eye2=[]right_eye2=[]for (x, y) in shape:cv2.circle(image1, (x, y), 2, (0, 0, 255), -1)cv2.putText(image1, str(count1)+"-"+str(count2), (x-3, y-3), cv2.FONT_HERSHEY_COMPLEX, 0.4, (100, 200, 200), 1)if count2>=36 and count2<=41:left_eye.append([x,y])left_eye2.append((x,y))elif count2>=42 and count2<=47:right_eye.append([x,y])right_eye2.append((x,y))count2+=1count1+=1    eyes.append([left_eye,right_eye])eyes2.append([left_eye2,right_eye2])cv2.imshow("Output", image1)cv2.waitKey(0)image2=image.copy()for i in range(len(eyes)):e=eyes[i]for j in range(len(e)):points=e[j]# 六边形的顶点坐标pts = np.array(points, np.int32)pts = pts.reshape((-1, 1, 2))# 创建一个空白图像作为掩模mask = np.zeros_like(image)# 在掩模上绘制填充了白色的六边形cv2.fillPoly(mask, [pts], (255, 255, 255))# 创建一个白色背景图像white_background = np.ones_like(image) * 255# 在白色背景上绘制填充了原始图像的六边形cv2.fillPoly(white_background, [pts], (0, 0, 0))# 将原始图像和白色背景图像按位取反inverse_mask = cv2.bitwise_not(mask)# 将原始图像中六边形内的部分与白色背景中六边形外的部分相结合result = cv2.bitwise_and(image, mask) + cv2.bitwise_and(white_background, inverse_mask)# 显示最终结果cv2.imshow('Result', result)cv2.waitKey(0)# 找到最小长方形的左上角和右下角坐标min_x = min(point[0] for point in points)max_x = max(point[0] for point in points)min_y = min(point[1] for point in points)max_y = max(point[1] for point in points)cv2.rectangle(image2, (min_x, min_y), (max_x, max_y), (0, 255, 255), 2)# 获取最小长方形中的图像部分roi = result[min_y:max_y, min_x:max_x]# 将图像部分转换为灰度图gray_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY)# define a threshold, 128 is the middle of black and white in grey scalethresh = 100# assign blue channel to zerosimg_binary = cv2.threshold(gray_roi, thresh, 255, cv2.THRESH_BINARY)[1]cv2.imshow("Output", img_binary)cv2.waitKey(0)#处理眼睛反光形成的白点# 获取图像高度img_binary1=img_binary.copy()height = img_binary1.shape[0]# 遍历每一列像素for col in range(img_binary1.shape[1]):white_run_length = 0start_index = 0end_index = 0for row in range(height):if img_binary1[row, col] == 255:  # 白色像素if white_run_length == 0:start_index = rowwhite_run_length += 1end_index = rowelse:  # 黑色像素if white_run_length > 0 and white_run_length < height / 2 and (start_index == 0 or img_binary1[start_index - 1, col] == 0) and (end_index == height - 1 or img_binary1[end_index + 1, col] == 0):img_binary1[start_index:end_index + 1, col] = 0  # 将连续的白色像素改为黑色像素white_run_length = 0cv2.imshow("Output", img_binary1)cv2.waitKey(0)# 计算每一列的像素值总和column_sums = np.sum(img_binary1, axis=0)# 计算每一列与相邻的n列的总和neighbor_sums = np.convolve(column_sums, np.ones(1), mode='valid')# 找到结果最小的n列的列号min_indices = np.argpartition(neighbor_sums, 20)[:20]# 将列号按数字排序sorted_indices = np.sort(min_indices)# 找到这7列的最中间的列的列号middle_column = sorted_indices[len(sorted_indices) // 2]print("每一列与相邻的6列的总和:", neighbor_sums)print("结果最小的7列的列号(按数字排序):", sorted_indices)print("这7列的最中间的列的列号:", middle_column)cv2.line(image2, (min_x+middle_column, min_y), (min_x+middle_column, max_y), (255, 0, 0))# 找出结果最小的列min_column = img_binary[:, middle_column]# 找出连续相邻的白色像素点white_pixels = np.where(min_column == 255)[0]# 找出连续相邻的白色像素点中最长的一段longest_start = 0longest_end = 0max_length = 0current_start = 0current_length = 0for i in range(1, len(white_pixels)):if white_pixels[i] == white_pixels[i-1] + 1:current_length += 1else:if current_length > max_length:max_length = current_lengthlongest_start = white_pixels[current_start]longest_end = white_pixels[i-1]current_start = icurrent_length = 0# 判断起始位置和结束位置的中点在图像的上半部分还是下半部分mid_point = (longest_start + longest_end) // 2height = img_binary.shape[0]if mid_point < height // 2:print("最长的白色像素段起始位置:", longest_start)print("最长的白色像素段结束位置:", longest_end)print("连续的长度:", max_length)print("中点在图像的上半部分")cv2.line(image2, (min_x,min_y+ height // 2-max_length), (max_x,min_y+ height // 2-max_length), (255, 0, 0))else:print("最长的白色像素段起始位置:", longest_start)print("最长的白色像素段结束位置:", longest_end)print("连续的长度:", max_length)print("中点在图像的下半部分")cv2.line(image2, (min_x,min_y+ height // 2+max_length), (max_x,min_y+ height // 2+max_length), (255, 0, 0))cv2.imshow("Output", image2)cv2.waitKey(0)if __name__ == "__main__":feature()

文件下载:
1.shape_predictor_68_face_landmarks.dat 下载地址

1.官方下载地址(会比较慢) http://dlib.net/files/

2.我的网盘: 链接:https://pan.baidu.com/s/1ORhqLS1bkHyyYfzbmftNpg 提取码:va12

3.我的资源(免费下载):https://download.csdn.net/download/qq_51985653/15122811

原文链接:https://blog.csdn.net/qq_51985653/article/details/113748025

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/225797.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

服务器感染了.locked、.locked1勒索病毒,如何确保数据文件完整恢复?

尊敬的读者&#xff1a; .locked、.locked1勒索病毒是当前网络安全威胁中备受关注的一种恶意软件。本文将深入介绍.locked、.locked1勒索病毒的特征&#xff0c;有效的数据恢复方法&#xff0c;以及一系列预防措施&#xff0c;以帮助用户更好地保护自己的数字资产。面对复杂的…

深入理解人工智能中的图神经网络:原理、应用与未来展望

导言&#xff1a; 图神经网络&#xff08;Graph Neural Networks, GNNs&#xff09;作为人工智能领域的一项前沿技术&#xff0c;在社交网络分析、推荐系统、生物信息学等多个领域展现出卓越的性能。本文将深入剖析图神经网络的原理、当前应用场景以及未来可能的发展方向。 1.…

swing快速入门(十二)

注释很详细&#xff0c;直接上代码 上一篇 新增内容 1.Box容器和BroadLayout布局管理器的结合用法 2.textArea&#xff08;多行文本域&#xff09; 3.Choice&#xff08;下拉选择栏&#xff09; 4. CheckboxGroup&#xff08;多项单选选择框&#xff09; 5. Checkbox&…

循环神经网络-1

目录 1 数据集构建 1.1 数据集的构建函数 1.2 加载数据并进行数据划分 1.3 构造Dataset类 2 模型构建 2.1 嵌入层 2.2 SRN层 2.3 线性层 2.4 模型汇总 3 模型训练 3.1 训练指定长度的数字预测模型 3.2 多组训练 3.3 损失曲线展示 4 模型评价 总结 参考文献 循环神经网络&…

从零开始:前端架构师的基础建设和架构设计之路

文章目录 一、引言二、前端架构师的职责三、基础建设四、架构设计思想五、总结《前端架构师&#xff1a;基础建设与架构设计思想》编辑推荐内容简介作者简介目录获取方式 一、引言 在现代软件开发中&#xff0c;前端开发已经成为了一个不可或缺的部分。随着互联网的普及和移动…

简洁高效的 NLP 入门指南: 200 行实现 Bert 文本分类 (TensorFlow 版)

简洁高效的 NLP 入门指南: 200 行实现 Bert 文本分类 TensorFlow 版 概述NLP 的不同任务Bert 概述MLM 任务 (Masked Language Modeling)TokenizeMLM 的工作原理为什么使用 MLM NSP 任务 (Next Sentence Prediction)NSP 任务的工作原理NSP 任务栗子NSP 任务的调整和局限性 安装和…

【UE5.2】从零开始控制角色移动、游泳、下潜、上浮

目录 效果 步骤 一、项目准备 二、控制角色移动 三、控制角色游泳 四、实现角色潜水、上浮 五、解决在水面上浮的Bug 效果 步骤 一、项目准备 1. 新建一个空白工程&#xff0c;创建一个Basic关卡&#xff0c;添加第三人称游戏资源到内容浏览器 2. 在插件中启用“W…

IDEA——还在手动new对象set值嘛,GenerateAllSetter插件帮你解决!!!

IDEA插件 一、GenerateAllSetter插件介绍二、如何下载安装三、如何使用 总结 最近项目上有些测试需要有很多属性&#xff0c;而且大部分的属性都是要设置值的&#xff0c;一个一个手动set设值很繁琐&#xff0c;就想着有没有能解决这个问题的办法&#xff0c;就发现了一个非常好…

HarmonyOS(十二)——全面认识HarmonyOS三种渲染控制

渲染控制概述 ArkUI通过自定义组件的build()函数和builder装饰器中的声明式UI描述语句构建相应的UI。在声明式描述语句中开发者除了使用系统组件外&#xff0c;还可以使用渲染控制语句来辅助UI的构建&#xff0c;这些渲染控制语句包括控制组件是否显示的条件渲染语句&#xff…

微软Microsoft二面面试题分享通过总结(不是标准答案分享

误打误撞 我写的shitty代码 当年面试算法开发岗竟然通过了 Background 先说下背景&#xff0c;软件工程本科毕业之后&#xff0c;当年8月到北欧读两年制硕士。面试发生在当年的11月&#xff0c;微软哥本哈根&#xff0c;location在丹麦的哥本哈根lingby&#xff08;是不是这么…

C++异步网络库workflow系列教程(3)Series串联任务流

往期教程 如果觉得写的可以,请给一个点赞关注支持一下 观看之前请先看,往期的两篇博客教程,否则这篇博客没办法看懂 workFlow c异步网络库编译教程与简介 C异步网络库workflow入门教程(1)HTTP任务 C异步网络库workflow系列教程(2)redis任务 简介 首先,workflow是任务流的意…

ThingWorx/Vuforia—工业物联网和AR平台

产品概述 ThingWorx是美国PTC公司旗下的一款物联网和AR平台&#xff0c;它提供了适用于IoT的开发工具和能力&#xff0c;使开发者可以为工业物联网快速构建和部署变革性的智能互联解决方案&#xff0c;使创新者能够快速为当今的智能互联世界提供优异的应用程序、解决方案和用户…

人工智能计算机视觉:解析现状与未来趋势

导言 随着人工智能的迅速发展&#xff0c;计算机视觉技术逐渐成为引领创新的关键领域。本文将深入探讨人工智能在计算机视觉方面的最新进展、关键挑战以及未来可能的趋势。 1. 简介 计算机视觉是人工智能的一个重要分支&#xff0c;其目标是使机器具备类似于人类视觉的能力。这…

k8syaml提供的几个有意思的功能,Kubernetes在线工具网站

k8syaml.cn 提供的几个有意思的功能。 一、yaml资源快速生成 之前编写operator的helm的时候就需要自己写deployment、service、configmap这些资源&#xff0c;那么多字段也记不清&#xff0c;都是先找个模版&#xff0c;然后copy改改&#xff0c;再看官方文档&#xff0c;添加…

智能优化算法应用:基于和声算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于和声算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于和声算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.和声算法4.实验参数设定5.算法结果6.参考文献7.MA…

Jenkins Pipeline 脚本优化实践:从繁琐到简洁

引言 在持续集成的过程中&#xff0c;Jenkins Pipeline 是非常关键的一环。它定义了如何自动编译、测试和部署代码。随着项目的不断发展&#xff0c;Pipeline 的复杂性也在不断上升&#xff0c;这就需要我们持续优化 Pipeline 脚本&#xff0c;以提高代码的可读性和维护性。本…

Python如何匹配库的版本

目录 1. 匹配库的版本 2. Python中pip&#xff0c;库&#xff0c;编译环境的问题回答总结 2.1 虚拟环境 2.2 pip&#xff0c;安装库&#xff0c;版本 1. 匹配库的版本 &#xff08;别的库的版本冲突同理&#xff09; 在搭建pyansys环境的时候&#xff0c;安装grpcio-tools…

RT-DETR优化:轻量化卷积设计 | DualConv双卷积魔改RT-DETR结构

🚀🚀🚀本文改进: DualConv双卷积魔改v8结构,达到轻量化的同时并能够实现小幅涨点 🚀🚀🚀RT-DETR改进创新专栏:http://t.csdnimg.cn/vuQTz 学姐带你学习YOLOv8,从入门到创新,轻轻松松搞定科研; RT-DETR模型创新优化,涨点技巧分享,科研小助手; 1.DualC…

软件测试经典面试题(答案解析+视频讲解)

前言 &#xff08;第一个就刷掉一大批人&#xff09; 有很多“会自动化”的同学来咨询技术问题&#xff0c;他总会问到我一些元素定位的问题。元素定位其实都不算自动化面试的问题。 一般我都会问&#xff1a;你是定位不到吗&#xff1f;通常结果都是说确实定位不到。 做自…

真正可行的vue3迁移到nuxt3方法(本人亲测,完全避坑)

终于到了总结经验的时候了&#xff0c;这绝对是全网唯一、完全真正可行的干货。 在我看来&#xff0c;知识就是要拿来分享的&#xff0c;分享给他人也是在提高自己。我绝对不会搞什么订阅或者vip专栏来搞钱坑害各位&#xff0c; 因为我在csdn写文章最主要的目的是为了记录和总…