diff --git a/app/ModulesHandle.cpp b/app/ModulesHandle.cpp index f2b8a99..d3aaf63 100644 --- a/app/ModulesHandle.cpp +++ b/app/ModulesHandle.cpp @@ -279,10 +279,17 @@ Void ModulesHandle::activateModule() Int numberOfFrames = pcCurrAppModuleIf->m_pcModule->m_uiNumberOfFrames; if( numberOfFrames > MODULE_REQUIRES_ONE_FRAME ) // Show dialog to select sub windows { - DialogSubWindowSelector dialogWindowsSelection( m_pcParent, m_pcMainWindowManager, SubWindowAbstract::VIDEO_SUBWINDOW, numberOfFrames, numberOfFrames ); + Int minNumFrames = numberOfFrames; + Int maxNumFrames = numberOfFrames; + if( numberOfFrames == MODULE_REQUIRES_SEVERAL_FRAMES ) + { + minNumFrames = 0; + maxNumFrames = 255; + } + DialogSubWindowSelector dialogWindowsSelection( m_pcParent, m_pcMainWindowManager, SubWindowAbstract::VIDEO_SUBWINDOW, minNumFrames, maxNumFrames ); QList windowsList = m_pcMainWindowManager->findSubWindow( SubWindowAbstract::VIDEO_SUBWINDOW ); - if( windowsList.size() <= numberOfFrames ) + if( windowsList.size() == minNumFrames && windowsList.size() == maxNumFrames ) { for( Int i = 0; i < windowsList.size(); i++ ) { @@ -291,7 +298,7 @@ Void ModulesHandle::activateModule() } else { - if( windowsList.size() <= numberOfFrames ) + if( windowsList.size() <= minNumFrames ) { for( Int i = 0; i < windowsList.size(); i++ ) { @@ -400,7 +407,7 @@ Void ModulesHandle::activateModule() { if( pcCurrAppModuleIf->m_pcDisplaySubWindow ) pcCurrAppModuleIf->m_pcDisplaySubWindow->enableModule( pcCurrAppModuleIf ); - for( Int i = 0; i < numberOfFrames; i++ ) + for( Int i = 0; i < videoSubWindowList.size(); i++ ) { pcCurrAppModuleIf->m_pcSubWindow[i]->associateModule( pcCurrAppModuleIf ); } @@ -411,7 +418,7 @@ Void ModulesHandle::activateModule() if( pcCurrAppModuleIf->m_pcModule->m_iModuleAPI == MODULE_API_2 ) { std::vector apcFrameList; - for( UInt i = 0; i < pcCurrAppModuleIf->m_pcModule->m_uiNumberOfFrames; i++ ) + for( UInt i = 0; i < videoSubWindowList.size(); i++ ) { apcFrameList.push_back( pcCurrAppModuleIf->m_pcSubWindow[i]->getCurrFrame() ); } diff --git a/app/PlaYUVerAppModuleIf.cpp b/app/PlaYUVerAppModuleIf.cpp index 6998717..fb4d85e 100644 --- a/app/PlaYUVerAppModuleIf.cpp +++ b/app/PlaYUVerAppModuleIf.cpp @@ -38,7 +38,7 @@ PlaYUVerAppModuleIf::PlaYUVerAppModuleIf( QObject* parent, QAction* action, PlaY m_dMeasurementResult( 0 ) { setParent( parent ); - for( Int i = 0; i < MAX_NUMBER_FRAMES; i++ ) + for( Int i = 0; i < MODULE_REQUIRES_MAX_NUM_FRAMES; i++ ) { m_pcSubWindow[i] = NULL; } @@ -194,7 +194,7 @@ Void PlaYUVerAppModuleIf::destroy() m_pcDisplaySubWindow->closeSubWindow(); m_pcDisplaySubWindow = NULL; - for( Int i = 0; i < MAX_NUMBER_FRAMES; i++ ) + for( Int i = 0; i < MODULE_REQUIRES_MAX_NUM_FRAMES; i++ ) { if( m_pcSubWindow[i] ) { diff --git a/app/PlaYUVerAppModuleIf.h b/app/PlaYUVerAppModuleIf.h index 36b1980..7536f18 100644 --- a/app/PlaYUVerAppModuleIf.h +++ b/app/PlaYUVerAppModuleIf.h @@ -60,7 +60,7 @@ private: QAction* m_pcModuleAction; PlaYUVerModuleIf* m_pcModule; - VideoSubWindow* m_pcSubWindow[MAX_NUMBER_FRAMES]; + VideoSubWindow* m_pcSubWindow[MODULE_REQUIRES_MAX_NUM_FRAMES]; VideoSubWindow* m_pcDisplaySubWindow; @@ -93,7 +93,7 @@ public: QList getSubWindowList() { QList arraySubWindows; - for( Int i = 0; i < MAX_NUMBER_FRAMES; i++ ) + for( Int i = 0; i < MODULE_REQUIRES_MAX_NUM_FRAMES; i++ ) if( m_pcSubWindow[i] ) arraySubWindows.append( m_pcSubWindow[i] ); return arraySubWindows; diff --git a/lib/PlaYUVerModuleIf.h b/lib/PlaYUVerModuleIf.h index 725054c..fa73c46 100644 --- a/lib/PlaYUVerModuleIf.h +++ b/lib/PlaYUVerModuleIf.h @@ -76,8 +76,6 @@ enum Module_Type FRAME_MEASUREMENT_MODULE, }; -#define MAX_NUMBER_FRAMES 3 - /** Module_NumberOfFrames Enum * \ingroup PlaYUVerLib_Modules * Number of frames requires by a module @@ -88,7 +86,11 @@ enum Module_NumberOfFrames MODULE_REQUIRES_ONE_FRAME = 1, MODULE_REQUIRES_TWO_FRAMES, MODULE_REQUIRES_THREE_FRAMES, - MODULE_REQUIRES_MAX_FRAMES = 255, + MODULE_REQUIRES_FOUR_FRAMES, + MODULE_REQUIRES_FIVE_FRAMES, + MODULE_REQUIRES_SIX_FRAMES, + MODULE_REQUIRES_SEVERAL_FRAMES = 255, + MODULE_REQUIRES_MAX_NUM_FRAMES, }; /** Module_Features Enum diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 98c4108..fc9ba38 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -19,6 +19,7 @@ ADD_MODULE( FilterComponentChromaV "FilterComponent" ) ADD_MODULE( FrameDifference "FrameDifference" ) ADD_MODULE( FrameMask "FrameMask" ) ADD_MODULE( AbsoluteFrameDifference "AbsoluteFrameDifference" ) +ADD_MODULE( InterFrameVariance "InterFrameVariance" ) ADD_MODULE( FrameBinarization "FrameBinarization" ) ADD_MODULE( FrameShift "FrameShift" ) ADD_MODULE( SetChromaHalfScale "SetChromaHalfScale" ) diff --git a/modules/InterFrameVariance.cpp b/modules/InterFrameVariance.cpp new file mode 100644 index 0000000..2abb77c --- /dev/null +++ b/modules/InterFrameVariance.cpp @@ -0,0 +1,111 @@ +/* This file is a part of plaYUVer project + * Copyright (C) 2014-2016 by Luis Lucas (luisfrlucas@gmail.com) + * Joao Carreira (jfmcarreira@gmail.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/** + * \file InterFrameVariance.cpp + * \brief Variance across several frames + */ + +#include "InterFrameVariance.h" +#include "lib/LibMemory.h" + +InterFrameVariance::InterFrameVariance() +{ + /* Module Definition */ + m_iModuleAPI = MODULE_API_2; // Use API version 2 (recommended). + // See this example for details on the functions prototype + m_iModuleType = FRAME_PROCESSING_MODULE; // Apply module to the frames or to the whole sequence. + m_pchModuleCategory = "Measurements"; // Category (sub-menu) + m_pchModuleName = "InterFrameVariance"; // Name + m_pchModuleTooltip = "Measure the variance across several frames"; + m_uiNumberOfFrames = MODULE_REQUIRES_SEVERAL_FRAMES; // Number of Frames required (This module allows a variable number of inputs) + m_uiModuleRequirements = MODULE_REQUIRES_NEW_WINDOW; // Module requirements (check PlaYUVerModulesIf.h). + // Several requirements should be "or" between each others. + m_pcFrameVariance = NULL; + +} + +Bool InterFrameVariance::create( std::vector apcFrameList ) +{ + m_uiNumberOfFrames = Module_NumberOfFrames( apcFrameList.size() ); + + _BASIC_MODULE_API_2_CHECK_ + + for( UInt i = 1; i < apcFrameList.size(); i++ ) + if( !apcFrameList[i]->haveSameFmt( apcFrameList[0], PlaYUVerFrame::MATCH_COLOR_SPACE | PlaYUVerFrame::MATCH_RESOLUTION | PlaYUVerFrame::MATCH_BITS ) ) + return false; + + m_pcFrameVariance = new PlaYUVerFrame( apcFrameList[0]->getWidth(), apcFrameList[0]->getHeight(), PlaYUVerFrame::GRAY, 8 ); + getMem2D( &m_pVariance, apcFrameList[0]->getHeight(), apcFrameList[0]->getWidth() ); + + return true; +} + +PlaYUVerFrame* InterFrameVariance::process( std::vector apcFrameList ) +{ + Int numFrames = apcFrameList.size(); + + Pel* pInput[numFrames]; + Pel* pOutputPelYUV = m_pcFrameVariance->getPelBufferYUV()[0][0]; + + for( Int i = 0; i < numFrames; i++ ) + { + pInput[i] = apcFrameList[i]->getPelBufferYUV()[0][0]; + } + + Double maxVariance = 0; + for( UInt y = 0; y < m_pcFrameVariance->getHeight(); y++ ) + for( UInt x = 0; x < m_pcFrameVariance->getWidth(); x++ ) + { + Int sum = 0; + Int v = 0; + m_pVariance[y][x] = 0; + + for( Int i = 0; i < numFrames; i++ ) + { + v = *pInput[i]++; + sum += v; + m_pVariance[y][x] += v * v; + + } + //Final result of the variance for one block + m_pVariance[y][x] -= Double( sum * sum ) / Double( numFrames ); + m_pVariance[y][x] /= Double( numFrames ); + if( m_pVariance[y][x] > maxVariance ) + maxVariance = m_pVariance[y][x]; + } + + for( UInt y = 0; y < m_pcFrameVariance->getHeight(); y++ ) + for( UInt x = 0; x < m_pcFrameVariance->getWidth(); x++ ) + { + *pOutputPelYUV++ = m_pVariance[y][x] * 255 / maxVariance; + } + return m_pcFrameVariance; +} + +Void InterFrameVariance::destroy() +{ + if( m_pVariance ) + freeMem2D( m_pVariance ); + m_pVariance = NULL; + if( m_pcFrameVariance ) + delete m_pcFrameVariance; + m_pcFrameVariance = NULL; +} + diff --git a/modules/InterFrameVariance.h b/modules/InterFrameVariance.h new file mode 100644 index 0000000..2ae8fab --- /dev/null +++ b/modules/InterFrameVariance.h @@ -0,0 +1,51 @@ +/* This file is a part of plaYUVer project + * Copyright (C) 2014-2016 by Luis Lucas (luisfrlucas@gmail.com) + * Joao Carreira (jfmcarreira@gmail.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/** + * \file InterFrameVariance.h + * \brief Absolute Frame Difference module + */ + +#ifndef __INTERFRAMEVARIANCE_H__ +#define __INTERFRAMEVARIANCE_H__ + +// PlaYUVerLib +#include "lib/PlaYUVerModuleIf.h" + + +class InterFrameVariance: public PlaYUVerModuleIf +{ + REGISTER_CLASS_FACTORY( InterFrameVariance ) + +private: + PlaYUVerFrame* m_pcFrameVariance; + Double** m_pVariance; +public: + InterFrameVariance(); + virtual ~InterFrameVariance() + { + } + Bool create( std::vector apcFrameList ); + PlaYUVerFrame* process( std::vector apcFrameList ); + Void destroy(); + +}; + +#endif // __INTERFRAMEVARIANCE_H__ +