|
|
@@ -7,10 +7,12 @@ DisplayOutput::~DisplayOutput() {
|
|
|
stop();
|
|
|
}
|
|
|
|
|
|
-bool DisplayOutput::start(bool enable, int grid_cols, const string& title) {
|
|
|
+bool DisplayOutput::start(bool enable, int grid_cols, const string& title,
|
|
|
+ bool fullscreen) {
|
|
|
enable_ = enable;
|
|
|
grid_cols_ = grid_cols;
|
|
|
title_ = title;
|
|
|
+ fullscreen_ = fullscreen;
|
|
|
if (!enable_) return false;
|
|
|
if (running_.load()) return true;
|
|
|
|
|
|
@@ -43,7 +45,21 @@ void DisplayOutput::setFrame(int channel, const cv::Mat& frame,
|
|
|
void DisplayOutput::loop() {
|
|
|
int fps_counter = 0;
|
|
|
auto last_t = chrono::steady_clock::now();
|
|
|
- char fps_buf[32];
|
|
|
+ char fps_buf[32] = {0};
|
|
|
+ bool window_ready = false;
|
|
|
+
|
|
|
+ // 窗口分辨率: 全屏时跟随实际屏幕分辨率
|
|
|
+ int wnd_w = kWndW, wnd_h = kWndH;
|
|
|
+ if (fullscreen_.load()) {
|
|
|
+ cv::namedWindow(title_, cv::WINDOW_NORMAL);
|
|
|
+ // 探测当前屏幕分辨率
|
|
|
+ cv::Mat probe = cv::Mat::zeros(1, 1, CV_8UC3);
|
|
|
+ cv::imshow(title_, probe);
|
|
|
+ cv::waitKey(1);
|
|
|
+ // 无直接API读分辨率, 用全屏属性让X自动拉伸, 但画布用1920x1080保证清晰
|
|
|
+ cv::setWindowProperty(title_, cv::WND_PROP_FULLSCREEN, cv::WINDOW_FULLSCREEN);
|
|
|
+ window_ready = true;
|
|
|
+ }
|
|
|
|
|
|
while (running_.load()) {
|
|
|
auto t0 = chrono::steady_clock::now();
|
|
|
@@ -56,8 +72,8 @@ void DisplayOutput::loop() {
|
|
|
|
|
|
if (snap.empty()) {
|
|
|
// 无画面: 显示黑色占位
|
|
|
- cv::Mat black(kWndH, kWndW, CV_8UC3, cv::Scalar(10, 10, 10));
|
|
|
- cv::putText(black, "ZoneAlarm - waiting for frames...",
|
|
|
+ cv::Mat black(wnd_h, wnd_w, CV_8UC3, cv::Scalar(10, 10, 10));
|
|
|
+ cv::putText(black, title_ + " - waiting for frames...",
|
|
|
cv::Point(50, 50), cv::FONT_HERSHEY_SIMPLEX, 1.0,
|
|
|
cv::Scalar(255, 255, 255), 2);
|
|
|
cv::imshow(title_, black);
|
|
|
@@ -70,9 +86,9 @@ void DisplayOutput::loop() {
|
|
|
}
|
|
|
int rows = (n + cols - 1) / cols;
|
|
|
|
|
|
- int cell_w = kWndW / cols;
|
|
|
- int cell_h = kWndH / rows;
|
|
|
- cv::Mat canvas(kWndH, kWndW, CV_8UC3, cv::Scalar(20, 20, 20));
|
|
|
+ int cell_w = wnd_w / cols;
|
|
|
+ int cell_h = wnd_h / rows;
|
|
|
+ cv::Mat canvas(wnd_h, wnd_w, CV_8UC3, cv::Scalar(20, 20, 20));
|
|
|
|
|
|
int idx = 0;
|
|
|
for (auto& [ch, p] : snap) {
|
|
|
@@ -113,7 +129,7 @@ void DisplayOutput::loop() {
|
|
|
last_t = t1;
|
|
|
}
|
|
|
if (fps_buf[0]) {
|
|
|
- cv::putText(canvas, fps_buf, cv::Point(kWndW - 100, 30),
|
|
|
+ cv::putText(canvas, fps_buf, cv::Point(wnd_w - 100, 30),
|
|
|
cv::FONT_HERSHEY_SIMPLEX, 0.7,
|
|
|
cv::Scalar(0, 255, 0), 2);
|
|
|
}
|
|
|
@@ -121,6 +137,12 @@ void DisplayOutput::loop() {
|
|
|
cv::imshow(title_, canvas);
|
|
|
}
|
|
|
|
|
|
+ if (!window_ready) {
|
|
|
+ cv::namedWindow(title_, cv::WINDOW_NORMAL);
|
|
|
+ cv::setWindowProperty(title_, cv::WND_PROP_FULLSCREEN, cv::WINDOW_FULLSCREEN);
|
|
|
+ window_ready = true;
|
|
|
+ }
|
|
|
+
|
|
|
cv::waitKey(1);
|
|
|
|
|
|
// 目标 15 FPS 刷新
|