基于OpenCV年齡與性別識別系統

深入解析基于OpenCV年齡與性別識別系統

在這篇博客中,我們將詳細解析一個使用OpenCV進行年齡和性別識別的Python腳本。這個腳本展示了如何利用深度學習模型,從視頻或圖像中檢測人臉并預測每個人臉的年齡和性別。

1. 導入必要的模塊
import cv2 as cv
import math
import time
import argparse

首先,腳本開始于導入必需的Python模塊。這里cv2是OpenCV庫的Python接口,主要用于圖像處理和計算機視覺任務。argparse用于處理命令行參數,time用于測量執行時間。

2. 人臉檢測功能
def getFaceBox(net, frame, conf_threshold=0.7):frameOpencvDnn = frame.copy()frameHeight = frameOpencvDnn.shape[0]frameWidth = frameOpencvDnn.shape[1]blob = cv.dnn.blobFromImage(frameOpencvDnn, 1.0, (300, 300), [104, 117, 123], True, False)net.setInput(blob)detections = net.forward()bboxes = []for i in range(detections.shape[2]):confidence = detections[0, 0, i, 2]if confidence > conf_threshold:x1 = int(detections[0, 0, i, 3] * frameWidth)y1 = int(detections[0, 0, i, 4] * frameHeight)x2 = int(detections[0, 0, i, 5] * frameWidth)y2 = int(detections[0, 0, i, 6] * frameHeight)bboxes.append([x1, y1, x2, y2])cv.rectangle(frameOpencvDnn, (x1, y1), (x2, y2), (0, 255, 0), int(round(frameHeight/150)), 8)return frameOpencvDnn, bboxes

getFaceBox`是腳本的核心,用于從給定的幀中檢測人臉。它首先創建一個圖像的blob(一個經過預處理的圖像數組),然后通過預訓練的神經網絡進行前向傳播,檢測出圖像中的人臉。對于每個檢測到的人臉,如果其置信度高于閾值,它計算出人臉的邊界框,并在圖像上繪制矩形。

3. 解析命令行參數和模型加載
if __name__ == '__main__':parser = argparse.ArgumentParser(description='Use this script to run age and gender recognition using OpenCV.')parser.add_argument('--input', help='Path to input image or video file. Skip this argument to capture frames from a camera.')parser.add_argument("--device", default="cpu", help="Device to inference on")args = parser.parse_args()

在腳本的主部分,它首先定義了命令行參數解析器,允許用戶指定輸入源(圖像或視頻文件,或者攝像頭流)和推理設備(CPU或GPU)。

    faceNet = cv.dnn.readNet(faceModel, faceProto)ageNet = cv.dnn.readNet(ageModel, ageProto)genderNet = cv.dnn.readNet(genderModel, genderProto)

這里,腳本加載了三個預訓練模型:人臉檢測、年齡預測和性別預測。每個模型都通過OpenCV的深度神經網絡模塊讀取。

4. 主循環
while cv.waitKey(1) < 0:hasFrame, frame = cap.read()if notFrame:cv.waitKey()breakframeFace, bboxes = getFaceBox(faceNet, frame)if not bboxes:print("No face Detected, Checking next frame")continue

在主循環中,腳本從視頻捕獲設備或圖像文件中讀取幀。然后它調用getFaceBox函數來獲取每幀中的人臉邊界框。

5. 性別和年齡識別
for bbox in bboxes:face = frame[max(0,bbox[1]-padding):min(bbox[3]+padding,frame.shape[0]-1),max(0,bbox[0]-padding):min(bbox[2]+padding, frame.shape[1]-1)]blob = cv.dnn.blobFromImage(face, 1.0, (227, 227), MODEL_MEAN_VALUES, swapRB=False)genderNet.setInput(blob)genderPreds = genderNet.forward()gender = genderList[genderPreds[0].argmax()]ageNet.setInput(blob)agePreds = ageNet.forward()age = ageList[agePreds[0].argmax()]label = "{},{}".format(gender, age)cv.putText(frameFace, label, (bbox[0], bbox[1]-10), cv.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 255), 2, cv.LINE_AA)cv.imshow("Age Gender Demo", frameFace)

對于每個檢測到的人臉,腳本提取人臉圖像并生成一個blob,然后將其輸入到性別和年齡識別模型中。通過模型的輸出,它確定每個人臉的性別和年齡,并在原始圖像上標記出這些信息。

完整代碼

# Import required modules
import cv2 as cv
import math
import time
import argparsedef getFaceBox(net, frame, conf_threshold=0.7):frameOpencvDnn = frame.copy()frameHeight = frameOpencvDnn.shape[0]frameWidth = frameOpencvDnn.shape[1]blob = cv.dnn.blobFromImage(frameOpencvDnn, 1.0, (300, 300), [104, 117, 123], True, False)net.setInput(blob)detections = net.forward()bboxes = []for i in range(detections.shape[2]):confidence = detections[0, 0, i, 2]if confidence > conf_threshold:x1 = int(detections[0, 0, i, 3] * frameWidth)y1 = int(detections[0, 0, i, 4] * frameHeight)x2 = int(detections[0, 0, i, 5] * frameWidth)y2 = int(detections[0, 0, i, 6] * frameHeight)bboxes.append([x1, y1, x2, y2])cv.rectangle(frameOpencvDnn, (x1, y1), (x2, y2), (0, 255, 0), int(round(frameHeight/150)), 8)return frameOpencvDnn, bboxesif __name__ == '__main__':parser = argparse.ArgumentParser(description='Use this script to run age and gender recognition using OpenCV.')parser.add_argument('--input', help='Path to input image or video file. Skip this argument to capture frames from a camera.')parser.add_argument("--device", default="cpu", help="Device to inference on")args = parser.parse_args()# args = parser.parse_args()faceProto = "opencv_face_detector.pbtxt"faceModel = "opencv_face_detector_uint8.pb"ageProto = "age_deploy.prototxt"ageModel = "age_net.caffemodel"genderProto = "gender_deploy.prototxt"genderModel = "gender_net.caffemodel"MODEL_MEAN_VALUES = (78.4263377603, 87.7689143744, 114.895847746)ageList = ['(0-2)', '(4-6)', '(8-12)', '(15-20)', '(25-32)', '(38-43)', '(48-53)', '(60-100)']genderList = ['Male', 'Female']# Load networkageNet = cv.dnn.readNet(ageModel, ageProto)genderNet = cv.dnn.readNet(genderModel, genderProto)faceNet = cv.dnn.readNet(faceModel, faceProto)if args.device == "cpu":ageNet.setPreferableBackend(cv.dnn.DNN_TARGET_CPU)genderNet.setPreferableBackend(cv.dnn.DNN_TARGET_CPU)faceNet.setPreferableBackend(cv.dnn.DNN_TARGET_CPU)print("Using CPU device")elif args.device == "gpu":ageNet.setPreferableBackend(cv.dnn.DNN_BACKEND_CUDA)ageNet.setPreferableTarget(cv.dnn.DNN_TARGET_CUDA)genderNet.setPreferableBackend(cv.dnn.DNN_BACKEND_CUDA)genderNet.setPreferableTarget(cv.dnn.DNN_TARGET_CUDA)genderNet.setPreferableBackend(cv.dnn.DNN_BACKEND_CUDA)genderNet.setPreferableTarget(cv.dnn.DNN_TARGET_CUDA)print("Using GPU device")#     # Open a video file or an image file or a camera streamcap = cv.VideoCapture(args.input if args.input else 0)padding = 20while cv.waitKey(1) < 0:# Read framet = time.time()hasFrame, frame = cap.read()if not hasFrame:cv.waitKey()breakframeFace, bboxes = getFaceBox(faceNet, frame)if not bboxes:print("No face Detected, Checking next frame")continuefor bbox in bboxes:# print(bbox)face = frame[max(0,bbox[1]-padding):min(bbox[3]+padding,frame.shape[0]-1),max(0,bbox[0]-padding):min(bbox[2]+padding, frame.shape[1]-1)]blob = cv.dnn.blobFromImage(face, 1.0, (227, 227), MODEL_MEAN_VALUES, swapRB=False)genderNet.setInput(blob)genderPreds = genderNet.forward()gender = genderList[genderPreds[0].argmax()]# print("Gender Output : {}".format(genderPreds))print("Gender : {}, conf = {:.3f}".format(gender, genderPreds[0].max()))ageNet.setInput(blob)agePreds = ageNet.forward()age = ageList[agePreds[0].argmax()]print("Age Output : {}".format(agePreds))print("Age : {}, conf = {:.3f}".format(age, agePreds[0].max()))label = "{},{}".format(gender, age)cv.putText(frameFace, label, (bbox[0], bbox[1]-10), cv.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 255), 2, cv.LINE_AA)cv.imshow("Age Gender Demo", frameFace)# cv.imwrite("age-gender-out-{}".format(args.input),frameFace)print("time : {:.3f}".format(time.time() - t))# cmake -DCMAKE_BUILD_TYPE=RELEASE -DCMAKE_INSTALL_PREFIX=~/opencv_gpu -DINSTALL_PYTHON_EXAMPLES=OFF -DINSTALL_C_EXAMPLES=OFF -DOPENCV_ENABLE_NONFREE=ON -DOPENCV_EXTRA_MODULES_PATH=~/cv2_gpu/opencv_contrib/modules -DPYTHON_EXECUTABLE=~/env/bin/python3 -DBUILD_EXAMPLES=ON -DWITH_CUDA=ON -DWITH_CUDNN=ON -DOPENCV_DNN_CUDA=ON  -DENABLE_FAST_MATH=ON -DCUDA_FAST_MATH=ON  -DWITH_CUBLAS=ON -DCUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda-10.2 -DOpenCL_LIBRARY=/usr/local/cuda-10.2/lib64/libOpenCL.so -DOpenCL_INCLUDE_DIR=/usr/local/cuda-10.2/include/ ..

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/11743.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/11743.shtml
英文地址,請注明出處:http://en.pswp.cn/web/11743.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ELK的詳解

ELK是由Elasticsearch、Logstash和Kibana三個開源軟件&#xff08;后來又新加了一個FileBeat&#xff09;組成的日志管理解決方案&#xff0c;這一組合在近年來得到了廣泛的關注和應用。以下是對這三個組件的詳細說明&#xff1a; Elasticsearch&#xff1a; Elasticsearch是…

nginx 負載均衡配置詳解

基于 ${nginx_home}/conf/nginx.conf 文件配置實現&#xff0c;如下&#xff1a; http {# 定義server地址upstream server_group {server 192.168.xxx.1:8080;server 192.168.xxx.2:8080;server 192.168.xxx.3:8080;}server {listen 80;location / {root html;index …

python數據分析——時間序列

時間序列 前言一、Datetime 模塊常用函數和數據結構的詳細解釋datetime模塊示例一示例二 二、時間運算示例一示例二示例三 三、時間序列分析自回歸(Autoregressive model/AR)模型示例 滑動平均(moving average model/MA)模型示例 自回歸滑動平均(Autoregressive moving average…

持續總結中!2024年面試必問 100 道 Java基礎面試題(四十五)

上一篇地址&#xff1a;持續總結中&#xff01;2024年面試必問 100 道 Java基礎面試題&#xff08;四十四&#xff09;-CSDN博客 八十九、在Java中&#xff0c;什么是線程局部變量&#xff08;ThreadLocal變量&#xff09;&#xff1f; 在Java中&#xff0c;ThreadLocal變量是…

企業微信hook接口協議,ipad協議http,發送鏈接的方式邀請成員進群

發送鏈接的方式邀請成員進群 參數名必選類型說明uuid是String每個實例的唯一標識&#xff0c;根據uuid操作具體企業微信 請求示例 {"uuid":"3240fde0-45e2-48c0-90e8-cb098d0ebe43","roomid":10696052955013729, "vids":[788130334…

Flutter 中的 CircleAvatar 小部件:全面指南

Flutter 中的 CircleAvatar 小部件&#xff1a;全面指南 在 Flutter 中&#xff0c;CircleAvatar 是一個用于顯示頭像的圓形控件&#xff0c;通常包含一個圖標、圖片或者一個簡單的文本字符。它在設計上與 Material Design 指南中的頭像規范相匹配&#xff0c;常用于展示用戶信…

C# 常用匯總

時間處理 public static class DateTimeHelper{/// <summary>/// 獲取當前時間戳&#xff08;Unix時間戳&#xff09; /// </summary>/// <returns></returns>public static long GetCurrentUnixTimestamp(){DateTimeOffset offset DateTimeOffset.…

Qt---文件系統

一、基本文件操作 1. QFile對文件進行讀和寫 QFile file( path 文件路徑) 讀&#xff1a; file.open(打開方式) QlODevice::readOnly 全部讀取->file.readAll()&#xff0c;按行讀->file.readLine()&#xff0c;atend()->判斷是否讀到文件尾 …

Java網絡編程基礎

Java網絡編程基礎主要涉及進程間通信、網絡通信協議、IP地址和端口以及Java提供的網絡應用編程接口等核心概念。 進程間通信是Java網絡編程的基礎。進程是運行中的程序&#xff0c;而進程間通信則是指不同進程之間進行數據交換和共享信息的過程。在Java中&#xff0c;進程間的…

STM32存儲左右互搏 USB接口FATS文件讀寫U盤

STM32存儲左右互搏 USB接口FATS文件讀寫U盤 STM32的USB接口可以例化為Host主機從而對U盤進行操作。SD卡/MicroSD/TF卡也可以通過讀卡器轉換成U盤使用。這里介紹STM32CUBEIDE開發平臺HAL庫實現U盤FATS文件訪問的例程。 USB接口介紹 常見的USB接口電路部分相似而有不同的連接器…

K8S -----二進制搭建 Kubernetes v1.20

目錄 一、準備環境 1.1 修改主機名 1.2 關閉防火墻&#xff08;三臺一起&#xff0c;這里只展示master01&#xff09; 1.3 在master添加hosts&#xff08;依舊是三臺一起&#xff09; 1.4 調整內核參數并開啟網橋模式 二、部署docker引擎 三、部署 etcd 集群 1.在mast…

15.JUC原子類

文章目錄 JUC原子類1.JUC中的Atomic原子操作包1.1. 基本原子類&#xff08;Basic Atomic Classes&#xff09;1.2. 數組原子類&#xff08;Array Atomic Classes&#xff09;1.3. 引用原子類&#xff08;Reference Atomic Classes&#xff09;4. 字段更新原子類&#xff08;Fie…

StackQueue+泛型簡單理解

&#x1f341; 個人主頁&#xff1a;愛編程的Tom&#x1f4ab; 本篇博文收錄專欄&#xff1a;Java專欄&#x1f449; 目前其它專欄&#xff1a;c系列小游戲 c語言系列--萬物的開始_ &#x1f389; 歡迎 &#x1f44d;點贊?評論?收藏&#x1f496;三連支持一…

ddpm Denoising Diffusion Probabilistic Model 學習筆記

目錄 Stable Diffusion 文章的貢獻抽象出來就兩個 潛空間上做擴散生成 ddpm(Denoising Diffusion Probabilistic Model)學習筆記 算法原理 unet預測噪聲 unet推理過程 重參數化技巧 &#xff08;1&#xff09;利用前一時刻的 xt-1 得到任意時刻的噪聲圖片 xt&#xff…

LeetCode2215找出兩數組的不同

題目描述 給你兩個下標從 0 開始的整數數組 nums1 和 nums2 &#xff0c;請你返回一個長度為 2 的列表 answer &#xff0c;其中&#xff1a;answer[0] 是 nums1 中所有 不 存在于 nums2 中的 不同 整數組成的列表。answer[1] 是 nums2 中所有 不 存在于 nums1 中的 不同 整數組…

Linux poweroff命令教程:如何實現一鍵關機(附實例詳解和注意事項)

Linux poweroff命令介紹 poweroff命令是用來關閉系統的。當你執行這個命令時&#xff0c;它會發送一個信號給系統&#xff0c;告訴系統關閉所有的進程&#xff0c;然后關閉系統。這個命令非常有用&#xff0c;特別是在你需要遠程關閉系統&#xff0c;或者你的系統沒有圖形用戶…

Autosar架構

藍框那種叫component&#xff0c;綠框的叫function cluster。 接口 有三種接口&#xff0c;RTE跟SWC之間鏈接的叫Autosar Interface&#xff0c;RTE跟BSW的Components鏈接是Standardized Interface&#xff0c;RTE跟BSW的services鏈接的是Standardized Autosar Interface。 St…

項目部署到線上proxytable代理失效nginx報404的問題

我的項目是在vue的config文件夾中的index.js中配置了接口地址 &#xff0c;本地跑的時候都能訪問&#xff0c;放到線上就報404&#xff1b; module.exports {dev: {// PathsassetsSubDirectory: static,assetsPublicPath: /,proxyTable: {/xxx: {target: http://xxxxxxxx:xxx…

分享四種CAD圖紙加密方法,嚴防盜圖

在數字化時代&#xff0c;cad圖紙的盜用和非法傳播問題日益突出。對于企業和設計師來說&#xff0c;保護設計成果的安全性和原創性&#xff0c;采取有效的cad加密方法至關重要。本文將分享四種cad加密方法&#xff0c;幫助您嚴防盜圖&#xff0c;保護圖紙安全。 使用cad軟件內…

網絡協議的分類

1.概要 網絡協議可以分為三類&#xff1a; 封裝協議路由協議功能類協議 2.分類說明 OSPF報文直接調用_ IP協議__協議進行封裝&#xff0c;以目的地址_244.0.0.5 __發送到所有的OSPF路由器? 244.0.0.1 所有主機&#xff1b;244.0.0.2 所有路由器&#xff1b;244.0.0.6 指定…