MTCNN 人臉識別

前言?

此處介紹強大的 MTCNN 模塊,給出demo,展示MTCNN?的 OOP,?以及ROS利用 C++ 節點,命令行調用腳本執行實際工作的思路。

?MTCNN Script

import argparse
import cv2
from mtcnn import MTCNN
import osclass MTCNNProcessor:def __init__(self):"""初始化MTCNN檢測器和繪圖配置"""self.detector = MTCNN()  # 模型只加載一次self.keypoint_colors = {  # 關鍵點顏色配置'left_eye': (0, 255, 0),'right_eye': (0, 255, 0),'nose': (255, 0, 255),'mouth_left': (255, 255, 0),'mouth_right': (255, 255, 0)}def process_image(self, input_path="/home/ncut/Pictures/MTCNN_test.jpg", output_path=None):"""完整處理流程入口:param input_path: 輸入圖像路徑:param output_path: 輸出圖像路徑 (None則不保存):return: 帶標注的BGR圖像數組"""image = self._load_image(input_path)if image is None:raise FileNotFoundError(f"圖像文件 {input_path} 不存在或無法讀取")results = self.detect_faces(image)annotated_image = self.draw_results(image.copy(), results)if output_path:self._save_image(annotated_image, output_path)return annotated_imagedef detect_faces(self, image):"""執行人臉檢測"""return self.detector.detect_faces(image)def draw_results(self, image, results):"""在圖像上繪制檢測結果"""for result in results:x, y, w, h = result['box']confidence = result['confidence']# 繪制邊界框和置信度cv2.rectangle(image, (x, y), (x + w, y + h), (255, 0, 0), 2)cv2.putText(image, f"{confidence:.2%}", (x, y - 10),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)# 繪制關鍵點for name, pos in result['keypoints'].items():cv2.circle(image, pos, 3, self.keypoint_colors.get(name, (255, 255, 255)), 2)return image@staticmethoddef _load_image(path):"""加載圖像并轉換為RGB格式"""if not os.path.exists(path):return Noneimage = cv2.imread(path)return cv2.cvtColor(image, cv2.COLOR_BGR2RGB) if image is not None else None@staticmethoddef _save_image(image, path):"""保存圖像到指定路徑"""cv2.imwrite(path, cv2.cvtColor(image, cv2.COLOR_RGB2BGR))def main():# 命令行參數解析print("in python begin")parser = argparse.ArgumentParser(description='MTCNN人臉檢測處理器')parser.add_argument('--input', required=True, help='輸入圖像路徑')parser.add_argument('--output', help='輸出圖像路徑 (可選)')args = parser.parse_args()print("parse succeed")# 創建處理器實例processor = MTCNNProcessor()try:# 執行處理流程result_image = processor.process_image(args.input, args.output)# 可選:顯示結果(調試時使用)if os.environ.get('DEBUG_SHOW'):import matplotlib.pyplot as pltplt.imshow(result_image)plt.axis('off')plt.show()except Exception as e:print(f"處理失敗: {str(e)}")exit(1)print("python process successfully done")if __name__ == "__main__":main()

上文中,我們在 init部分實現了初始化,包括模型的加載,關鍵點顏色的硬編碼——這部分將直接作用于后續的圖像繪制。因為MTCNN模型的幫助,這里我們不需要預處理圖像,直接調用方法進行。注意到類中有兩個 static method,用修飾符@標識,這是python特有的語法,類似C++中的 static method,獨立于變量,由類的方式調用,也許跟單例有關。

實際上,對于MTCNN模塊,在環境正確配置后,通過下述語句,能夠進行推理

from mtcnn import MTCNN
detector = MTCNN()
image = cv2.cvtColor(cv2.imread('/home/ncut/Pictures/MTCNN_test.jpg'), cv2.COLOR_BGR2RGB)
results = detector.detect_faces(image)
x, y, width, height = result['box']
confidence = result['confidence']

?

ROS Topic subscriber?

C++的sub節點,訂閱topic,保存圖片,通過命令行方式指定python版本,執行模型推理。

#include <ros/ros.h>
#include <sensor_msgs/Image.h>
#include <cv_bridge/cv_bridge.h>
#include <opencv2/opencv.hpp>
#include <cstdlib>
#include <ctime>
#include <string>
#include <sstream>// 生成唯一文件名(替代 generate_uuid())
std::string generate_unique_id() {static int counter = 0;std::stringstream ss;ss << time(nullptr) << "_" << counter++;  // 時間戳 + 計數器return ss.str();
}void imageCallback(const sensor_msgs::ImageConstPtr& msg) {ROS_INFO("process callback");try {// 轉換 ROS 圖像消息cv_bridge::CvImagePtr cv_ptr = cv_bridge::toCvCopy(msg, "bgr8");cv::Mat image = cv_ptr->image;// 生成唯一文件名(避免多幀覆蓋)std::string uuid = generate_unique_id();std::string temp_path = "/dev/shm/ros_input_" + uuid + ".jpg";std::string output_path = "/dev/shm/ros_output_" + uuid + ".jpg";// 保存輸入圖像cv::imwrite(temp_path, image);// 構建 Python 調用命令std::string command = "DEBUG_SHOW=1 ""/home/ncut/miniconda3/envs/tf/bin/python /home/ncut/my_ws/src/graduation_design/scripts/MTCNN_photo.py ""--input " + temp_path + " ""--output " + output_path + " ""&";  // attention here// 調用 Python 腳本int ret = std::system(command.c_str());if (ret != 0) {ROS_ERROR("Python腳本調用失敗,返回碼: %d", ret);return;}ROS_INFO("invoke python script sucessfully");} catch (cv_bridge::Exception& e) {ROS_ERROR("cv_bridge異常: %s", e.what());}
}void MessageCallback()
{ROS_INFO("NOW I am in the callback funciton");return ;
}int main(int argc, char** argv) {ros::init(argc, argv, "MTCNN_sub_photo");ros::NodeHandle nh;// PC test, topic name is camera/image_raw, which matches the video_pub.pyros::Subscriber sub = nh.subscribe("/camera/rgb/image_raw", 2, imageCallback);ROS_INFO("now i will go into the ros::ok() loop");ros::Rate loop_rate(0.04); while(ros::ok()) {ros::spinOnce();    // asynchronous wayloop_rate.sleep();}//ros::spin();system("rm -f /dev/shm/ros_input_*.jpg  /dev/shm/ros_output_*.jpg");return 0;
}

這份代碼展示了 ROS 編程的范例,比如 while?loop 以 ros::ok()? 為循環判斷條件。用于生成唯一std::stringstream變量名的time()使用,附加計數器標識圖片文件先后存儲順序。在 /dev/shm/共享內存目錄保存文件,減少文件讀寫 I/O, 以及通過 std::stream()方式,運行命令行指令。

In conclusion

這些技巧展示了解決方案的多樣性,也展示了C++與命令行、系統時間的交互。——實際上,不少我們熟知的、主觀上認為獨立的計算機概念,可能都以類似的方式彼此連接著。

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

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

相關文章

01_核心系統下的技術原理解析

15年前&#xff0c;基本上國內的核心系統被C壟斷&#xff0c;基本上是IBM的那套東西&#xff0c;場景也是比價復雜&#xff0c;這里不再贅述&#xff0c;TPS太過于龐大&#xff0c;技術上確實比較復雜。為此我這里拋磚引玉&#xff0c;說下對應的支付系統&#xff1a; &#x…

Python 實現最小插件框架

文章目錄 Python 實現最小插件框架1. 基礎實現項目結構plugin_base.py - 插件基類plugins/hello.py - 示例插件1plugins/goodbye.py - 示例插件2main.py - 主程序 2. 更高級的特性擴展2.1 插件配置支持2.2 插件依賴管理2.3 插件熱加載 3. 使用 setuptools 的入口點發現插件3.1 …

電感詳解:定義、作用、分類與使用要點

一、電感的基本定義 電感&#xff08;Inductor&#xff09; 是由導線繞制而成的儲能元件&#xff0c;其核心特性是阻礙電流變化&#xff0c;將電能轉化為磁能存儲。 基本公式&#xff1a; 自感電動勢&#xff1a; E -L * (di/dt) &#xff08;L&#xff1a;電感值&#xff0c…

運行一次性任務與定時任務

運行一次性任務與定時任務 文章目錄 運行一次性任務與定時任務[toc]一、使用Job運行一次性任務1.創建一次性任務2.測試一次性任務3.刪除Job 二、使用CronJob運行定時任務1.創建定時任務2.測試定時任務3.刪除CronJob 一、使用Job運行一次性任務 1.創建一次性任務 &#xff08;…

對話記憶(Conversational Memory)

一、引言 在與大型語言模型&#xff08;LLM&#xff09;交互的場景中&#xff0c;對話記憶&#xff08;Conversational Memory&#xff09;指的是模型能夠在多輪對話中保留、檢索并利用先前上下文信息的能力。這一機制使得對話系統不再僅僅是“問答機”&#xff0c;而是能夠持…

【HD-RK3576-PI】VNC 遠程桌面連接

在當今數字化時代&#xff0c;高效便捷的操作方式是技術愛好者與專業人士的共同追求。對于使用 HD-RK3576-PI微型單板計算機的用戶而言&#xff0c;當面臨沒有顯示屏的場景時&#xff0c;如何實現遠程操作桌面系統呢&#xff1f;別擔心&#xff0c;VNC 遠程桌面連接將為你解決這…

【unity游戲開發介紹之UGUI篇】UGUI概述和基礎使用

注意&#xff1a;考慮到UGUI的內容比較多&#xff0c;我將UGUI的內容分開&#xff0c;并全部整合放在【unity游戲開發介紹之UGUI篇】專欄里&#xff0c;感興趣的小伙伴可以前往逐一查看學習。 文章目錄 前言1、UI系統的重要性2、UGUI概述2.1 基本定義2.2 UGUI發展歷史 3、學習U…

Ubuntu 系統深度清理:徹底卸載 Redis 服務及殘留配置

Ubuntu 系統深度清理&#xff1a;徹底卸載 Redis 服務及殘留配置 在Ubuntu系統中&#xff0c;Redis是一種廣泛使用的內存數據存儲系統&#xff0c;用于緩存和消息傳遞等場景。然而&#xff0c;有時候我們需要徹底卸載Redis&#xff0c;以清理系統資源或為其他應用騰出空間。本…

[ARC196A] Adjacent Delete 題解

假設 n n n 是偶數。如果我們忽略刪除相鄰數的條件&#xff0c;即可以任選兩個數相減&#xff0c;那么答案應該是前 n 2 \frac{n}{2} 2n? 大的數&#xff08;記作“較大數”&#xff09;的和減去前 n 2 \frac{n}{2} 2n? 小的數&#xff08;記作“較小數”&#xff09;的和…

Linux上位機開發實踐(關于Qt的移植)

【 聲明&#xff1a;版權所有&#xff0c;歡迎轉載&#xff0c;請勿用于商業用途。 聯系信箱&#xff1a;feixiaoxing 163.com】 linux平臺上面&#xff0c;很多界面應用&#xff0c;都是基于qt開發的。不管是x86平臺&#xff0c;還是arm平臺&#xff0c;qt使用的地方都比較多。…

”插入排序“”選擇排序“

文章目錄 插入排序1. 直接插入排序(O(n^2))舉例1&#xff1a;舉例2&#xff1a;直插排序的"代碼"直插排序的“時間復雜度” 2. 希爾排序(O(n^1.3))方法一方法二(時間復雜度更優) 選擇排序堆排序直接選擇排序 我們學過冒泡排序&#xff0c;堆排序等等。&#xff08;回…

FPGA_BD Block Design學習(一)

PS端開發流程詳細步驟 1.第一步&#xff1a;打開Vivado軟件&#xff0c;創建或打開一個工程。 2.第二步&#xff1a;在Block Design中添加arm核心&#xff0c;并將其配置為IP核。 3.第三步&#xff1a;配置arm核心的外設信息&#xff0c;如DDR接口、時鐘頻率、UART接口等。 …

【Python] pip制作離線包

制作離線安裝包是一種非常實用的方法&#xff0c;尤其是在網絡環境受限或需要在多臺機器上部署相同環境時。以下是詳細的步驟&#xff0c;幫助您創建一個包含所有依賴項的離線安裝包&#xff0c;并在后續環境中復用。 步驟 1&#xff1a;準備工具和環境 確保您有一臺可以訪問互…

為啥物聯網用MQTT?

前言 都說物聯網用MQTT&#xff0c;那分別使用Http和Mqtt發送“Hello”&#xff0c;比較一下就知道啦 HTTP HTTP請求報文由請求行、頭部字段和消息體組成。一個最簡單的HTTP POST請求如下&#xff1a; POST / HTTP/1.1 Host: example.com Content-Length: 5 Content-Type: …

操作系統 ------ 五種IO模型

阻塞IO&#xff1a;一個IO請求操作&#xff0c;準備階段和復制階段都會阻塞應用程序&#xff0c;直到操作完全完成 非阻塞IO&#xff1a;一個IO操作請求&#xff0c;先判斷準備階段是否完成&#xff0c;如果未完成立即返回&#xff0c;否則&#xff0c;進入復制階段&#xff0…

service和endpoints是如何關聯的?

在Kubernetes中&#xff0c;Service 和 Endpoints 是兩個密切關聯的對象&#xff0c;它們共同實現了服務發現和負載均衡的功能。以下是它們之間的關聯和工作原理&#xff1a; 1. Service 的定義 Service 是一種抽象&#xff0c;定義了一組邏輯上相關的 Pod&#xff0c;以及用…

程序化廣告行業(78/89):多因素交織下的行業剖析與展望

程序化廣告行業&#xff08;78/89&#xff09;&#xff1a;多因素交織下的行業剖析與展望 在程序化廣告這片充滿活力又不斷變化的領域&#xff0c;持續學習和知識共享是我們緊跟潮流、實現突破的關鍵。一直以來&#xff0c;我都渴望能與大家一同探索這個行業的奧秘&#xff0c…

數智化重構供應商管理

當供應鏈韌性成為核心競爭力&#xff0c;你的供應商管理還在 “摸著石頭過河” 嗎&#xff1f; 在傳統模式下&#xff0c;供應商管理高度依賴人工經驗與紙質流程&#xff1a; 入庫篩選如“大海撈針”&#xff1a;供應商資質審核停留在Excel表格比對&#xff0c;資質造假、歷史…

網絡互連與互聯網

1.在路由表中找不到目標網絡時使用默認路由&#xff0c;默認路由通常指本地網關的地址。 2.OSPF最主要的特征是使用分布式鏈路狀態協議&#xff0c;而RIP使用的是距離向量協議。 3.OSPF使用鏈路狀態公告LSA擴散路由信息 4.內部網關路由協議IGRP是一種動態距離矢量路由協議&a…

Raymarching Textures In Depth

本節課最主要的就是學會hlsl中使用紋理采樣 float4 color Texture2DSample(Texobj, TexobjSampler, uv); return color; 課程中的代碼&#xff08;沒有這張圖我就沒做&#xff09; 課程代碼產生深度的原因是uv偏移&#xff0c;黑色區域會不斷向左偏移&#xff0c;直到找到白色…