draw
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
本程序用于视频分流
|
本程序用于视频分流
|
||||||
1.推流摄像头画面至RTSP服务器,交由YOLO模型进行处理
|
1.推流摄像头画面,使用UDP原生协议进行推流,交由YOLO模型进行处理
|
||||||
2.接收YOLO传来的坐标,深度,警报等级等等数据
|
2.接收YOLO传来的坐标,深度,警报等级等等数据
|
||||||
3.根据获取到的数据绘制边框和相应数据
|
3.根据获取到的数据绘制边框和相应数据
|
||||||
4.将绘制完毕的视频流继续推流至RTSP服务器用于输出
|
4.将绘制完毕的视频流继续推流至RTSP服务器用于输出
|
||||||
@@ -17,7 +17,7 @@ using namespace chrono_literals;
|
|||||||
|
|
||||||
// 全局变量
|
// 全局变量
|
||||||
VideoCapture cap(0);
|
VideoCapture cap(0);
|
||||||
Mat handleFrame;
|
Mat handleFrame; // 存放处理后的帧
|
||||||
const string mqtt_url = "tcp://192.168.12.1:1883";
|
const string mqtt_url = "tcp://192.168.12.1:1883";
|
||||||
const string clientId = "video_subData";
|
const string clientId = "video_subData";
|
||||||
const string Topic = "/video/PersonData";
|
const string Topic = "/video/PersonData";
|
||||||
@@ -57,7 +57,7 @@ int main()
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化mqtt
|
// 初始化mqtt:订阅,回调函数
|
||||||
MqttInit();
|
MqttInit();
|
||||||
|
|
||||||
// 主处理循环
|
// 主处理循环
|
||||||
@@ -93,12 +93,22 @@ void MqttInit()
|
|||||||
void getMsgCallback(mqtt::const_message_ptr msg)
|
void getMsgCallback(mqtt::const_message_ptr msg)
|
||||||
{
|
{
|
||||||
string payload = msg->to_string();
|
string payload = msg->to_string();
|
||||||
cout << "Recv payload: " << payload << endl;
|
|
||||||
|
|
||||||
thread([payload]()
|
thread([payload]()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
// TODO 处理接收到到的位置数据
|
// TODO 处理接收到到的位置数据
|
||||||
|
auto json = nlohmann::json::parse(payload);
|
||||||
|
//绘制标况
|
||||||
|
for(auto & ii :json)
|
||||||
|
{
|
||||||
|
int x = static_cast<int>(ii["x"]);
|
||||||
|
int y = static_cast<int>(ii["y"]);
|
||||||
|
int w = static_cast<int>(ii["w"]);
|
||||||
|
int h = static_cast<int>(ii["h"]);
|
||||||
|
double distance = static_cast<double>(ii["distance"]);
|
||||||
|
drawRect(x,y,w,h,distance);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (const nlohmann::json::parse_error &e) {
|
catch (const nlohmann::json::parse_error &e) {
|
||||||
cerr << "JSON 解析错误: " << e.what() << "\n原始 payload: " << payload << "\n";
|
cerr << "JSON 解析错误: " << e.what() << "\n原始 payload: " << payload << "\n";
|
||||||
@@ -171,20 +181,6 @@ bool processFrame(VideoCapture &cap, FILE *pipe, Mat &frame, int64 &count, chron
|
|||||||
// 拷贝视频帧
|
// 拷贝视频帧
|
||||||
handleFrame = frame;
|
handleFrame = frame;
|
||||||
|
|
||||||
auto now_ms = chrono::system_clock::now();
|
|
||||||
auto timestamp = chrono::duration_cast<chrono::milliseconds>(now_ms.time_since_epoch()).count();
|
|
||||||
auto now_time = chrono::system_clock::to_time_t(now_ms);
|
|
||||||
auto ms = timestamp % 1000;
|
|
||||||
|
|
||||||
char timeStr[100];
|
|
||||||
struct tm *tm_info = localtime(&now_time);
|
|
||||||
sprintf(timeStr, "%02d:%02d:%02d.%03ld",
|
|
||||||
tm_info->tm_hour, tm_info->tm_min, tm_info->tm_sec, ms);
|
|
||||||
|
|
||||||
// 添加提示文本
|
|
||||||
putText(frame, timeStr, Point(0, 20),
|
|
||||||
FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 255, 0), 2, LINE_8);
|
|
||||||
|
|
||||||
// FPS计算与显示
|
// FPS计算与显示
|
||||||
++count;
|
++count;
|
||||||
auto now = chrono::steady_clock::now();
|
auto now = chrono::steady_clock::now();
|
||||||
@@ -199,7 +195,7 @@ bool processFrame(VideoCapture &cap, FILE *pipe, Mat &frame, int64 &count, chron
|
|||||||
fwrite(frame.data, 1, frame.total() * frame.elemSize(), pipe);
|
fwrite(frame.data, 1, frame.total() * frame.elemSize(), pipe);
|
||||||
fflush(pipe);
|
fflush(pipe);
|
||||||
// 可选:显示窗口
|
// 可选:显示窗口
|
||||||
imshow("测试画面", frame);
|
// imshow("测试画面", frame);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -212,14 +208,14 @@ void mainLoop(VideoCapture &cap, FILE *pipe)
|
|||||||
Mat frame;
|
Mat frame;
|
||||||
cout << "开始视频处理循环..." << endl;
|
cout << "开始视频处理循环..." << endl;
|
||||||
|
|
||||||
// // 创建全屏窗口
|
// 创建全屏窗口
|
||||||
// namedWindow("处理后的画面", WINDOW_NORMAL);
|
namedWindow("处理后的画面", WINDOW_NORMAL);
|
||||||
// setWindowProperty("处理后的画面", WND_PROP_FULLSCREEN, WINDOW_FULLSCREEN);
|
setWindowProperty("处理后的画面", WND_PROP_FULLSCREEN, WINDOW_FULLSCREEN);
|
||||||
|
|
||||||
// // 获取屏幕尺寸(通过获取全屏窗口的实际大小)
|
// 获取屏幕尺寸(通过获取全屏窗口的实际大小)
|
||||||
// cv::Rect windowRect = getWindowImageRect("处理后的画面");
|
cv::Rect windowRect = getWindowImageRect("处理后的画面");
|
||||||
// int screenWidth = windowRect.width > 0 ? windowRect.width : 1920;
|
int screenWidth = windowRect.width > 0 ? windowRect.width : 1920;
|
||||||
// int screenHeight = windowRect.height > 0 ? windowRect.height : 1080;
|
int screenHeight = windowRect.height > 0 ? windowRect.height : 1080;
|
||||||
|
|
||||||
Mat displayFrame; // 用于存储缩放后的画面
|
Mat displayFrame; // 用于存储缩放后的画面
|
||||||
|
|
||||||
@@ -230,9 +226,10 @@ void mainLoop(VideoCapture &cap, FILE *pipe)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// // 将 handleFrame 缩放到全屏尺寸
|
// 将 handleFrame 缩放到全屏尺寸
|
||||||
// resize(handleFrame, displayFrame, Size(screenWidth, screenHeight));
|
resize(handleFrame, displayFrame, Size(screenWidth, screenHeight));
|
||||||
// imshow("处理后的画面", displayFrame);
|
imshow("处理后的画面", displayFrame);
|
||||||
|
|
||||||
// 检测退出键
|
// 检测退出键
|
||||||
if (cv::waitKey(1) == 'q')
|
if (cv::waitKey(1) == 'q')
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user