ATV Modulator: text overlay for still images

This commit is contained in:
f4exb 2017-03-12 15:10:59 +01:00
parent e24c7bcf2c
commit b42d39108a
5 changed files with 168 additions and 6 deletions

View File

@ -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<int>& 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);
}

View File

@ -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<ATVCamera> 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)
{

View File

@ -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();

View File

@ -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();

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>386</width>
<width>491</width>
<height>364</height>
</rect>
</property>
@ -39,7 +39,7 @@
<rect>
<x>10</x>
<y>10</y>
<width>360</width>
<width>461</width>
<height>341</height>
</rect>
</property>
@ -421,6 +421,50 @@
</property>
</widget>
</item>
<item>
<widget class="ButtonSwitch" name="overlayTextShow">
<property name="minimumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>Activate text overlay</string>
</property>
<property name="text">
<string>T</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="overlayText">
<property name="minimumSize">
<size>
<width>110</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>110</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Text overlay</string>
</property>
<property name="text">
<string/>
</property>
<property name="maxLength">
<number>12</number>
</property>
<property name="cursorPosition">
<number>0</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">