tag 标签: opencv

相关帖子
相关博文
  • 2024-12-19 10:57
    79 次阅读|
    0 个评论
    本篇源自:优秀创作者 lulugl 本文将介绍基于米尔电子MYD-LR3576开发板(米尔基于瑞芯微 RK3576开发板)的人脸疲劳检测方案测试。 米尔基于RK3576核心板/开发板 【前言】 人脸疲劳检测 :一种通过分析人脸特征来判断一个人是否处于疲劳状态的技术。其原理主要基于计算机视觉和机器学习方法。当人疲劳时,面部会出现一些特征变化,如眼睛闭合程度增加、眨眼频率变慢、打哈欠、头部姿态改变等。 例如,通过检测眼睛的状态来判断疲劳程度是一个关键部分。正常情况下,人的眨眼频率相对稳定,而当疲劳时,眨眼频率会降低,并且每次眨眼时眼睛闭合的时间可能会延长。同时,头部可能会不自觉地下垂或者摇晃,这些特征都可以作为疲劳检测的依据。米尔MYC-LR3576采用8核CPU+搭载6 TOPS的NPU加速器,3D GPU,能够非常轻松的实现这个功能,下面就如何实现这一功能分享如下: 【硬件】 1、米尔MYC-LR3576开发板 2、USB摄像头 【软件】 1、v4l2 2、openCV 3、dlib库:dlib 是一个现代化的 C++ 工具包,它包含了许多用于机器学习、图像处理、数值计算等多种任务的算法和工具。它的设计目标是提供高性能、易于使用的库,并且在开源社区中被广泛应用。 【实现步骤】 1、安装python-opencv 2、安装dlib库 3、安装v4l2库 【 代码实现】 1、引入cv2、dlib以及线程等: import cv2 import dlib import numpy as np import time from concurrent. futures import ThreadPoolExecutor import threading 2、初始化dlib的面部检测器和特征点预测器 detector = dlib.get_frontal_face_detector() predictor = dlib.shape_predictor( 'shape_predictor_68_face_landmarks.dat' ) 3、定义计算眼睛纵横比的函数 def eye_aspect_ratio (eye): A = np.linalg. norm (np. array (eye ) - np. array (eye )) B = np.linalg. norm (np. array (eye ) - np. array (eye )) C = np.linalg. norm (np. array (eye ) - np. array (eye )) ear = (A + B) / ( 2.0 * C) return ear 4、定义计算头部姿势的函数 def get_head_pose ( shape ): # 定义面部特征点的三维坐标 object_points = np.array( , dtype=np.float32) image_pts = np.float32( for i in ]) size = frame.shape focal_length = size center = (size // 2, size // 2) camera_matrix = np.array( ], ], ], dtype= "double" ) dist_coeffs = np.zeros(( 4 , 1 )) (success, rotation_vector, translation_vector) = cv2.solvePnP( object_points, image_pts, camera_matrix, dist_coeffs, flags=cv2.SOLVEPNP_ITERATIVE ) rmat, _ = cv2.Rodrigues(rotation_vector) angles, _, _, _, _, _ = cv2.RQDecomp3x3(rmat) return angles 5、定义眼睛纵横比阈值和连续帧数阈值 EYE_AR_THRESH = 0.3 EYE_AR_CONSEC_FRAMES = 48 6、打开摄像头 我们先使用v4l2-ctl --list-devices来例出接在开发板上的列表信息: USB Camera: USB Camera (usb-xhci-hcd.0.auto-1.2): /dev/video60 /dev/video61 /dev/media7 在代码中填入60为摄像头的编号: cap = cv2.VideoCapture( 60 ) cap. set (cv2.CAP_PROP_FRAME_WIDTH, 480 ) # 降低分辨率 cap. set (cv2.CAP_PROP_FRAME_HEIGHT, 320 ) 7、创建多线程处理函数,实现采集与分析分离: # 多线程处理函数 def process_frame ( frame ): global COUNTER, TOTAL gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = detector(gray, 0 ) # 第二个参数为0,表示不使用upsampling for face in faces: landmarks = predictor(gray, face) shape = left_eye = shape right_eye = shape left_ear = eye_aspect_ratio(left_eye) right_ear = eye_aspect_ratio(right_eye) ear = (left_ear + right_ear) / 2.0 if ear < EYE_AR_THRESH: with lock: COUNTER += 1 else : with lock: if = EYE_AR_CONSEC_FRAMES: TOTAL += 1 COUNTER = 0 # 绘制68个特征点 for n in range ( 0 , 68 ): x, y = shape cv2.circle(frame, (x, y), 2 , ( 0 , 255 , 0 ), - 1 ) cv2.putText(frame, f"Eye AR: {ear: .2 f} " , ( 10 , 30 ), cv2.FONT_HERSHEY_SIMPLEX, font_scale, ( 0 , 0 , 255 ), 2 ) cv2.putText(frame, f"Blink Count: {TOTAL} " , ( 10 , 60 ), cv2.FONT_HERSHEY_SIMPLEX, font_scale, ( 0 , 0 , 255 ), 2 ) # 计算头部姿势 angles = get_head_pose(shape) pitch, yaw, roll = angles cv2.putText(frame, f"Pitch: {pitch: .2 f} " , ( 10 , 120 ), cv2.FONT_HERSHEY_SIMPLEX, font_scale, ( 0 , 0 , 255 ), 2 ) cv2.putText(frame, f"Yaw: {yaw: .2 f} " , ( 10 , 150 ), cv2.FONT_HERSHEY_SIMPLEX, font_scale, ( 0 , 0 , 255 ), 2 ) cv2.putText(frame, f"Roll: {roll: .2 f} " , ( 10 , 180 ), cv2.FONT_HERSHEY_SIMPLEX, font_scale, ( 0 , 0 , 255 ), 2 ) # 判断疲劳状态 if = EYE_AR_CONSEC_FRAMES or abs 30 or abs 30 or abs 30 : cv2.putText(frame, "Fatigue Detected!" , ( 10 , 210 ), cv2.FONT_HERSHEY_SIMPLEX, font_scale, ( 0 , 0 , 255 ), 2 ) return frame 8、创建图像显示线程: with ThreadPoolExecutor (max_workers= 2 ) as executor: future_to_frame = {} while True: ret, frame = cap. read () if not ret: break # 提交当前帧到线程池 future = executor. submit (process_frame, frame. copy ()) future_to_frame = frame # 获取已完成的任务结果 for future in list (future_to_frame. keys ()): if future. done (): processed_frame = future. result () cv2. imshow ( "Frame" , processed_frame) del future_to_frame break # 计算帧数 fps_counter += 1 elapsed_time = time. time 1.0 : fps = fps_counter / elapsed_time fps_counter = 0 start_time = time. time () cv2. putText (processed_frame, f "FPS: {fps:.2f}" , ( 10 , 90 ), cv2.FONT_HERSHEY_SIMPLEX, 0.7 , ( 0 , 0 , 255 ), 2 ) if cv2. waitKey ( 1 ) & 0 xFF == ord ( 'q' ): 实现效果: 根据检测的结果,我们就可以来实现疲劳提醒等等的功能。 整体代码如下: import cv2 import dlib import numpy as np import time from concurrent.futures import ThreadPoolExecutor import threading # 初始化dlib的面部检测器和特征点预测器 detector = dlib.get_frontal_face_detector() predictor = dlib.shape_predictor( 'shape_predictor_68_face_landmarks.dat' ) # 修改字体大小 font_scale = 0.5 # 原来的字体大小是0.7,现在改为0.5 # 定义计算眼睛纵横比的函数 def eye_aspect_ratio ( eye ): A = np.linalg.norm(np.array(eye ) - np.array(eye )) B = np.linalg.norm(np.array(eye ) - np.array(eye )) C = np.linalg.norm(np.array(eye ) - np.array(eye )) ear = (A + B) / ( 2.0 * C) return ear # 定义计算头部姿势的函数 def get_head_pose ( shape ): # 定义面部特征点的三维坐标 object_points = np.array( , dtype=np.float32) image_pts = np.float32( for i in ]) size = frame.shape focal_length = size center = (size // 2 , size // 2 ) camera_matrix = np.array( ], ], ], dtype= "double" ) dist_coeffs = np.zeros(( 4 , 1 )) (success, rotation_vector, translation_vector) = cv2.solvePnP( object_points, image_pts, camera_matrix, dist_coeffs, flags=cv2.SOLVEPNP_ITERATIVE ) rmat, _ = cv2.Rodrigues(rotation_vector) angles, _, _, _, _, _ = cv2.RQDecomp3x3(rmat) return angles # 定义眼睛纵横比阈值和连续帧数阈值 EYE_AR_THRESH = 0.3 EYE_AR_CONSEC_FRAMES = 48 # 初始化计数器 COUNTER = 0 TOTAL = 0 # 创建锁对象 lock = threading.Lock() # 打开摄像头 cap = cv2.VideoCapture( 60 ) cap. set (cv2.CAP_PROP_FRAME_WIDTH, 480 ) # 降低分辨率 cap. set (cv2.CAP_PROP_FRAME_HEIGHT, 320 ) # 初始化帧计数器和时间戳 fps_counter = 0 start_time = time.time() # 多线程处理函数 def process_frame ( frame ): global COUNTER, TOTAL gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = detector(gray, 0 ) # 第二个参数为0,表示不使用upsampling for face in faces: landmarks = predictor(gray, face) shape = left_eye = shape right_eye = shape left_ear = eye_aspect_ratio(left_eye) right_ear = eye_aspect_ratio(right_eye) ear = (left_ear + right_ear) / 2.0 if ear < EYE_AR_THRESH: with lock: COUNTER += 1 else : with lock: if = EYE_AR_CONSEC_FRAMES: TOTAL += 1 COUNTER = 0 # 绘制68个特征点 for n in range ( 0 , 68 ): x, y = shape cv2.circle(frame, (x, y), 2 , ( 0 , 255 , 0 ), - 1 ) cv2.putText(frame, f"Eye AR: {ear: .2 f} " , ( 10 , 30 ), cv2.FONT_HERSHEY_SIMPLEX, font_scale, ( 0 , 0 , 255 ), 2 ) cv2.putText(frame, f"Blink Count: {TOTAL} " , ( 10 , 60 ), cv2.FONT_HERSHEY_SIMPLEX, font_scale, ( 0 , 0 , 255 ), 2 ) # 计算头部姿势 angles = get_head_pose(shape) pitch, yaw, roll = angles cv2.putText(frame, f"Pitch: {pitch: .2 f} " , ( 10 , 120 ), cv2.FONT_HERSHEY_SIMPLEX, font_scale, ( 0 , 0 , 255 ), 2 ) cv2.putText(frame, f"Yaw: {yaw: .2 f} " , ( 10 , 150 ), cv2.FONT_HERSHEY_SIMPLEX, font_scale, ( 0 , 0 , 255 ), 2 ) cv2.putText(frame, f"Roll: {roll: .2 f} " , ( 10 , 180 ), cv2.FONT_HERSHEY_SIMPLEX, font_scale, ( 0 , 0 , 255 ), 2 ) # 判断疲劳状态 if = EYE_AR_CONSEC_FRAMES or abs 30 or abs 30 or abs 30 : cv2.putText(frame, "Fatigue Detected!" , ( 10 , 210 ), cv2.FONT_HERSHEY_SIMPLEX, font_scale, ( 0 , 0 , 255 ), 2 ) return frame with ThreadPoolExecutor(max_workers= 2 ) as executor: future_to_frame = {} while True : ret, frame = cap.read() if not ret: break # 提交当前帧到线程池 future = executor.submit(process_frame, frame.copy()) future_to_frame = frame # 获取已完成的任务结果 for future in list (future_to_frame.keys()): if future.done(): processed_frame = future.result() cv2.imshow( "Frame" , processed_frame) del future_to_frame break # 计算帧数 fps_counter += 1 elapsed_time = time.time() - start_time if 1.0 : fps = fps_counter / elapsed_time fps_counter = 0 start_time = time.time() cv2.putText(processed_frame, f"FPS: {fps: .2 f} " , ( 10 , 90 ), cv2.FONT_HERSHEY_SIMPLEX, 0.7 , ( 0 , 0 , 255 ), 2 ) if cv2.waitKey( 1 ) & 0xFF == ord ( 'q' ): break # 释放摄像头并关闭所有窗口 cap.release() cv2.destroyAllWindows() 【总结】 【米尔MYC-LR3576核心板及开发板】 这块开发板性能强大,能轻松实现对人脸的疲劳检测,通过计算结果后进入非常多的工业、人工智能等等的实用功能。
  • 热度 1
    2024-12-13 15:19
    83 次阅读|
    0 个评论
    本文将介绍基于米尔电子MYD-LT527开发板(米尔基于全志T527开发板)的OpenCV手势识别方案测试。 摘自优秀创作者-小火苗 米尔基于全志T527开发板 一、软件环境安装 1.安装OpenCV sudo apt-get install libopencv-dev python3-opencv 2.安装pip sudo apt-get install python3-pip 二、OpenCV手势识别步骤 ​1.图像获取 :从摄像头或其他图像源获取手部图像。使用OpenCV的VideoCapture类可以捕获视频流,或者使用imread函数加载图像。 2.图像预处理 :对图像进行预处理,以提高特征提取的准确性。常用的预处理操作包括灰度化、滤波、边缘检测、二值化、噪声去除和形态学处理等。 灰度化:将彩色图像转换为灰度图像,去除颜色信息,简化图像。 滤波:使用滤波器去除图像中的噪声。 边缘检测:使用边缘检测算法提取图像中的边缘信息。 二值化:将灰度图像转换为二值图像,将像素值分为黑色和白色。 形态学处理:使用形态学操作增强手势轮廓。 3.特征提取 :从预处理后的图像中提取手部特征。常用的特征包括形状特征、纹理特征和运动轨迹特征等。 形状特征:提取手部轮廓、面积、周长、质心等形状特征。 纹理特征:提取手部皮肤纹理、皱纹等纹理特征。 运动轨迹特征:提取手部运动轨迹、速度、加速度等运动轨迹特征。 4.分类和识别 :使用机器学习算法对提取的特征进行分类,以识别特定的手势。 三、代码实现 # -*- coding: utf-8 -*- import cv2 def reg(x): o1 = cv2.imread('paper.jpg',1) o2 = cv2.imread('rock.jpg',1) o3 = cv2.imread('scissors.jpg',1) gray1 = cv2.cvtColor(o1,cv2.COLOR_BGR2GRAY) gray2 = cv2.cvtColor(o2,cv2.COLOR_BGR2GRAY) gray3 = cv2.cvtColor(o3,cv2.COLOR_BGR2GRAY) xgray = cv2.cvtColor(x,cv2.COLOR_BGR2GRAY) ret, binary1 = cv2.threshold(gray1,127,255,cv2.THRESH_BINARY) ret, binary2 = cv2.threshold(gray2,127,255,cv2.THRESH_BINARY) ret, binary3 = cv2.threshold(gray3,127,255,cv2.THRESH_BINARY) xret, xbinary = cv2.threshold(xgray,127,255,cv2.THRESH_BINARY) contours1, hierarchy = cv2.findContours(binary1, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) contours2, hierarchy = cv2.findContours(binary2, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) contours3, hierarchy = cv2.findContours(binary3, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) xcontours, hierarchy = cv2.findContours(xbinary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) cnt1 = contours1 cnt2 = contours2 cnt3 = contours3 x = xcontours ret=[] ret.append(cv2.matchShapes(x,cnt1,1,0.0)) ret.append(cv2.matchShapes(x,cnt2,1,0.0)) ret.append(cv2.matchShapes(x,cnt3,1,0.0)) max_index = ret.index(min(ret)) #计算最大值索引 if max_index==0: r="paper" elif max_index==1: r="rock" else: r="sessiors" return r t1=cv2.imread('test1.jpg',1) t2=cv2.imread('test2.jpg',1) t3=cv2.imread('test3.jpg',1) # print(reg(t1)) # print(reg(t2)) # print(reg(t3)) # ===========显示处理结果================== org=(0,60) font = cv2.FONT_HERSHEY_SIMPLEX fontScale=2 color=(255,255,255) thickness=3 cv2.putText(t1,reg(t1),org,font,fontScale,color,thickness) cv2.putText(t2,reg(t2),org,font,fontScale,color,thickness) cv2.putText(t3,reg(t3),org,font,fontScale,color,thickness) cv2.imshow('test1',t1) cv2.imshow('test2',t2) cv2.imshow('test3',t3) cv2.waitKey() cv2.destroyAllWindows() 四、实践 1.程序运行 2、原始图像包含训练图像 3.识别结果 识别到了 剪刀 石头 布 原始图片
  • 热度 3
    2024-2-3 15:21
    561 次阅读|
    0 个评论
    OpenCV中的Moments类用于**计算图像的矩(moments)**,这是一种描述图像形状的数学工具。 在计算机视觉和图像处理中,矩用来表征图像的形状特征,类似于物理学中物体质量分布的概念。OpenCV提供了`cv::moments()`函数,它能够计算图像的中心矩(最高到三阶)。这些矩可以用来计算图像或轮廓的质心位置、面积、方向等重要特性。 以下是Moments类的一些主要用途: 1. **质心计算**:利用矩可以计算出图像或轮廓的质心坐标。 2. **形状分析**:通过分析图像的矩,可以获取有关图像形状的信息,例如是否对称、大小比例等。 3. **图像匹配**:在某些情况下,矩可以用于图像匹配任务,通过比较两个图像的矩来判断它们是否相似。 4. **方向估计**:对于非对称形状,可以通过矩来估计其主轴的方向。 5. **Hu矩**:除了中心矩之外,OpenCV还提供了`HuMoments()`函数,用于由中心矩计算出一组称为Hu矩的特征值,这些特征值对图像的缩放、平移和旋转具有不变性,广泛用于图像识别和分类任务。 此外,使用`cv::moments()`时,可以选择是否将图像视为二值图像。如果设置为真,则所有非零像素都会按值1对待,这通常用于简化计算并提高处理速度。 总的来说,Moments类在OpenCV中扮演了形状分析和特征提取的角色,是进行高级图像处理和理解的重要工具之一。
  • 2024-1-25 14:28
    250 次阅读|
    0 个评论
    双目视觉是一种利用两个摄像头从不同角度拍摄同一场景,通过计算两幅图像之间的视差信息来获取物体的深度信息的技术。在OpenCV中,我们可以使用StereoBM、StereoSGBM和StereoMCC等算法来实现双目视觉。 首先,我们需要安装OpenCV库,可以使用以下命令进行安装: ```bash pip install opencv-python ``` 接下来,我们将使用StereoBM算法实现双目视觉。以下是一个简单的示例代码: ```python import cv2 import numpy as np # 读取左右相机拍摄的图像 left_image = cv2.imread('left.jpg', cv2.IMREAD_GRAYSCALE) right_image = cv2.imread('right.jpg', cv2.IMREAD_GRAYSCALE) # 创建StereoBM对象 stereo = cv2.StereoBM_create(numDisparities=64, blockSize=15) # 计算视差图 disparity = stereo.compute(left_image, right_image) # 显示结果 cv2.imshow('Disparity', disparity) cv2.waitKey(0) cv2.destroyAllWindows() ``` 在这个示例中,我们首先读取了左右相机拍摄的图像(假设它们已经进行了校正),然后创建了一个StereoBM对象。接着,我们使用`compute`方法计算了视差图。最后,我们显示了视差图。 需要注意的是,为了获得更好的效果,通常需要对输入图像进行预处理,例如缩放、平滑滤波等。此外,还可以尝试使用其他算法,如StereoSGBM和StereoMCC,以获得更准确的深度信息。 总之,OpenCV提供了丰富的双目视觉算法,可以帮助我们轻松地实现双目视觉。通过学习和实践这些算法,我们可以更好地理解双目视觉的原理和应用。
  • 热度 2
    2023-10-12 18:27
    1009 次阅读|
    0 个评论
    在RISC-V上编译OpenCV需要一些准备工作。首先,确保您的系统已安装了RISC-V版本的GCC编译器和相关的构建工具。然后,按照以下步骤进行操作: 下载OpenCV源代码。您可以从OpenCV官方网站下载最新版本的源代码。 解压源代码文件。使用以下命令将压缩文件解压到指定目录: 复制代码 tar -xzf opencv-x.x.x.tar.gz -C /path/to/destination/ 进入解压后的目录。使用以下命令进入解压后的目录: bash 复制代码 cd /path/to/destination/opencv-x.x.x 配置构建。使用以下命令配置构建选项: bash 复制代码 ./configure --with-riscv --prefix=/path/to/installation/directory 编译OpenCV。使用以下命令编译OpenCV: 复制代码 make -j4 安装OpenCV。使用以下命令将编译后的OpenCV安装到指定目录: go 复制代码 make install prefix=/path/to/installation/directory 完成。现在,您已成功在RISC-V上编译和安装了OpenCV。您可以使用相应的include路径和库文件来链接和编译您的项目。 请注意,以上步骤中的命令可能因您的具体环境和配置而有所不同。确保在执行每个步骤之前查看OpenCV文档以获取更多指导和帮助。
相关资源