first commit
This commit is contained in:
25
network_camera_receiver/CMakeLists.txt
Normal file
25
network_camera_receiver/CMakeLists.txt
Normal file
@@ -0,0 +1,25 @@
|
||||
# ============================================================================
|
||||
# network_camera_receiver —— 静态库
|
||||
# 仅负责从网络视频流抓取最新帧,不包含任何人脸检测逻辑、不依赖 libfacedetection。
|
||||
# ============================================================================
|
||||
|
||||
add_library(network_camera_receiver STATIC
|
||||
src/network_camera_receiver.cpp
|
||||
)
|
||||
|
||||
target_include_directories(network_camera_receiver PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
)
|
||||
|
||||
# OpenCV 用于视频采集;Threads 用于后台抓帧线程。
|
||||
# 设为 PUBLIC,链接本库的目标可传递获得这些依赖。
|
||||
target_link_libraries(network_camera_receiver PUBLIC
|
||||
${OpenCV_LIBS}
|
||||
Threads::Threads
|
||||
)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||
target_compile_options(network_camera_receiver PRIVATE -O3)
|
||||
elseif(MSVC)
|
||||
target_compile_options(network_camera_receiver PRIVATE /O2)
|
||||
endif()
|
||||
47
network_camera_receiver/include/network_camera_receiver.h
Normal file
47
network_camera_receiver/include/network_camera_receiver.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* @Author: Liu zhenyu
|
||||
* @Description: 网络摄像头接收器(重构版)
|
||||
* 仅负责从视频流抓取最新帧,不做任何检测/显示。
|
||||
* 主程序通过 getLatestFrame() 拉取最新帧后自行处理。
|
||||
*/
|
||||
|
||||
#ifndef NETWORK_CAMERA_RECEIVER_H
|
||||
#define NETWORK_CAMERA_RECEIVER_H
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
|
||||
class NetworkCameraReceiver {
|
||||
public:
|
||||
NetworkCameraReceiver(const std::string& host_ip, int port = 5000);
|
||||
~NetworkCameraReceiver();
|
||||
|
||||
// 打开视频流
|
||||
bool connect();
|
||||
// 启动后台抓帧线程(不阻塞)
|
||||
void start();
|
||||
// 停止抓帧线程并 join
|
||||
void stop();
|
||||
// 取最新帧(深拷贝到 out);自上次取帧后若无新帧则返回 false
|
||||
bool getLatestFrame(cv::Mat& out);
|
||||
// 视频流是否已打开
|
||||
bool isOpened() const;
|
||||
|
||||
private:
|
||||
// 后台抓帧循环
|
||||
void captureLoop();
|
||||
|
||||
std::string stream_url;
|
||||
cv::VideoCapture cap;
|
||||
|
||||
std::thread capture_thread;
|
||||
std::mutex mtx; // 保护 latest_frame
|
||||
cv::Mat latest_frame; // 最新一帧
|
||||
std::atomic<bool> has_new_frame{false};
|
||||
std::atomic<bool> running{false};
|
||||
};
|
||||
|
||||
#endif // NETWORK_CAMERA_RECEIVER_H
|
||||
73
network_camera_receiver/src/network_camera_receiver.cpp
Normal file
73
network_camera_receiver/src/network_camera_receiver.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* @Author: Liu zhenyu
|
||||
* @Description: 网络摄像头接收器(重构版)实现
|
||||
* 后台线程持续抓帧并更新最新帧缓冲;主线程按需拉取。
|
||||
*/
|
||||
|
||||
#include "network_camera_receiver.h"
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
|
||||
NetworkCameraReceiver::NetworkCameraReceiver(const std::string& host_ip, int port) {
|
||||
stream_url = "http://" + host_ip + ":" + std::to_string(port) + "/video";
|
||||
}
|
||||
|
||||
NetworkCameraReceiver::~NetworkCameraReceiver() {
|
||||
stop();
|
||||
if (cap.isOpened()) cap.release();
|
||||
}
|
||||
|
||||
bool NetworkCameraReceiver::connect() {
|
||||
std::cout << "尝试连接到视频流: " << stream_url << std::endl;
|
||||
cap.open(stream_url);
|
||||
if (!cap.isOpened()) {
|
||||
std::cerr << "无法打开视频流: " << stream_url << std::endl;
|
||||
return false;
|
||||
}
|
||||
std::cout << "视频流连接成功。" << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetworkCameraReceiver::isOpened() const {
|
||||
return cap.isOpened();
|
||||
}
|
||||
|
||||
void NetworkCameraReceiver::start() {
|
||||
// 已在运行则直接返回
|
||||
if (running.exchange(true)) return;
|
||||
capture_thread = std::thread(&NetworkCameraReceiver::captureLoop, this);
|
||||
}
|
||||
|
||||
void NetworkCameraReceiver::stop() {
|
||||
// 未运行则直接返回
|
||||
if (!running.exchange(false)) return;
|
||||
if (capture_thread.joinable()) capture_thread.join();
|
||||
}
|
||||
|
||||
void NetworkCameraReceiver::captureLoop() {
|
||||
cv::Mat frame;
|
||||
while (running.load()) {
|
||||
cap >> frame;
|
||||
if (frame.empty()) {
|
||||
// 流暂未就绪或读取失败,稍作等待避免空转占满 CPU
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
continue;
|
||||
}
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
// 仅保留最新一帧,旧帧直接丢弃
|
||||
frame.copyTo(latest_frame);
|
||||
}
|
||||
has_new_frame.store(true);
|
||||
}
|
||||
}
|
||||
|
||||
bool NetworkCameraReceiver::getLatestFrame(cv::Mat& out) {
|
||||
if (!has_new_frame.load()) return false;
|
||||
// 先清标记:若在此期间后台又写入新帧,标记会被再次置 true,下一轮可取到
|
||||
has_new_frame.store(false);
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
if (latest_frame.empty()) return false;
|
||||
latest_frame.copyTo(out);
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user