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
|
#include "video-widget.hpp"
#include <opencv2/imgproc.hpp>
void cv_video_widget::update_image(const cv::Mat& frame)
{
QMutexLocker l(&mtx);
if (freshp)
return;
if (W < 1 || H < 1 || frame.rows < 1 || frame.cols < 1)
return;
cv::Mat const* __restrict frame_scaled = nullptr;
if (frame3.cols != W || frame3.rows != H)
{
frame3 = cv::Mat(H, W, frame.type());
frame2 = cv::Mat(H, W, CV_8UC4);
if (!frame2.isContinuous() || !frame3.isContinuous())
std::abort();
}
if (frame.cols != W || frame.rows != H)
{
cv::resize(frame, frame3, { W, H }, 0, 0, cv::INTER_NEAREST);
frame_scaled = &frame3;
}
else if (!frame.isContinuous())
{
frame.copyTo(frame3);
frame_scaled = &frame3;
}
else
frame_scaled = &frame;
freshp = true;
int color_cvt = 0;
constexpr int nchannels = 4;
switch (frame_scaled->channels())
{
case 1:
color_cvt = cv::COLOR_GRAY2BGRA;
break;
case 3:
color_cvt = cv::COLOR_BGR2BGRA;
break;
case nchannels:
break;
default:
unreachable();
break;
}
cv::Mat const* frame_color;
if (color_cvt != cv::COLOR_COLORCVT_MAX)
{
cv::cvtColor(*frame_scaled, frame2, color_cvt);
frame_color = &frame2;
}
else
frame_color = frame_scaled;
int stride = frame_color->step.p[0], rows = frame_color->rows;
int nbytes = rows * stride;
vec.resize(nbytes); vec.shrink_to_fit();
std::memcpy(vec.data(), frame_color->data, nbytes);
texture = QImage((const unsigned char*) vec.data(), W, H, stride, QImage::Format_ARGB32);
texture.setDevicePixelRatio(devicePixelRatioF());
}
cv_video_widget::cv_video_widget(QWidget* parent) : video_widget(parent) {}
|