summaryrefslogtreecommitdiffhomepage
path: root/cv/video-widget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cv/video-widget.cpp')
-rw-r--r--cv/video-widget.cpp153
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) {}