summaryrefslogtreecommitdiffhomepage
path: root/cv/video-widget.cpp
blob: ea5e13acafe6254c098f840fe4a89b4e96660547 (plain)
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
#include "video-widget.hpp"

#include <opencv2/imgproc.hpp>

void cv_video_widget::update_image(const cv::Mat& frame)
{
    if (fresh())
        return;

    auto [ W, H ] = preview_size();

    if (W < 1 || H < 1 || frame.rows < 1 || frame.cols < 1)
        return;

    cv::Mat const* __restrict scaled = nullptr;
    frame3.create(H, W, frame.type());
    frame2.create(H, W, CV_8UC4);

    if (frame.cols != W || frame.rows != H)
    {
        cv::resize(frame, frame3, { W, H }, 0, 0, cv::INTER_NEAREST);
        scaled = &frame3;
    }
    else if (!frame.isContinuous())
    {
        frame.copyTo(frame3);
        scaled = &frame3;
    }
    else
        scaled = &frame;

    int color_cvt = cv::COLOR_COLORCVT_MAX;

    switch (scaled->channels())
    {
    case 1:
        color_cvt = cv::COLOR_GRAY2BGRA;
        break;
    case 3:
        color_cvt = cv::COLOR_BGR2BGRA;
        break;
    case 4:
        break;
    default:
        unreachable();
        break;
    }

    cv::Mat const* color;

    if (color_cvt != cv::COLOR_COLORCVT_MAX)
    {
        cv::cvtColor(*scaled, frame2, color_cvt);
        color = &frame2;
    }
    else
        color = scaled;

    int width = color->cols, height = color->rows;
    unsigned stride = color->step.p[0];
    set_image(color->data, width, height, stride, QImage::Format_ARGB32);

    set_fresh(true);
}