From b42d39108afc408ded826cc6e8c0d1fe78916ddd Mon Sep 17 00:00:00 2001 From: f4exb Date: Sun, 12 Mar 2017 15:10:59 +0100 Subject: [PATCH] ATV Modulator: text overlay for still images --- plugins/channeltx/modatv/atvmod.cpp | 62 ++++++++++++++++++++++++-- plugins/channeltx/modatv/atvmod.h | 49 +++++++++++++++++++- plugins/channeltx/modatv/atvmodgui.cpp | 12 +++++ plugins/channeltx/modatv/atvmodgui.h | 3 ++ plugins/channeltx/modatv/atvmodgui.ui | 48 +++++++++++++++++++- 5 files changed, 168 insertions(+), 6 deletions(-) diff --git a/plugins/channeltx/modatv/atvmod.cpp b/plugins/channeltx/modatv/atvmod.cpp index 73e4ece88..1ae4542c5 100644 --- a/plugins/channeltx/modatv/atvmod.cpp +++ b/plugins/channeltx/modatv/atvmod.cpp @@ -31,6 +31,8 @@ MESSAGE_CLASS_DEFINITION(ATVMod::MsgReportVideoFileSourceStreamTiming, Message) MESSAGE_CLASS_DEFINITION(ATVMod::MsgReportVideoFileSourceStreamData, Message) MESSAGE_CLASS_DEFINITION(ATVMod::MsgConfigureCameraIndex, Message) MESSAGE_CLASS_DEFINITION(ATVMod::MsgReportCameraData, Message) +MESSAGE_CLASS_DEFINITION(ATVMod::MsgConfigureOverlayText, Message) +MESSAGE_CLASS_DEFINITION(ATVMod::MsgConfigureShowOverlayText, Message) const float ATVMod::m_blackLevel = 0.3f; const float ATVMod::m_spanLevel = 0.7f; @@ -50,7 +52,8 @@ ATVMod::ATVMod() : m_videoPrevFPSCount(0), m_videoEOF(false), m_videoOK(false), - m_cameraIndex(-1) + m_cameraIndex(-1), + m_showOverlayText(false) { setObjectName("ATVMod"); scanCameras(); @@ -489,6 +492,34 @@ bool ATVMod::handleMessage(const Message& cmd) getOutputMessageQueue()->push(report); } } + else if (MsgConfigureOverlayText::match(cmd)) + { + MsgConfigureOverlayText& cfg = (MsgConfigureOverlayText&) cmd; + m_overlayText = cfg.getOverlayText().toStdString(); + return true; + } + else if (MsgConfigureShowOverlayText::match(cmd)) + { + MsgConfigureShowOverlayText& cfg = (MsgConfigureShowOverlayText&) cmd; + bool showOverlayText = cfg.getShowOverlayText(); + + if (!m_imageFromFile.empty()) + { + m_imageFromFile.copyTo(m_imageOriginal); + + if (showOverlayText) { + qDebug("ATVMod::handleMessage: overlay text"); + mixImageAndText(m_imageOriginal); + } else{ + qDebug("ATVMod::handleMessage: clear text"); + } + + resizeImage(); + } + + m_showOverlayText = showOverlayText; + return true; + } else { return false; @@ -621,11 +652,17 @@ void ATVMod::applyStandard() void ATVMod::openImage(const QString& fileName) { - m_imageOriginal = cv::imread(qPrintable(fileName), CV_LOAD_IMAGE_GRAYSCALE); - m_imageOK = m_imageOriginal.data != 0; + m_imageFromFile = cv::imread(qPrintable(fileName), CV_LOAD_IMAGE_GRAYSCALE); + m_imageOK = m_imageFromFile.data != 0; if (m_imageOK) { + m_imageFromFile.copyTo(m_imageOriginal); + + if (m_showOverlayText) { + mixImageAndText(m_imageOriginal); + } + resizeImage(); } } @@ -802,3 +839,22 @@ void ATVMod::getCameraNumbers(std::vector& numbers) getOutputMessageQueue()->push(report); } } + +void ATVMod::mixImageAndText(cv::Mat& image) +{ + int fontFace = cv::FONT_HERSHEY_PLAIN; + double fontScale = image.rows / 100.0; + int thickness = 3; + int baseline=0; + + qDebug("ATVMod::mixImageAndText: fontScale: %f m_overlayText: %s", fontScale, m_overlayText.c_str()); + + cv::Size textSize = cv::getTextSize(m_overlayText, fontFace, fontScale, thickness, &baseline); + baseline += thickness; + + // position the text in the top left corner + cv::Point textOrg(2, textSize.height+4); + // then put the text itself + cv::putText(image, m_overlayText, textOrg, fontFace, fontScale, cv::Scalar::all(255*m_running.m_uniformLevel), thickness, CV_AA); +} + diff --git a/plugins/channeltx/modatv/atvmod.h b/plugins/channeltx/modatv/atvmod.h index e775667e6..87bef299f 100644 --- a/plugins/channeltx/modatv/atvmod.h +++ b/plugins/channeltx/modatv/atvmod.h @@ -256,6 +256,48 @@ public: { } }; + class MsgConfigureOverlayText : public Message + { + MESSAGE_CLASS_DECLARATION + + public: + const QString& getOverlayText() const { return m_overlayText; } + + static MsgConfigureOverlayText* create(const QString& overlayText) + { + return new MsgConfigureOverlayText(overlayText); + } + + private: + QString m_overlayText; + + MsgConfigureOverlayText(const QString& overlayText) : + Message(), + m_overlayText(overlayText) + { } + }; + + class MsgConfigureShowOverlayText : public Message + { + MESSAGE_CLASS_DECLARATION + + public: + bool getShowOverlayText() const { return m_showOverlayText; } + + static MsgConfigureShowOverlayText* create(bool showOverlayText) + { + return new MsgConfigureShowOverlayText(showOverlayText); + } + + private: + bool m_showOverlayText; + + MsgConfigureShowOverlayText(bool showOverlayText) : + Message(), + m_showOverlayText(showOverlayText) + { } + }; + ATVMod(); ~ATVMod(); @@ -452,7 +494,8 @@ private: Real m_peakLevel; Real m_levelSum; - cv::Mat m_imageOriginal; //!< original non resized image + cv::Mat m_imageFromFile; //!< original image not resized not overlaid by text + cv::Mat m_imageOriginal; //!< original not resized image cv::Mat m_image; //!< resized image for transmission at given rate bool m_imageOK; @@ -474,6 +517,9 @@ private: std::vector m_cameras; //!< vector of available cameras int m_cameraIndex; //!< curent camera index in list of available cameras + std::string m_overlayText; + bool m_showOverlayText; + static const float m_blackLevel; static const float m_spanLevel; static const int m_levelNbSamples; @@ -496,6 +542,7 @@ private: void calculateCamerasSizes(); void resizeCameras(); void resizeCamera(); + void mixImageAndText(cv::Mat& image); inline void pullImageLine(Real& sample) { diff --git a/plugins/channeltx/modatv/atvmodgui.cpp b/plugins/channeltx/modatv/atvmodgui.cpp index b128c8f2c..90279a5a0 100644 --- a/plugins/channeltx/modatv/atvmodgui.cpp +++ b/plugins/channeltx/modatv/atvmodgui.cpp @@ -324,6 +324,18 @@ void ATVModGUI::on_camSelect_currentIndexChanged(int index) m_atvMod->getInputMessageQueue()->push(message); } +void ATVModGUI::on_overlayTextShow_toggled(bool checked) +{ + ATVMod::MsgConfigureShowOverlayText* message = ATVMod::MsgConfigureShowOverlayText::create(checked); + m_atvMod->getInputMessageQueue()->push(message); +} + +void ATVModGUI::on_overlayText_textEdited(const QString& arg1) +{ + ATVMod::MsgConfigureOverlayText* message = ATVMod::MsgConfigureOverlayText::create(ui->overlayText->text()); + m_atvMod->getInputMessageQueue()->push(message); +} + void ATVModGUI::configureImageFileName() { qDebug() << "ATVModGUI::configureImageFileName: " << m_imageFileName.toStdString().c_str(); diff --git a/plugins/channeltx/modatv/atvmodgui.h b/plugins/channeltx/modatv/atvmodgui.h index bb541825c..549f8f8e0 100644 --- a/plugins/channeltx/modatv/atvmodgui.h +++ b/plugins/channeltx/modatv/atvmodgui.h @@ -77,6 +77,9 @@ private slots: void on_playCamera_toggled(bool checked); void on_camSelect_currentIndexChanged(int index); + void on_overlayTextShow_toggled(bool checked); + void on_overlayText_textEdited(const QString& arg1); + void onWidgetRolled(QWidget* widget, bool rollDown); void onMenuDoubleClicked(); diff --git a/plugins/channeltx/modatv/atvmodgui.ui b/plugins/channeltx/modatv/atvmodgui.ui index 754e84e6f..bcabbcdea 100644 --- a/plugins/channeltx/modatv/atvmodgui.ui +++ b/plugins/channeltx/modatv/atvmodgui.ui @@ -6,7 +6,7 @@ 0 0 - 386 + 491 364 @@ -39,7 +39,7 @@ 10 10 - 360 + 461 341 @@ -421,6 +421,50 @@ + + + + + 24 + 24 + + + + Activate text overlay + + + T + + + + + + + + 110 + 0 + + + + + 110 + 16777215 + + + + Text overlay + + + + + + 12 + + + 0 + + +