直方圖統計和顯示


直方圖

一、原理和目的

(1)目的:將單通道圖像的灰度值與對應的頻率數據可視化,便於分析圖像

(2)原理:創建一個大小為256的數組,表示0~255的灰度范圍,然后對圖像進行遍歷,每次讀取到一個灰度值就在數組對應的值進行自增操作。最終數組的下標代表的是灰度,下標對應的值代表的是灰度頻率,然后根據數據的數據描線,最終描成直方圖。

灰度

0

1

...

255

頻率

x

y

...

z

公式:

①   W=k*256  W圖像的寬度

 

②   {

         Pmin = min hist[i]     Pmin,灰度頻率的最小值

         Pmax=max hist[i]     Pmax,灰度頻率的最大值

   }

 

③   S=W/Pmax         S,y方向的縮放比例

④   H=W+△             H,圖像的高度

 

⑤   {

         ∀i,hist[i]

         P1=(i*k+1,H-1-S.Hist[i])

         P2=(i*k+1,H-1)

參數:k,△,k表示線寬,△表示高度方向上最高直方圖的余量;

 

二、步驟

(1)使用公式1計算圖像寬W

(2)使用公式2、3、4計算圖像高H

(3)遍歷數組,對每一個i,

                   可用公式5計算P1,P2

                   調用line()

          直到圖像遍歷完畢

(4)顯示直方圖

 

三、偽代碼

輸入:{H(i)|i=0,1,...,255}

△:表示高度方向上最高直方圖的余量,防止圖像顯示不完整,在代碼中為dt表示

K:表示線寬

arr[]表示存放灰度頻率的數組,下標值與灰度頻率一一對應

輸出:直方圖圖像

 

void showHisto(long arr[],int k,int dt)

{

         求arr中的最大值,等比例顯示

 

         遍歷arr數組,根據數組值,調用line描線

 

         顯示直方圖

}

 

四、源碼

void traverse(cv::Mat src,long arr[])	//統計灰度級以及其頻率,下標為灰度級,數組值為頻率
{
	long grayData[256] = { 0 };

	for (int i = 0; i < src.rows; i++)
	{

		uchar* src_rows_ptr = src.ptr<uchar>(i);
		for (int j = 0; j < src.cols; j++)
		{
			grayData[src_rows_ptr[j]]++;
		}
	}
	for (int i = 0; i < 255; i++) {
		arr[i] = grayData[i];
	}
}

 

ong getMax(long arr[])	//求最大灰度頻率
{
	long max = 0;
	for (int i = 0; i < 256; i++)
	{
		if (max < arr[i]) {
			max = arr[i];
		}
	}
	return max;
}

  

void showHisto(long arr[],int k,int dt)  //顯示直方圖
{

    long Pmax = getMax(arr);    //getMax只是求arr數組的最大值,可以自己寫一下

 

    Mat mat(k * 256+20, k * 256 , 0);

    for (int i = 0; i < 256; i++) {

        line(mat, Point(i*k + 1, k * 256+ dt), Point(i*k + 1, 256.0 * k+ dt  -  arr[i] * (3*256.0/ Pmax)), Scalar(0, 0, 0), 3);  //等比例顯示

    }

    imshow("histo", mat);

}

  

 

 

五、結果圖

顯示的結果圖像和將數據導出到Excel所顯示的圖像一致,如果要將直方圖縮小或者放大可以用cv::resize;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM