-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpreview_worker.cpp
More file actions
103 lines (87 loc) · 3.03 KB
/
preview_worker.cpp
File metadata and controls
103 lines (87 loc) · 3.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
//
// Created by peng on 2026/1/6.
//
#include "preview_worker.hpp"
#include <QDebug>
#include <QPixmap>
#include <opencv2/imgproc.hpp>
PreviewWorker::PreviewWorker(const uint16_t width, const uint16_t height, const size_t bufferSize, QObject* parent)
: QObject{parent} {
_width = width;
_height = height;
_ringBuffer.capacity = bufferSize;
_ringBuffer.frames.reserve(bufferSize);
}
PreviewWorker::~PreviewWorker() = default;
void PreviewWorker::frameReceived(const cv::Mat& frame) {
if (frame.empty() || !frame.data)
return;
QMutexLocker lock(&_mutex);
// 环形缓冲区写入逻辑
if (_ringBuffer.frames.size() < _ringBuffer.capacity) {
// 初始化阶段:直接添加
_ringBuffer.frames.push_back(frame.clone());
} else {
// 正常运行:覆盖最旧帧
_ringBuffer.frames[_ringBuffer.writeIndex] = frame.clone();
}
_ringBuffer.writeIndex = (_ringBuffer.writeIndex + 1) % _ringBuffer.capacity;
if (_ringBuffer.count < _ringBuffer.capacity) {
++_ringBuffer.count;
}
// 触发处理(如果未在处理中)
if (!_isProcessing && _ringBuffer.count > 0) {
_isProcessing = true;
lock.unlock(); // 先解锁再emit,避免死锁
handleFrame();
}
}
void PreviewWorker::handleFrame() {
cv::Mat frame;
{
QMutexLocker lock(&_mutex);
if (_ringBuffer.count == 0) {
_isProcessing = false;
return;
}
frame = _ringBuffer.frames[_ringBuffer.readIndex];
_ringBuffer.readIndex = (_ringBuffer.readIndex + 1) % _ringBuffer.capacity;
--_ringBuffer.count;
}
{
cv::Mat resizedFrame;
try {
cv::resize(frame, resizedFrame, cv::Size(640, 360), 0, 0,
cv::INTER_LINEAR);
} catch (...) {
qWarning() << "Error during resize in PreviewWorker";
return; // 发生错误则退出
}
if (resizedFrame.empty()) {
qWarning() << "Resized frame is empty!";
return;
}
QImage qimg;
if (resizedFrame.channels() == 3) {
// OpenCV 是 BGR, Qt 是 RGB
cv::cvtColor(resizedFrame, resizedFrame, cv::COLOR_BGR2RGB);
qimg = QImage(resizedFrame.data, resizedFrame.cols, resizedFrame.rows,
resizedFrame.step, QImage::Format_RGB888);
} else if (resizedFrame.channels() == 1) {
qimg = QImage(resizedFrame.data, resizedFrame.cols, resizedFrame.rows,
resizedFrame.step,
QImage::Format_Grayscale8);
} else {
qWarning() << "Unsupported Mat format for preview.";
return;
}
if (qimg.isNull()) {
qWarning() << "QImage conversion failed!";
return;
}
// 发射信号,传递给主线程显示,复制 QImage 数据,确保线程安全
emit onPreviewReady(qimg.copy());
}
// 继续处理下一帧
handleFrame();
}