以下の例では、1ごとの頻度分布を求めています。
//8bit画像のヒストグラム配列を作成する。 void GetHist ( BYTE **btaaData, int nRow, int nCol, int naHist, UINT uiaHist[256], UINT *uiMode ) { int i, j; *uiMode = 0; for ( i = 0; i < 255; i++ ) { uiaHist = 0; } //ヒストグラムの登録 for ( i = 0; i < nRow; i++ ) { for ( j = 0; j < nCol; j++ ) { if ( uiaHist[btaaData[i][j]] == UINT_MAX ) { continue; } else { uiaHist[ btaaData[i][j] ]++; } //最頻値を計算 if ( uiaHist[ btaaData[i][j] ] >= *uiMode ) { *uiMode = uiaHist[ btaaData[i][j] ]; } } } }
ヒストグラムの画像化
以下の例では、縦=最頻値、横=レベル数の2値マトリックスを作成します。
void ResultInMatrix( UINT uiaHist[255], BOOL **baaHist, int nMode ) { int i, j; //縦=最頻値、横=レベル数の画像を作成 (*baaHist) = (BYTE *)calloc( nMode * 255, sizeof(BYTE) ); //ヒストグラムの分だけ黒を残して、他を白にする //行列の添え字に注意! for ( i = 0; i < 255; i++ ) { for ( j = 0; j < (int)(m_mode - uiaHist[i]); j++ ) { (*baaHist)[j*255+i] = true; } } }
ヒストグラムから統計量の算出
ヒストグラムが求まっている状態から平均、標準偏差を求めるには以下のようにします。
この例では、ヒストグラム中のnStartLevel
〜nEndLevel
までの平均、標準偏差を求めます。
また、この範囲に入っていない画素の数はnOmitPixels
で与えられているものとします。
void CalcStatics ( UINT uiaHist[255], int nRow, int nCol, int nOmitPixels, int nStartLevel, int nEndLevel, double *dMean, double *dStdev ) { *dMean = 0.0; for ( i = nStartLevel; i <= nEndLevel; i++ ) { *dMean += i * uiaHist[i-nStartLevel]; //画素値の合計 } //平均 *dMean /= nRow * nCol - nOmitPixels; //標準偏差 *dStdev = 0.0; for ( i = nStartLevel; i <= nEndLevel; i++ ) { //偏差 dCn = (double)i - *dMean; //相対度数 dFqRel = (double)uiaHist[i-nStartLevel] / ((nRow * nCol) - nOmitPixels); //分散 *dStdev += dCn*dCn * dFqRel; //分散=Σ{偏差^2 × 相対度数} } //標準偏差 *dStdev = sqrt( *dStdev ); }
なお、コントラストは上記のnStartlevel
、nEndLevel
を利用して以下のように求めることができます。
double dCont = ( nEndLEvel - nStartLevel ) / ( nEndLevel + nStartLevel );