/* * 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& 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 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 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