diff --git a/plugins/channeltx/modatv/atvmod.cpp b/plugins/channeltx/modatv/atvmod.cpp index 75e8847d4..7219b4c77 100644 --- a/plugins/channeltx/modatv/atvmod.cpp +++ b/plugins/channeltx/modatv/atvmod.cpp @@ -16,6 +16,8 @@ #include +#include "opencv2/imgproc/imgproc.hpp" + #include "dsp/upchannelizer.h" #include "atvmod.h" @@ -25,6 +27,7 @@ MESSAGE_CLASS_DEFINITION(ATVMod::MsgConfigureImageFileName, Message) const float ATVMod::m_blackLevel = 0.3f; const float ATVMod::m_spanLevel = 0.7f; const int ATVMod::m_levelNbSamples = 10000; // every 10ms +const int ATVMod::m_nbBars = 6; ATVMod::ATVMod() : m_modPhasor(0.0f), @@ -32,7 +35,8 @@ ATVMod::ATVMod() : m_tvSampleRate(1000000), m_settingsMutex(QMutex::Recursive), m_horizontalCount(0), - m_lineCount(0) + m_lineCount(0), + m_imageOK(false) { setObjectName("ATVMod"); @@ -319,7 +323,7 @@ void ATVMod::applyStandard() switch(m_config.m_atvStd) { - case ATVStdPAL525: + case ATVStdPAL525: // Follows PAL-M standard m_pointsPerSync = (uint32_t) roundf(4.7f * m_pointsPerTU); // normal sync pulse (4.7/1.008 us) m_pointsPerBP = (uint32_t) roundf(4.7f * m_pointsPerTU); // back porch (4.7/1.008 us) m_pointsPerFP = (uint32_t) roundf(1.5f * m_pointsPerTU); // front porch (1.5/1.008 us) @@ -329,16 +333,16 @@ void ATVMod::applyStandard() m_nbLines = 525; m_nbLines2 = 262; m_nbImageLines = 510; - m_nbImageLines2 = 205; + m_nbImageLines2 = 255; m_interlaced = true; m_nbHorizPoints = 64 * m_pointsPerTU; // full line - m_nbBlankLines = 16; - m_pointsPerHBar = m_pointsPerImgLine / 6; - m_linesPerVBar = m_nbImageLines2 / 6; - m_hBarIncrement = m_spanLevel / 6.0f; - m_vBarIncrement = m_spanLevel / 6.0f; + m_nbBlankLines = 15; // yields 480 lines (255 - 15) * 2 + m_pointsPerHBar = m_pointsPerImgLine / m_nbBars; + m_linesPerVBar = m_nbImageLines2 / m_nbBars; + m_hBarIncrement = m_spanLevel / (float) m_nbBars; + m_vBarIncrement = m_spanLevel / (float) m_nbBars; break; - case ATVStdPAL625: + case ATVStdPAL625: // Follows PAL-B/G/H standard default: m_pointsPerSync = (uint32_t) roundf(4.7f * m_pointsPerTU); // normal sync pulse (4.7 us) m_pointsPerBP = (uint32_t) roundf(4.7f * m_pointsPerTU); // back porch (4.7 us) @@ -352,10 +356,25 @@ void ATVMod::applyStandard() m_nbImageLines2 = 305; m_interlaced = true; m_nbHorizPoints = 64 * m_pointsPerTU; // full line - m_nbBlankLines = 16; - m_pointsPerHBar = m_pointsPerImgLine / 6; - m_linesPerVBar = m_nbImageLines2 / 6; - m_hBarIncrement = m_spanLevel / 6.0f; - m_vBarIncrement = m_spanLevel / 6.0f; + m_nbBlankLines = 17; // yields 576 lines (305 - 17) * 2 + m_pointsPerHBar = m_pointsPerImgLine / m_nbBars; + m_linesPerVBar = m_nbImageLines2 / m_nbBars; + m_hBarIncrement = m_spanLevel / (float) m_nbBars; + m_vBarIncrement = m_spanLevel / (float) m_nbBars; } } + +void ATVMod::openImage(QString& fileName) +{ + cv::Mat tmpImage = cv::imread(qPrintable(fileName), CV_LOAD_IMAGE_GRAYSCALE); + m_imageOK = tmpImage.data != 0; + + if (m_imageOK) + { + float fy = (m_nbImageLines - 2*m_nbBlankLines) / (float) tmpImage.rows; + float fx = m_pointsPerImgLine / (float) tmpImage.cols; + cv::resize(tmpImage, m_image, cv::Size(), fx, fy); + qDebug("ATVMod::openImage: %d x %d -> %d x %d", tmpImage.cols, tmpImage.rows, m_image.cols, m_image.rows); + // later: image.at(49,39); + } +} diff --git a/plugins/channeltx/modatv/atvmod.h b/plugins/channeltx/modatv/atvmod.h index 8eb512276..52c554d82 100644 --- a/plugins/channeltx/modatv/atvmod.h +++ b/plugins/channeltx/modatv/atvmod.h @@ -46,7 +46,7 @@ public: ATVModInputUniform, ATVModInputHBars, ATVModInputVBars, - ATVModInputCheckbox, + ATVModInputChessboard, ATVModInputHGradient, ATVModInputVGradient, ATVModInputImage, @@ -194,15 +194,15 @@ private: uint32_t m_linesPerVBar; //!< number of lines for a bar of the bar chart uint32_t m_pointsPerTU; //!< number of line points per time unit uint32_t m_nbLines; //!< number of lines per complete frame - uint32_t m_nbLines2; - uint32_t m_nbImageLines; - uint32_t m_nbImageLines2; + uint32_t m_nbLines2; //!< same number as above (non interlaced) or half the number above (interlaced) + uint32_t m_nbImageLines; //!< number of image lines excluding synchronization lines + uint32_t m_nbImageLines2; //!< same number as above (non interlaced) or half the number above (interlaced) uint32_t m_nbHorizPoints; //!< number of line points per horizontal line - uint32_t m_nbBlankLines; - float m_hBarIncrement; - float m_vBarIncrement; + uint32_t m_nbBlankLines; //!< number of lines in a frame (full or half) that are blanked (black) at the top of the image + float m_hBarIncrement; //!< video level increment at each horizontal bar increment + float m_vBarIncrement; //!< video level increment at each vertical bar increment bool m_interlaced; //!< true if image is interlaced (2 half frames per frame) - bool m_evenImage; + bool m_evenImage; //!< in interlaced mode true if this is an even image QMutex m_settingsMutex; int m_horizontalCount; //!< current point index on line int m_lineCount; //!< current line index in frame @@ -213,10 +213,12 @@ private: Real m_levelSum; cv::Mat m_image; + bool m_imageOK; static const float m_blackLevel; static const float m_spanLevel; static const int m_levelNbSamples; + static const int m_nbBars; // number of bars in bar or chessboard patterns void apply(bool force = false); void pullFinalize(Complex& ci, Sample& sample); @@ -224,6 +226,7 @@ private: void calculateLevel(Real& sample); void modulateSample(); void applyStandard(); + void openImage(QString& fileName); inline void pullImageLine(Real& sample) { @@ -248,7 +251,7 @@ private: case ATVModInputVBars: sample = (iLine / m_linesPerVBar) * m_vBarIncrement + m_blackLevel; break; - case ATVModInputCheckbox: + case ATVModInputChessboard: sample = (((iLine / m_linesPerVBar)*5 + (pointIndex / m_pointsPerHBar)) % 2) * m_spanLevel * m_running.m_uniformLevel + m_blackLevel; break; @@ -258,6 +261,7 @@ private: case ATVModInputVGradient: sample = ((iLine -5) / (float) m_nbImageLines2) * m_spanLevel + m_blackLevel; break; + case ATVModInputImage: case ATVModInputUniform: default: sample = m_spanLevel * m_running.m_uniformLevel + m_blackLevel; diff --git a/plugins/channeltx/modatv/atvmodgui.ui b/plugins/channeltx/modatv/atvmodgui.ui index 643b2274e..1f0dc18db 100644 --- a/plugins/channeltx/modatv/atvmodgui.ui +++ b/plugins/channeltx/modatv/atvmodgui.ui @@ -372,7 +372,7 @@ - Chekbd + Chess diff --git a/plugins/channeltx/modatv/modatv.pro b/plugins/channeltx/modatv/modatv.pro index 287281965..f80347cb3 100644 --- a/plugins/channeltx/modatv/modatv.pro +++ b/plugins/channeltx/modatv/modatv.pro @@ -37,7 +37,7 @@ FORMS += atvmodgui.ui LIBS += -L../../../sdrbase/$${build_subdir} -lsdrbase -CONFIG(MINGW32):LIBS += -LD:\softs\opencv\build\mw32\install\x86\mingw\bin -llibopencv_core2413 -llibopencv_highgui2413 -CONFIG(MINGW64):LIBS += -LD:\softs\opencv\build\mw64\install\x64\mingw\bin -llibopencv_core2413 -llibopencv_highgui2413 +CONFIG(MINGW32):LIBS += -LD:\softs\opencv\build\mw32\install\x86\mingw\bin -llibopencv_core2413 -llibopencv_highgui2413 -llibopencv_imgproc2413 +CONFIG(MINGW64):LIBS += -LD:\softs\opencv\build\mw64\install\x64\mingw\bin -llibopencv_core2413 -llibopencv_highgui2413 -llibopencv_imgproc2413 RESOURCES = ../../../sdrbase/resources/res.qrc