原理介紹:
如果遇到了需要估算一塊灰度圖像平均灰度的問題,而且這幅圖像又很“巨大”,那麼逐像素遍歷式的暴力計算方法往往費時費力,此時採用“米字估算“的方法可以較好的提高效率。所謂“米字估算”如圖-1,只需要計算深色區域的灰度之和然後除以像素數量就可以得平均灰度。深色區域可以分爲 橫,豎,撇,捺 四個部分。橫線上的像素數量正好是所要計算的灰度圖像的寬度,豎線上的
圖-1
像素數量正好是灰度圖像的高度。如果要計算撇和捺上的像素灰度和,首先需要計算灰度度圖的高寬之比,定義一個乘算因子 factor = 圖像高度/圖像寬度,然後依次遍歷橫線上像素的同時就可以很容易計算出垂直方向上在撇和捺直線上分別對應的兩個像素的位置,那麼,撇和捺上需要計算的像素數量之和就是灰度圖寬度的2倍,這樣橫豎撇捺四條直線上需要計算的像素數量就是 圖像的寬度×3+圖像高度。
實現代碼:
(ps:未提供編程上下文的情況下僅供參考使用):
// 估算平均灰度 value(採用 米字 估算)
unsigned char *perline = nullptr;
unsigned char *pixel = nullptr;
float count = 0.0f; // 米字像素的總亮度
float factor = (float)(parea->height) / (float)(parea->width); // 乘算因子
int j=0, k=0; // 遍歷之用
for(k=0;k < parea->width;++k)
{
j = (int)(k * factor);
pixel = parea->begin + k*3;
count += PIXEL_LIGHT( (pixel + parea->height/2*(parea->width*3)) );
count += PIXEL_LIGHT( (pixel + j*parea->step) );
count += PIXEL_LIGHT( (pixel + (parea->height-j-1)*parea->step) );
}
perline = parea->begin + parea->width*3;
for(j=0;j < parea->height;++j)
{
pixel = perline + parea->step;
count += PIXEL_LIGHT(pixel);
}
parea->avevalue = (int)( count / (parea->width*3 + parea->height) );
代碼簡單測試與結果:
對於以下三幅圖像分別使用全部遍歷計算的方法和“米字估算”方法計算其平均灰度,一下爲三次測試結果:
測試1圖像:
測試1結果:
測試2圖像:
測試2結果:
測試3圖像:
測試3結果:
本篇結束。
如有任何錯誤或者更好的方法或建議,歡迎指正