Add PlaYUVerFrameStats in order to calculate frame stats. This is meant to replace the existing class
This commit is contained in:
1 parent
34b4fe7439
commit
bec150f705
5 files changed
+555
-3
No files matched your search
@@ -8,6 +8,7 @@ set(plaYUver_Lib_SRCS
|
||||
# Frame
|
||||
PlaYUVerFrame.cpp
|
||||
PlaYUVerFramePixelFormats.cpp
|
||||
PlaYUVerFrameStats.cpp
|
||||
# Stream
|
||||
PlaYUVerStream.cpp
|
||||
)
|
||||
|
||||
@@ -110,6 +110,7 @@ Void PlaYUVerFrame::init( UInt width, UInt height, Int pel_format )
|
||||
}
|
||||
getMem1D( &m_pcRGB32, m_uiHeight * m_uiWidth * 4 );
|
||||
|
||||
xSetupStatistics( this );
|
||||
openPixfc();
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -25,18 +25,19 @@
|
||||
#ifndef __PLAYUVERFRAME_H__
|
||||
#define __PLAYUVERFRAME_H__
|
||||
|
||||
#include "PlaYUVerDefs.h"
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include <QtCore>
|
||||
#include "PlaYUVerDefs.h"
|
||||
#include "PlaYUVerFrameStats.h"
|
||||
|
||||
class PixFcSSE;
|
||||
|
||||
namespace plaYUVer
|
||||
{
|
||||
|
||||
class PlaYUVerFrame
|
||||
class PlaYUVerFrame : public PlaYUVerFrameStats
|
||||
{
|
||||
public:
|
||||
class Pixel
|
||||
@@ -131,7 +132,6 @@ public:
|
||||
{
|
||||
return m_iPixelFormat;
|
||||
}
|
||||
|
||||
Int getBitsChannel() const
|
||||
{
|
||||
return m_iBitsChannels;
|
||||
@@ -157,6 +157,7 @@ public:
|
||||
}
|
||||
Pel*** getPelBufferYUV()
|
||||
{
|
||||
m_bHasHistogram = false;
|
||||
m_bHasRGBPel = false;
|
||||
return m_pppcInputPel;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,429 @@
|
||||
/* This file is a part of plaYUVer project
|
||||
* Copyright (C) 2014 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 PlaYUVerFrameStats.cpp
|
||||
* \brief Measure PlaYUVerFrame statistics
|
||||
* Based on the work of Ricardo N. Rocha Sardo in SCode project
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
#include "PlaYUVerFrameStats.h"
|
||||
#include "PlaYUVerFrame.h"
|
||||
#include "LibMemory.h"
|
||||
|
||||
namespace plaYUVer
|
||||
{
|
||||
|
||||
PlaYUVerFrameStats::PlaYUVerFrameStats() :
|
||||
m_pdHistogram( NULL ),
|
||||
m_bHasHistogram( false )
|
||||
{
|
||||
}
|
||||
|
||||
PlaYUVerFrameStats::~PlaYUVerFrameStats()
|
||||
{
|
||||
if( m_pdHistogram )
|
||||
delete[] m_pdHistogram;
|
||||
|
||||
}
|
||||
|
||||
// statistics
|
||||
Void PlaYUVerFrameStats::xSetupStatistics( const PlaYUVerFrame *pcFrame, UInt options )
|
||||
{
|
||||
m_pppImageData = pcFrame->getPelBufferYUV();
|
||||
m_uiImageWidth = pcFrame->getWidth();
|
||||
m_uiImageHeight = pcFrame->getHeight();
|
||||
m_uiChannels = pcFrame->getNumberChannels();
|
||||
|
||||
m_uiHistoSegments = ( pcFrame->getBitsChannel() == 16 ) ? 65536 : 256;
|
||||
imageColorSpace = pcFrame->getColorSpace();
|
||||
imageChromaSize = pcFrame->getChromaLength();
|
||||
|
||||
if( options == CalcLumaWhenRGB )
|
||||
calcLuma = true;
|
||||
else
|
||||
calcLuma = false;
|
||||
|
||||
if( calcLuma && ( imageColorSpace == PlaYUVerFrame::COLOR_RGB ) )
|
||||
histoChannels = m_uiChannels + 1;
|
||||
else
|
||||
histoChannels = m_uiChannels;
|
||||
}
|
||||
|
||||
Void PlaYUVerFrameStats::calcHistogram()
|
||||
{
|
||||
m_bHasHistogram = false;
|
||||
getMem1D<Double>( &( m_pdHistogram ), m_uiHistoSegments * histoChannels );
|
||||
|
||||
if( !m_pdHistogram )
|
||||
{
|
||||
qWarning( ) << "PlaYUVerFrameStats::calcHistogramValuess: "
|
||||
"Unable to allocate memory!"
|
||||
<< endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
UInt i, j;
|
||||
|
||||
if( imageColorSpace == PlaYUVerFrame::COLOR_YUV )
|
||||
{
|
||||
const Pel *data[3];
|
||||
data[LUMA] = m_pppImageData[LUMA][0];
|
||||
data[CHROMA_U] = m_pppImageData[CHROMA_U][0];
|
||||
data[CHROMA_V] = m_pppImageData[CHROMA_V][0];
|
||||
for( i = 0; i < m_uiImageHeight * m_uiImageWidth; i++ )
|
||||
{
|
||||
m_pdHistogram[*( data[LUMA] ) + LUMA * m_uiHistoSegments]++;
|
||||
data[LUMA] += 1;
|
||||
}
|
||||
for( i = 0; ( i < imageChromaSize ) && runningFlag; i++ )
|
||||
{
|
||||
for( j = 1; j < m_uiChannels; j++ )
|
||||
{
|
||||
m_pdHistogram[*( data[j] ) + j * m_uiHistoSegments]++;
|
||||
}
|
||||
for( j = 1; j < m_uiChannels; j++ )
|
||||
data[j] += 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const Pel* data[3];
|
||||
Pel luma;
|
||||
data[COLOR_R] = m_pppImageData[COLOR_R][0];
|
||||
data[COLOR_G] = m_pppImageData[COLOR_G][0];
|
||||
data[COLOR_B] = m_pppImageData[COLOR_B][0];
|
||||
|
||||
for( i = 0; ( i < m_uiImageHeight * m_uiImageWidth ) && runningFlag; i++ )
|
||||
{
|
||||
for( j = 0; j < m_uiChannels; j++ )
|
||||
{
|
||||
m_pdHistogram[*( data[j] ) + j * m_uiHistoSegments]++;
|
||||
}
|
||||
if( calcLuma && ( imageColorSpace == PlaYUVerFrame::COLOR_RGB || imageColorSpace == PlaYUVerFrame::COLOR_ARGB ) )
|
||||
{
|
||||
PlaYUVerFrame::Pixel currPixel( imageColorSpace, *( data[COLOR_R] ), *( data[COLOR_G] ), *( data[COLOR_B] ) );
|
||||
luma = PlaYUVerFrame::ConvertPixel( currPixel, PlaYUVerFrame::COLOR_YUV ).Y();
|
||||
m_pdHistogram[luma + j * m_uiHistoSegments]++;
|
||||
}
|
||||
for( j = 0; j < m_uiChannels; j++ )
|
||||
data[j] += 1;
|
||||
}
|
||||
}
|
||||
m_bHasHistogram = true;
|
||||
}
|
||||
|
||||
Int PlaYUVerFrameStats::getHistogramSegment()
|
||||
{
|
||||
return m_uiHistoSegments;
|
||||
}
|
||||
|
||||
Int PlaYUVerFrameStats::getRealHistoChannel( Int channel )
|
||||
{
|
||||
Int histoChannel;
|
||||
|
||||
switch( imageColorSpace )
|
||||
{
|
||||
case PlaYUVerFrame::COLOR_GRAY:
|
||||
if( channel != LumaChannel )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
histoChannel = 0;
|
||||
break;
|
||||
case PlaYUVerFrame::COLOR_RGB:
|
||||
if( channel != RedChannel && channel != GreenChannel && channel != BlueChannel && ( channel != LumaChannel && calcLuma ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( channel == RedChannel )
|
||||
histoChannel = 0;
|
||||
|
||||
if( channel == GreenChannel )
|
||||
histoChannel = 1;
|
||||
|
||||
if( channel == BlueChannel )
|
||||
histoChannel = 2;
|
||||
|
||||
if( channel == LumaChannel )
|
||||
histoChannel = 3;
|
||||
}
|
||||
break;
|
||||
case PlaYUVerFrame::COLOR_ARGB:
|
||||
if( channel != RedChannel && channel != GreenChannel && channel != BlueChannel && channel != AlphaChannel && ( channel != LumaChannel && calcLuma ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( channel == AlphaChannel )
|
||||
histoChannel = 0;
|
||||
|
||||
if( channel == RedChannel )
|
||||
histoChannel = 1;
|
||||
|
||||
if( channel == GreenChannel )
|
||||
histoChannel = 2;
|
||||
|
||||
if( channel == BlueChannel )
|
||||
histoChannel = 3;
|
||||
|
||||
if( channel == LumaChannel )
|
||||
histoChannel = 4;
|
||||
}
|
||||
break;
|
||||
case PlaYUVerFrame::COLOR_YUV:
|
||||
if( channel != LumaChannel && channel != YChannel && channel != CbChannel && channel != CrChannel )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( channel == YChannel || channel == LumaChannel )
|
||||
histoChannel = 0;
|
||||
|
||||
if( channel == CbChannel )
|
||||
histoChannel = 1;
|
||||
|
||||
if( channel == CrChannel )
|
||||
histoChannel = 2;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
histoChannel = -1;
|
||||
}
|
||||
return histoChannel;
|
||||
}
|
||||
|
||||
Double PlaYUVerFrameStats::getCount( Int channel, UInt start, UInt end )
|
||||
{
|
||||
UInt i;
|
||||
Int histoChannel;
|
||||
Int indexStart;
|
||||
Double count = 0.0;
|
||||
|
||||
if( !m_pdHistogram || start < 0 || end > m_uiHistoSegments - 1 || start > end )
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
histoChannel = getRealHistoChannel( channel );
|
||||
|
||||
if( histoChannel == -1 )
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
indexStart = histoChannel * m_uiHistoSegments;
|
||||
|
||||
for( i = start; i <= end; i++ )
|
||||
{
|
||||
count += m_pdHistogram[indexStart + i];
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
Double PlaYUVerFrameStats::getPixels()
|
||||
{
|
||||
if( !m_pdHistogram )
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return ( m_uiImageWidth * m_uiImageHeight );
|
||||
}
|
||||
|
||||
Double PlaYUVerFrameStats::getMean( Int channel, UInt start, UInt end )
|
||||
{
|
||||
Int indexStart;
|
||||
Int histoChannel;
|
||||
Double mean = 0.0;
|
||||
Double count;
|
||||
|
||||
if( !m_pdHistogram || start < 0 || end > m_uiHistoSegments - 1 || start > end )
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
histoChannel = getRealHistoChannel( channel );
|
||||
|
||||
if( histoChannel == -1 )
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
indexStart = histoChannel * m_uiHistoSegments;
|
||||
|
||||
for( UInt i = start; i <= end; i++ )
|
||||
{
|
||||
mean += i * m_pdHistogram[indexStart + i];
|
||||
}
|
||||
|
||||
count = getCount( channel, start, end );
|
||||
|
||||
if( count > 0.0 )
|
||||
{
|
||||
return mean / count;
|
||||
}
|
||||
|
||||
return mean;
|
||||
}
|
||||
|
||||
Int PlaYUVerFrameStats::getMedian( Int channel, UInt start, UInt end )
|
||||
{
|
||||
Int histoChannel;
|
||||
Int indexStart;
|
||||
Double sum = 0.0;
|
||||
Double count;
|
||||
|
||||
if( !m_pdHistogram || start < 0 || end > m_uiHistoSegments - 1 || start > end )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
histoChannel = getRealHistoChannel( channel );
|
||||
|
||||
if( histoChannel == -1 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
indexStart = histoChannel * m_uiHistoSegments;
|
||||
|
||||
count = getCount( channel, start, end );
|
||||
|
||||
for( UInt i = start; i <= end; i++ )
|
||||
{
|
||||
sum += m_pdHistogram[indexStart + i];
|
||||
if( sum * 2 > count )
|
||||
return i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Double PlaYUVerFrameStats::getStdDev( Int channel, UInt start, UInt end )
|
||||
{
|
||||
Int histoChannel;
|
||||
Int indexStart;
|
||||
Double dev = 0.0;
|
||||
Double count;
|
||||
Double mean;
|
||||
|
||||
if( !m_pdHistogram || start < 0 || end > m_uiHistoSegments - 1 || start > end )
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
histoChannel = getRealHistoChannel( channel );
|
||||
|
||||
if( histoChannel == -1 )
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
indexStart = histoChannel * m_uiHistoSegments;
|
||||
mean = getMean( channel, start, end );
|
||||
count = getCount( channel, start, end );
|
||||
|
||||
if( count == 0.0 )
|
||||
count = 1.0;
|
||||
|
||||
/*------------ original
|
||||
|
||||
for ( i = start ; i <= end ; i++ )
|
||||
{
|
||||
dev += ( i - mean ) * ( i - mean ) * m_pdHistogram[indexStart +i];
|
||||
}
|
||||
|
||||
return sqrt( dev / count );
|
||||
|
||||
-----------------------*/
|
||||
|
||||
for( UInt i = start; i <= end; i++ )
|
||||
{
|
||||
dev += ( i * i ) * m_pdHistogram[indexStart + i];
|
||||
}
|
||||
|
||||
return sqrt( ( dev - count * mean * mean ) / ( count - 1 ) );
|
||||
|
||||
}
|
||||
|
||||
Double PlaYUVerFrameStats::getHistogramValue( Int channel, UInt bin )
|
||||
{
|
||||
Double value;
|
||||
Int histoChannel;
|
||||
Int indexStart;
|
||||
|
||||
if( !m_pdHistogram || bin < 0 || bin > m_uiHistoSegments - 1 )
|
||||
return 0.0;
|
||||
|
||||
histoChannel = getRealHistoChannel( channel );
|
||||
|
||||
if( histoChannel == -1 )
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
indexStart = histoChannel * m_uiHistoSegments;
|
||||
|
||||
value = m_pdHistogram[indexStart + bin];
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
Double PlaYUVerFrameStats::getMaximum( Int channel )
|
||||
{
|
||||
Double max = 0.0;
|
||||
|
||||
Int histoChannel;
|
||||
Int indexStart;
|
||||
|
||||
if( !m_pdHistogram )
|
||||
return 0.0;
|
||||
|
||||
histoChannel = getRealHistoChannel( channel );
|
||||
|
||||
if( histoChannel == -1 )
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
indexStart = histoChannel * m_uiHistoSegments;
|
||||
|
||||
for( UInt x = 0; x < m_uiHistoSegments; x++ )
|
||||
{
|
||||
if( m_pdHistogram[indexStart + x] > max )
|
||||
{
|
||||
max = m_pdHistogram[indexStart + x];
|
||||
}
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
} // NAMESPACE
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
/* This file is a part of plaYUVer project
|
||||
* Copyright (C) 2014 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 PlaYUVerFrameStats.h
|
||||
* \brief Measure PlaYUVerFrame statistics
|
||||
* Based on the work of Ricardo N. Rocha Sardo in SCode project
|
||||
*/
|
||||
|
||||
#ifndef __PLAYUVERFRAMESTATS_H__
|
||||
#define __PLAYUVERFRAMESTATS_H__
|
||||
|
||||
#include "PlaYUVerDefs.h"
|
||||
|
||||
namespace plaYUVer
|
||||
{
|
||||
|
||||
class PlaYUVerFrame;
|
||||
|
||||
class PlaYUVerFrameStats
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
enum StatisticsChannel
|
||||
{
|
||||
LumaChannel = 0,
|
||||
RedChannel = 1,
|
||||
GreenChannel = 2,
|
||||
BlueChannel = 3,
|
||||
AlphaChannel = 4,
|
||||
YChannel = 1,
|
||||
CbChannel = 2,
|
||||
CrChannel = 3
|
||||
};
|
||||
|
||||
enum StatisticsOptions
|
||||
{
|
||||
CalcLumaWhenRGB = 1
|
||||
};
|
||||
|
||||
public:
|
||||
PlaYUVerFrameStats();
|
||||
~PlaYUVerFrameStats();
|
||||
|
||||
Void calcHistogram();
|
||||
|
||||
// Methods for to manipulate the histogram data.
|
||||
Double getCount( Int channel, UInt start, UInt end );
|
||||
Double getMean( Int channel, UInt start, UInt end );
|
||||
Int getMedian( Int channel, UInt start, UInt end );
|
||||
|
||||
/**
|
||||
* @return Number of image pixels
|
||||
*/
|
||||
Double getPixels();
|
||||
Double getStdDev( Int channel, UInt start, UInt end );
|
||||
Double getHistogramValue( Int channel, UInt bin );
|
||||
Double getMaximum( Int channel );
|
||||
|
||||
/**
|
||||
* @return Number of histogram segments: 256 or 65536 for 8 or 16 bits per
|
||||
* sample.
|
||||
*/
|
||||
Int getHistogramSegment();
|
||||
|
||||
private:
|
||||
|
||||
/** The histogram data.*/
|
||||
Double* m_pdHistogram;
|
||||
|
||||
/** If true, calc the luminosity channel histogram when the image is RGB */
|
||||
Bool calcLuma;
|
||||
|
||||
/** If the image is RGB and calcLuma is true, we have 1 more channel */
|
||||
Int histoChannels;
|
||||
|
||||
/** Image information.*/
|
||||
Pel*** m_pppImageData;
|
||||
UInt m_uiImageWidth;
|
||||
UInt m_uiImageHeight;
|
||||
UInt m_uiChannels;
|
||||
Int imageColorSpace;
|
||||
UInt imageChromaSize;
|
||||
|
||||
/** Numbers of histogram segments dependaing of image bytes depth*/
|
||||
UInt m_uiHistoSegments;
|
||||
|
||||
/** Used to stop thread during calculations.*/
|
||||
Bool runningFlag;
|
||||
|
||||
Int getRealHistoChannel( Int channel );
|
||||
|
||||
protected:
|
||||
|
||||
Bool m_bHasHistogram;
|
||||
|
||||
Void xSetupStatistics( const PlaYUVerFrame *pcFrame, UInt options = CalcLumaWhenRGB );
|
||||
|
||||
};
|
||||
|
||||
} // NAMESPACE
|
||||
|
||||
#endif // __PLAYUVERFRAMESTATS_H__
|
||||
Reference in new issue
Block a user