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.cpp150
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);
}