This commit is contained in:
2025-11-07 16:48:14 +08:00
parent 6bdd25e210
commit fa6bc474dc
2 changed files with 74 additions and 17 deletions

Binary file not shown.

View File

@@ -9,6 +9,7 @@
#include <iostream> #include <iostream>
#include <opencv4/opencv2/opencv.hpp> #include <opencv4/opencv2/opencv.hpp>
#include <mqtt/async_client.h> #include <mqtt/async_client.h>
#include <nlohmann/json.hpp>
using namespace std; using namespace std;
using namespace cv; using namespace cv;
@@ -16,18 +17,30 @@ using namespace chrono_literals;
// 全局变量 // 全局变量
VideoCapture cap(0); VideoCapture cap(0);
Mat handleFrame;
const string mqtt_url = "tcp://192.168.12.1:1883";
const string clientId = "video_subData";
const string Topic = "/video/Data";
const int Qos = 1;
mqtt::async_client client(mqtt_url, clientId);
// 函数声明 // 函数声明
//摄像头管道初始化 // mqtt初始化
void MqttInit();
// 摄像头管道初始化
bool videoInit(VideoCapture &cap); bool videoInit(VideoCapture &cap);
//ffmpeg管道初始化 // ffmpeg管道初始化
FILE* pipeInit(); FILE *pipeInit();
//对单个帧进行处理 // 对单个帧进行处理
bool processFrame(VideoCapture &cap, FILE* pipe, Mat &frame, int64 &count, chrono::steady_clock::time_point &t0); bool processFrame(VideoCapture &cap, FILE *pipe, Mat &frame, int64 &count, chrono::steady_clock::time_point &t0);
//资源清理 // 资源清理
void cleanup(FILE* pipe, VideoCapture &cap); void cleanup(FILE *pipe, VideoCapture &cap);
//主循环 // 主循环
void mainLoop(VideoCapture &cap, FILE* pipe); void mainLoop(VideoCapture &cap, FILE *pipe);
// mqtt接收订阅消息的回调
void getMsgCallback(mqtt::const_message_ptr msg);
// 绘制矩形方框和深度信息
void drawRect(int x, int y, int w, int h, double distance);
int main() int main()
{ {
@@ -53,6 +66,34 @@ int main()
return 0; return 0;
} }
// 绘制矩形方框和深度信息
void drawRect(int x, int y, int w, int h, double distance)
{
Rect r(x, y, w, h);
rectangle(handleFrame, r, Scalar(0, 255, 0), 2);
}
// mqtt初始化
void MqttInit()
{
// 设置回调
client.set_connected_handler([](const string &cause)
{ cout << "连接成功" << endl; });
client.set_message_callback(getMsgCallback);
client.connect()->wait();
client.subscribe(Topic, Qos)->wait();
}
// mqtt接收订阅消息的回调
void getMsgCallback(mqtt::const_message_ptr msg)
{
string payload = msg->to_string();
cout << payload << endl;
}
// 摄像头初始化 // 摄像头初始化
bool videoInit(VideoCapture &cap) bool videoInit(VideoCapture &cap)
{ {
@@ -74,7 +115,7 @@ bool videoInit(VideoCapture &cap)
} }
// FFmpeg管道初始化 // FFmpeg管道初始化
FILE* pipeInit() FILE *pipeInit()
{ {
FILE *pipe = popen( FILE *pipe = popen(
"ffmpeg " "ffmpeg "
@@ -102,7 +143,7 @@ FILE* pipeInit()
} }
// 处理单帧 // 处理单帧
bool processFrame(VideoCapture &cap, FILE* pipe, Mat &frame, int64 &count, chrono::steady_clock::time_point &t0) bool processFrame(VideoCapture &cap, FILE *pipe, Mat &frame, int64 &count, chrono::steady_clock::time_point &t0)
{ {
// 读取帧 // 读取帧
cap.read(frame); cap.read(frame);
@@ -112,8 +153,11 @@ bool processFrame(VideoCapture &cap, FILE* pipe, Mat &frame, int64 &count, chron
return false; return false;
} }
// 拷贝视频帧
handleFrame = frame;
// 添加提示文本 // 添加提示文本
putText(frame, "press 'q' to quit", Point(0, 20), putText(frame, "press 'q' to quit", Point(0, 20),
FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 255, 0), 2, LINE_8); FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 255, 0), 2, LINE_8);
// FPS计算与显示 // FPS计算与显示
@@ -121,7 +165,7 @@ bool processFrame(VideoCapture &cap, FILE* pipe, Mat &frame, int64 &count, chron
auto now = chrono::steady_clock::now(); auto now = chrono::steady_clock::now();
if (chrono::duration_cast<chrono::milliseconds>(now - t0).count() / 1000.0 > 1.0) if (chrono::duration_cast<chrono::milliseconds>(now - t0).count() / 1000.0 > 1.0)
{ {
string fps = "FPS:" + to_string(count); string fps = "FPS:" + to_string(count);
count = 0; count = 0;
t0 = now; t0 = now;
} }
@@ -137,21 +181,34 @@ bool processFrame(VideoCapture &cap, FILE* pipe, Mat &frame, int64 &count, chron
} }
// 主处理循环 // 主处理循环
void mainLoop(VideoCapture &cap, FILE* pipe) void mainLoop(VideoCapture &cap, FILE *pipe)
{ {
int64 count = 0; int64 count = 0;
auto t0 = chrono::steady_clock::now(); auto t0 = chrono::steady_clock::now();
Mat frame; Mat frame;
cout << "开始视频处理循环..." << endl; cout << "开始视频处理循环..." << endl;
// 创建全屏窗口
namedWindow("处理后的画面", WINDOW_NORMAL);
setWindowProperty("处理后的画面", WND_PROP_FULLSCREEN, WINDOW_FULLSCREEN);
// 获取屏幕尺寸(通过获取全屏窗口的实际大小)
cv::Rect windowRect = getWindowImageRect("处理后的画面");
int screenWidth = windowRect.width > 0 ? windowRect.width : 1920;
int screenHeight = windowRect.height > 0 ? windowRect.height : 1080;
Mat displayFrame; // 用于存储缩放后的画面
while (true) while (true)
{ {
if (!processFrame(cap, pipe, frame, count, t0)) if (!processFrame(cap, pipe, frame, count, t0))
{ {
break; break;
} }
// 将 handleFrame 缩放到全屏尺寸
resize(handleFrame, displayFrame, Size(screenWidth, screenHeight));
imshow("处理后的画面", displayFrame);
// 检测退出键 // 检测退出键
if (cv::waitKey(1) == 'q') if (cv::waitKey(1) == 'q')
{ {
@@ -162,7 +219,7 @@ void mainLoop(VideoCapture &cap, FILE* pipe)
} }
// 资源清理 // 资源清理
void cleanup(FILE* pipe, VideoCapture &cap) void cleanup(FILE *pipe, VideoCapture &cap)
{ {
if (pipe) if (pipe)
{ {