直方圖
一、原理和目的
(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;

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/285708.html
標籤:其他
