diff options
Diffstat (limited to 'cv/video-widget.cpp')
-rw-r--r-- | cv/video-widget.cpp | 150 |
1 files changed, 43 insertions, 107 deletions
diff --git a/cv/video-widget.cpp b/cv/video-widget.cpp index fd4fe350..7accd275 100644 --- a/cv/video-widget.cpp +++ b/cv/video-widget.cpp @@ -1,128 +1,64 @@ -/* Copyright (c) 2012 Patrick Ruoff - * Copyright (c) 2014-2016 Stanislaw Halik <sthalik@misaki.pl> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - */ - #include "video-widget.hpp" -#include "compat/check-visible.hpp" - -#include <cstring> - +#include "compat/macros.h" #include <opencv2/imgproc.hpp> -cv_video_widget::cv_video_widget(QWidget* parent) : QWidget(parent) -{ - connect(&timer, SIGNAL(timeout()), this, SLOT(update_and_repaint()), Qt::DirectConnection); - timer.start(65); -} - void cv_video_widget::update_image(const cv::Mat& frame) { - QMutexLocker l(&mtx); - - if (!freshp) - { - if (width < 1 || height < 1) - return; - - if (_frame.cols != frame.cols || _frame.rows != frame.rows) - _frame = cv::Mat(frame.rows, frame.cols, CV_8UC3); - frame.copyTo(_frame); - freshp = true; - - if (_frame2.cols != _frame.cols || _frame2.rows != _frame.rows) - _frame2 = cv::Mat(_frame.rows, _frame.cols, CV_8UC4); - - if (_frame3.cols != width || _frame3.rows != height) - _frame3 = cv::Mat(height, width, CV_8UC4); - - cv::cvtColor(_frame, _frame2, cv::COLOR_BGR2BGRA); - - const cv::Mat* img; - - if (_frame.cols != width || _frame.rows != height) - { - cv::resize(_frame2, _frame3, cv::Size(width, height), 0, 0, cv::INTER_NEAREST); - - img = &_frame3; - } - else - img = &_frame2; - - const unsigned nbytes = 4 * img->rows * img->cols; - - vec.resize(nbytes); - - std::memcpy(vec.data(), img->data, nbytes); - - texture = QImage((const unsigned char*) vec.data(), width, height, QImage::Format_ARGB32); - } -} - -void cv_video_widget::update_image(const QImage& img) -{ - QMutexLocker l(&mtx); - - if (freshp) + if (fresh()) return; - const unsigned nbytes = img.bytesPerLine() * img.height(); - - vec.resize(nbytes); - - std::memcpy(vec.data(), img.constBits(), nbytes); - - texture = QImage((const unsigned char*) vec.data(), img.width(), img.height(), img.format()); - - freshp = true; -} - -void cv_video_widget::paintEvent(QPaintEvent*) -{ - QMutexLocker foo(&mtx); - - QPainter painter(this); - - double dpr = devicePixelRatioF(); + auto [ W, H ] = preview_size(); - int W = int(QWidget::width() * dpr); - int H = int(QWidget::height() * dpr); + if (W < 1 || H < 1 || frame.rows < 1 || frame.cols < 1) + return; - painter.drawImage(rect(), texture); + cv::Mat const* __restrict scaled = nullptr; + frame3.create(H, W, frame.type()); + frame2.create(H, W, CV_8UC4); - if (texture.width() != W || texture.height() != H) + if (frame.cols != W || frame.rows != H) + { + cv::resize(frame, frame3, { W, H }, 0, 0, cv::INTER_NEAREST); + scaled = &frame3; + } + else if (!frame.isContinuous()) { - texture = QImage(W, H, QImage::Format_ARGB32); - texture.setDevicePixelRatio(dpr); + frame.copyTo(frame3); + scaled = &frame3; + } + else + scaled = &frame; - width = W, height = H; + int color_cvt = cv::COLOR_COLORCVT_MAX; - _frame = cv::Mat(); - _frame2 = cv::Mat(); - _frame3 = cv::Mat(); + 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; } -} -void cv_video_widget::update_and_repaint() -{ - if (!check_is_visible()) - return; - - QMutexLocker l(&mtx); + cv::Mat const* color; - if (freshp) + if (color_cvt != cv::COLOR_COLORCVT_MAX) { - freshp = false; - repaint(); + cv::cvtColor(*scaled, frame2, color_cvt); + color = &frame2; } -} + else + color = scaled; -void cv_video_widget::get_preview_size(int& w, int& h) -{ - QMutexLocker l(&mtx); + int width = color->cols, height = color->rows; + unsigned stride = color->step.p[0]; + set_image(color->data, width, height, stride, QImage::Format_ARGB32); - w = width, h = height; + set_fresh(true); } |