123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- /*
- * Copyright (C) =USTC= Fu Li
- *
- * Author : Fu Li
- * Create : 2003-12-23
- * Home : http://www.crazy-bit.com/
- * Mail : crazybit@263.net
- * History :
- */
- #ifndef __PCL_HISTOGRAM__2003_12_23__H__
- #define __PCL_HISTOGRAM__2003_12_23__H__
- #include "ObjImage.h"
- //=============================================================================
- /**
- * Calculate histogram of image.
- */
- class FCHistogram
- {
- public:
- /// Calculate img's histogram, img's bpp >= 24.
- FCHistogram (const FCObjImage& img) ;
- /// Analyze image (only 24bpp or 32bpp image can be analyzed).
- void AnalyzeImage (const FCObjImage& img) ;
- /**
- * @name Get/Set histogram Stat. range.
- */
- //@{
- /// Get start position.
- int GetStart() const {return m_nStart;}
- /// Get end position.
- int GetEnd() const {return m_nEnd;}
- /// Set start position.
- void SetStart (int nStart) {m_nStart = FClamp0255(nStart);}
- /// Set end position.
- void SetEnd (int nEnd) {m_nEnd = FClamp0255(nEnd);}
- //@}
- /**
- * @name Query attributes.
- * nChannel can be CHANNEL_GRAY, CHANNEL_RED, CHANNEL_GREEN, CHANNEL_BLUE
- */
- //@{
- /// Get pixel count of Stat. image.
- int GetPixelNumber() const {return m_nPixelNum;}
- /// Pixel count of selected region (nChannel).
- int GetCount (IMAGE_CHANNEL nChannel = CHANNEL_GRAY) const ;
- /// Pixel count of nValue position (nChannel).
- int GetValueCount (int nValue, IMAGE_CHANNEL nChannel = CHANNEL_GRAY) const ;
- /// Pixel average of selected region (nChannel).
- int GetAverage (IMAGE_CHANNEL nChannel = CHANNEL_GRAY) const ;
- /// Get max count in selected region (nChannel).
- int GetMaxCount (IMAGE_CHANNEL nChannel = CHANNEL_GRAY) const ;
- /// Received img is 24bpp, size is (256,nHeight)
- void GetHistogramImage (int nHeight, FCObjImage* img, IMAGE_CHANNEL nChannel = CHANNEL_GRAY) const ;
- //@}
- private:
- const PCL_array<int>& GetChannelHistogram (IMAGE_CHANNEL nChannel) const
- {
- switch (nChannel)
- {
- case CHANNEL_RED : return m_HisRed ;
- case CHANNEL_GREEN : return m_HisGreen ;
- case CHANNEL_BLUE : return m_HisBlue ;
- }
- return m_HisGray ;
- }
- private:
- PCL_array<int> m_HisGray, m_HisRed, m_HisGreen, m_HisBlue ;
- int m_nStart ;
- int m_nEnd ;
- int m_nPixelNum ;
- };
- //=============================================================================
- // inline Implement
- //=============================================================================
- inline FCHistogram::FCHistogram (const FCObjImage& img) : m_HisGray(256), m_HisRed(256), m_HisGreen(256), m_HisBlue(256)
- {
- m_nStart = 0 ;
- m_nEnd = 255 ;
- m_nPixelNum = 0 ;
- AnalyzeImage (img) ;
- }
- //-----------------------------------------------------------------------------
- inline void FCHistogram::AnalyzeImage (const FCObjImage& img)
- {
- if (!img.IsValidImage() || (img.ColorBits() < 24))
- {assert(false); return;}
- for (int i=0 ; i < 256 ; i++)
- {
- m_HisGray[i] = m_HisRed[i] = m_HisGreen[i] = m_HisBlue[i] = 0 ;
- }
- m_nPixelNum = img.Width()*img.Height() ;
- for (int y=0 ; y < img.Height() ; y++)
- for (int x=0 ; x <img.Width() ; x++)
- {
- BYTE * p = img.GetBits(x,y) ;
- m_HisBlue[PCL_B(p)]++ ;
- m_HisGreen[PCL_G(p)]++ ;
- m_HisRed[PCL_R(p)]++ ;
- m_HisGray[FCColor::GetGrayscale(p)]++ ;
- }
- }
- //-----------------------------------------------------------------------------
- inline int FCHistogram::GetCount (IMAGE_CHANNEL nChannel) const
- {
- int nCount = 0 ;
- for (int i=m_nStart ; i <= m_nEnd ; i++)
- nCount += GetChannelHistogram(nChannel)[i] ;
- return nCount ;
- }
- //-----------------------------------------------------------------------------
- inline int FCHistogram::GetValueCount (int nValue, IMAGE_CHANNEL nChannel) const
- {
- return GetChannelHistogram(nChannel)[FClamp0255(nValue)] ;
- }
- //-----------------------------------------------------------------------------
- inline int FCHistogram::GetAverage (IMAGE_CHANNEL nChannel) const
- {
- double fAverage = 0 ;
- int nCount = 0 ;
- for (int i=m_nStart ; i <= m_nEnd ; i++)
- {
- int n = GetChannelHistogram(nChannel)[i] ;
- nCount += n ;
- fAverage = fAverage + n * i ;
- }
- return nCount ? (int)(fAverage/nCount) : 0 ;
- }
- //-----------------------------------------------------------------------------
- inline int FCHistogram::GetMaxCount (IMAGE_CHANNEL nChannel) const
- {
- int nMaxCount = 0 ;
- for (int i=m_nStart ; i <= m_nEnd ; i++)
- {
- int n = GetChannelHistogram(nChannel)[i] ;
- if (n > nMaxCount)
- nMaxCount = n ;
- }
- return nMaxCount ;
- }
- //-----------------------------------------------------------------------------
- inline void FCHistogram::GetHistogramImage (int nHeight, FCObjImage* img, IMAGE_CHANNEL nChannel) const
- {
- if (!img || !img->Create (256, nHeight, 24))
- return ;
- // fill white back
- memset (img->GetMemStart(), 0xFF, img->GetPitch() * img->Height()) ;
- int nMaxCount = GetMaxCount(nChannel) ;
- if (nMaxCount == 0)
- return ;
- for (int x=0 ; x < img->Width() ; x++)
- {
- int nFill = FClamp (GetChannelHistogram(nChannel)[x]*img->Height()/nMaxCount, 0, img->Height()) ;
- for (int i=0 ; i < nFill ; i++)
- {
- BYTE * p = img->GetBits(x, img->Height() - 1 - i) ;
- PCL_R(p) = PCL_G(p) = PCL_B(p) = 0 ;
- }
- }
- }
- #endif
|