diff options
Diffstat (limited to 'cv/video-widget.cpp')
-rw-r--r-- | cv/video-widget.cpp | 153 |
1 files changed, 51 insertions, 102 deletions
diff --git a/cv/video-widget.cpp b/cv/video-widget.cpp index d93429cb..7cc6ca2d 100644 --- a/cv/video-widget.cpp +++ b/cv/video-widget.cpp @@ -1,129 +1,78 @@ -/* 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 "compat/math.hpp" - -#include <cstring> #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) 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()); + if (W < 1 || H < 1 || frame.rows < 1 || frame.cols < 1) + return; - freshp = true; -} + cv::Mat const* __restrict frame_scaled = nullptr; -void cv_video_widget::paintEvent(QPaintEvent*) -{ - QMutexLocker foo(&mtx); + if (frame3.cols != W || frame3.rows != H) + { + frame3 = cv::Mat(H, W, frame.type()); + frame2 = cv::Mat(H, W, CV_8UC4); - QPainter painter(this); + if (!frame2.isContinuous() || !frame3.isContinuous()) + std::abort(); + } - double dpr = devicePixelRatioF(); + 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; - int W = iround(QWidget::width() * dpr); - int H = iround(QWidget::height() * dpr); + freshp = true; - painter.drawImage(rect(), texture); + int color_cvt = 0; + constexpr int nchannels = 4; - if (texture.width() != W || texture.height() != H) + switch (frame_scaled->channels()) { - texture = QImage(W, H, QImage::Format_ARGB32); - texture.setDevicePixelRatio(dpr); - - width = W, height = H; - - _frame = cv::Mat(); - _frame2 = cv::Mat(); - _frame3 = cv::Mat(); + case 1: + color_cvt = cv::COLOR_GRAY2BGRA; + break; + case 3: + color_cvt = cv::COLOR_BGR2BGRA; + break; + case nchannels: + break; + default: + unreachable(); + break; } -} - -void cv_video_widget::update_and_repaint() -{ - if (!check_is_visible()) - return; - QMutexLocker l(&mtx); + cv::Mat const* frame_color; - if (freshp) + if (color_cvt != cv::COLOR_COLORCVT_MAX) { - freshp = false; - repaint(); + cv::cvtColor(*frame_scaled, frame2, color_cvt); + frame_color = &frame2; } -} + else + frame_color = frame_scaled; -void cv_video_widget::get_preview_size(int& w, int& h) -{ - QMutexLocker l(&mtx); + 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); - w = width, h = height; + 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) {} |