本文目錄一覽:
直方圖均衡化
想像一下,如果一副圖像中的大多是像素點的像素值都集中在一個像素值範圍之內會怎樣呢?例如,如果一幅圖片整體很亮,那所有的像素值應該都會很高。但是一副高質量的圖像的像素值分布應該很廣泛。所以你應該把它的直方圖做一個橫向拉伸(如下圖),這就是直方圖均衡化要做的事情。通常情況下,這種操作會改善圖像的對比度。
這種方法通常用來增加許多圖像的全局 對比度 ,尤其是當圖像的有用數據的對比度相當接近的時候。通過這種方法, 亮度 可以更好地在直方圖上分布。這樣就可以用於增強局部的對比度而不影響整體的對比度,直方圖均衡化通過有效地擴展常用的亮度來實現這種功能。
這種方法對於背景和前景都太亮或者太暗的圖像非常有用,這種方法尤其是可以帶來 X光 圖像中更好的 骨骼 結構顯示以及曝光過度或者曝光不足 照片 中更好的細節。這種方法的一個主要優勢是它是一個相當直觀的技術並且是 可逆 操作,如果已知均衡化 函數 ,那麼就可以恢復原始的直方圖,並且計算量也不大。這種方法的一個缺點是它對處理的數據不加選擇,它可能會增加背景 雜訊 的對比度並且降低有用 信號 的對比度。
我們先來看看相應的直方圖和累積直方圖,然後使用 OpenCV 進行直方圖均衡化。
我們可以看出來直方圖大部分在灰度值較高的部分,而且分布很集中。而我們希望直方圖的分布比較分散,能夠涵蓋整個 x 軸。所以,我們就需要一個變換函數幫助我們把現在的直方圖映射到一個廣泛分布的直方圖中,這就是直方圖均衡化。
**限制對比度自適應性直方圖均衡化 CLAHE **
在上邊做的直方圖均衡化會改變整個圖像的對比度,但是在很多情況下,這樣做的效果並不好。的確在進行完直方圖均衡化之後,圖片背景的對比度被改變了。但是你再對比一下兩幅圖像中雕像的面圖,由於太亮我們丟失了很多信息。
原理:
為了解決這個問題,我們需要使用自適應的直方圖均衡化 CLAHE (Contrast Limited Adaptive Histogram Equalization)。這種情況下,整幅圖像會被分成很多小塊,這些小塊被稱為「tiles」(在 OpenCV 中 tileGridSize默認是 8×8),然後再對每一個小塊分別進行直方圖均衡化(跟前面類似)。所以在每一個的區域中,直方圖會集中在某一個小的區域中(除非有雜訊干擾)。如果有雜訊的話,雜訊會被放大。為了避免這種情況的出現,要使用對比度限制。
CLAHE中,每一個像素鄰域都要進行對比度限制,從而得到對應的變換函數,被用來降低AHE中雜訊的增強,這主要是通過限制AHE中的對比度增強來實現的。像素周圍鄰域雜訊的增強主要是由變換函數的斜率造成的,由於像素鄰域的雜訊與鄰域的CDF成正比,因此也與鄰域直方圖在該中心像素位置的值成正比,CLAHE之所以能夠限制對比度,是因為它在計算鄰域的CDF之前在指定閾值處對直方圖進行了修剪,如下圖所示,這一做法不僅限制了CDF的斜率,也限制了變換函數的斜率,其中對直方圖進行切割所使用的閾值,被稱作修剪限制度(clip limit),這個參數不僅依賴於直方圖的歸一化,而且依賴於像素鄰域的size大小,通常設為3到4之間。
對於每個小塊來說,如果直方圖中的 bin 超過對比度的上限的話,就把其中的像素點均勻分散到其他 bins 中,然後在進行直方圖均衡化。最後,為了去除每一個小塊之間「人造的」(由於演算法造成)邊界,再使用雙線性差值,與原圖做圖層濾色混合操作(可選)。
實現:
參考文獻:
網址: 直方圖均衡化
Adaptive_histogram_equalization
書籍:《數字圖像處理》《OpenCV-Python 中文教程》
直方圖均衡化處理的主要步驟是什麼
設原始圖像在(x,y)處的灰度為f,而改變後的圖像為g,則對圖像增強的方法可表述為將在(x,y)處的灰度f映射為g。
在灰度直方圖均衡化處理中對圖像的映射函數可定義為:g = EQ (f)。
這個映射函數EQ(f)必須滿足兩個條件(其中L為圖像的灰度級數):
(1)EQ(f)在0≤f≤L-1範圍內是一個單值單增函數。這是為了保證增強處理沒有打亂原始圖像的灰度排列次序,原圖各灰度級在變換後仍保持從黑到白(或從白到黑)的排列。
(2)對於0≤f≤L-1有0≤g≤L-1,這個條件保證了變換前後灰度值動態範圍的一致性。
擴展資料:
直方圖均衡化作用
這種方法通常用來增加許多圖像的全局對比度,尤其是當圖像的有用數據的對比度相當接近的時候。通過這種方法,亮度可以更好地在直方圖上分布。
這樣就可以用於增強局部的對比度而不影響整體的對比度,直方圖均衡化通過有效地擴展常用的亮度來實現這種功能。
這種方法對於背景和前景都太亮或者太暗的圖像非常有用,這種方法尤其是可以帶來X光圖像中更好的骨骼結構顯示以及曝光過度或者曝光不足照片中更好的細節。
這種方法的一個主要優勢是它是一個相當直觀的技術並且是可逆操作,如果已知均衡化函數,那麼就可以恢復原始的直方圖,並且計算量也不大。這種方法的一個缺點是它對處理的數據不加選擇,它可能會增加背景雜訊的對比度並且降低有用信號的對比度。
在統計學中,直方圖(英語:Histogram)是一種對數據分布情況的圖形表示,是一種二維統計圖表,它的兩個坐標分別是統計樣本和該樣本對應的某個屬性的度量。直方圖是品質管理七大工具之一。
把直方圖上每個屬性的計數除以所有屬性的計數之和,就得到了歸一化直方圖。之所以叫「歸一」,是因為歸一化直方圖的所有屬性的計數之和為1,也就是說,每個屬性對應計數都是0到1之間的一個數(百分比)。
參考資料來源:百度百科-直方圖均衡化
圖像直方圖與直方圖均衡化
圖像的直方圖用來表徵該圖像像素值的分布情況。用一定數目的小區間(bin)來指定表徵像素值的範圍,每個小區間會得到落入該小區間表示範圍的像素數目。
圖像直方圖圖形化顯示不同的像素值在不同的強度值上的出現頻率,對於灰度圖像來說強度範圍為[0~255]之間,對於RGB的彩色圖像可以獨立顯示三種顏色的圖像直方圖。
drawHist()用於展示圖像的直方圖,並把它轉換成bitmap。
如果對CalcHistogram感興趣,可以查看 cv4j 的具體實現。
直方圖均衡化(histogram equalization)是一種藉助直方圖變換實現灰度映射從而達到圖像增強目的的方法。
直方圖均衡化通常是對圖像灰度值進行歸一化的一個非常好的方法,並且可以增強圖像的對比度。
基本思想:把原始圖的直方圖變換成為均勻分布的形式,這樣,就增加了像素灰度值的動態範圍,從而達到增強圖像整體對比度的效果。
同樣,如果對EqualHist感興趣,可以查看 cv4j 的具體實現。
圖像是由像素構成的,然而直方圖能夠反映像素的分布情況,可以作為是圖像一個很重要的特徵。在實際開發中,圖像直方圖在特徵提取、圖像匹配等方面都有很好的應用。除此之外,直方圖還能做圖像的相似度匹配。
直方圖均衡化則用於增強圖片,利於人的視覺效果或便於機器識別。
CalcHistogram 和 EqualHist 是 cv4j 中直方圖相關操作的類。
cv4j 是 gloomyfish 和我一起開發的圖像處理庫,純java實現,目前還處於早期的版本。
上周末我們開始做直方圖的相關操作,預計下周能做完這個模塊。
另外,在Google I/O之後,我們第一時間便更新了cv4j中的rxcv4j模塊。該模塊顧名思義是對cv4j使用RxJava進行封裝,我們將該模塊用 Kotlin 重寫,也算是趕了一回時髦:)。
該系列先前的文章:
模擬油畫和鉛筆畫的濾鏡效果
二值圖像分析之輪廓分析
基於邊緣保留濾波實現人臉磨皮的演算法
二值圖像分析:案例實戰(文本分離+硬幣計數)
Java實現高斯模糊和圖像的空間卷積
Java實現圖片濾鏡的高級玩法
Java實現圖片的濾鏡效果
數字圖像處理:直方圖均衡化
首先在直方圖的修整,有兩種方法,一種是直方圖均衡化,另外一種是直方圖規定化,用起來的話第一種方法用的比較多,這裡著重說一下第一種:直方圖均衡化.
我們引入直方圖,很大程度上是可以根據直方圖的形態來去判斷圖像的質量,比如根據下圖所示,會很快發現一張圖片是過亮還是過暗,這篇文章會說一下直方圖均衡化的原理,至於實現,以後有機會再說吧.
1.直方圖均衡化
直方圖均衡化是將原圖像通過某種變換,得到一幅灰度直方圖為均勻分布的新圖像的方法。
直方圖均衡化方法的基本思想是對在圖像中像素個數多的灰度級進行展寬,而對像素個數少的灰度級進行縮減。從而達到清晰圖像的目的。
一些理論的東西我們不談,直接用一個例子來說一下,會更容易理解:
假設有一幅圖像,共有64×64個像素,8個灰度級,各灰度級概率分布見下表 ,試將其直方圖均勻化。
解題步驟:
1:確定圖像的灰度級
在實際情況下,如果我們的圖像是彩色,需要將其轉換為灰度圖像,其中的灰度級一般是0-255,這個題的灰度級只有8級,需要注意下
2:計算原始直方圖的概率
統計每一個灰度在原始圖像上的像素所佔總體的比例,記為Pi
3:計算直方圖概率的累加值S(i)
直到最後一個灰度級,總和為1
4: 根據公式求取像素映射關係.
這裡的pix是指的灰度級,也就是(最大灰度級-最小灰度級)*累加概率+0.5後取整數
5: 灰度映射
找到了原圖像和均衡化圖像灰度的對應關係,對原圖進行操作,將每個像素映射成新的像素
此時圖像均衡化已經完成,當然你也可以再次統計灰度概率,觀察一下結果。
求一個直方圖均衡化的程序
圖形處理中有一種對比度變換,像顯示器就有對比度調節,PhotoShop也有圖片的對比度修改,對比度的提高可以使圖像細節清晰,相反,對比度的減小可以隱藏圖像的細節,在一定程度上使圖像柔和。
對比度變換其中一種比較簡單的方法是直方圖均衡化。
所謂直方圖就是在某一灰度級的象素個數占整幅圖像的象素比 h=nj/N,其中nj是灰度級在j的象素數,N是總象素數,掃描整幅圖像得出的h的離散序列就是圖像的直方圖,h求和必然=1,所以直方圖可以看成是象素對於灰度的概率分布函數。
直方圖是高低不齊的,因為象素灰度是隨機變化的,直方圖均衡化就是用一定的演算法使直方圖大致平和。
演算法如下:
對於一個直方圖
設 Pr(r)是原始圖像直方圖,Ps(s)是均衡化的直方圖,
由於其是一個概率分布函數
所以有 Ps(s)ds=Pr(r)dr (編輯關係,ds,dr是積分變數)
因為要進行均衡化,令 Ps(s)=1,
得 ds=Pr(r)dr/1
兩邊積分得 s=F Pr(r)dr (因為編輯關係,左邊F表示積分符號….-__-++)
數字圖像是離散的,因此離散化上式得
sk=E{j=0,k}(nj/N) 左式k,j是離散量下標,因為編輯關係,E{0,k}表示下標0到k的連加符號,N是象素總數
由此得出每一象素的sk為均衡化後的正規化灰度(即灰度正規化到[0,1]),統計sk即可得出均衡化後的直方圖。
在均衡化過程中可以對每一象素映射到新的實際灰度值sk*255,就實現了圖像的變換
(嚴格理論中應該是灰度正規化到[0,1]區間,然後均衡化後的sk還要量化到原始的正規灰度以實現灰度合併,下面的BCB程序並沒有量化,而且255是固定灰度級,因為256色BMP的彩色表就是256個表項)
現在開始實踐
用BCB對一BMP灰度圖像進行直方圖均衡化處理,代碼如下
//—————————-BCB6代碼
#include vcl.h
#pragma hdrstop
#includestdio.h
#include “Unit1.h”
#include”File1.h”
#pragma pack(1)
//BMP文件頭
struct BITMAPFILEHEADER_
{
short type;
int bfSize;
short re1,re2;
int Offbits;
};
//BMP信息頭
struct BITMAPINFO_
{
long size;
long width,height;
short planes,bitCount;
long comp,sizeImg;
long xpels,ypels;
long used,important;
};
//BMP彩色表項
struct COLOR_
{
char blue,green,red,re;
};
//——將BMP彩色表的數據校正到BCB TColor的數據。
void SwitchColor(long c)
{
long blue=c 0x000000ff;
long green=c 0x0000ff00;
long red=c 0x00ff0000;
c=(blue16) | green | (red16);
}
void xxx()
{
FILE *f=fopen(“f:\\bbs_prev2.bmp”,”rb”);
if(f==NULL) /*判斷文件是否打開成功*/
{
ShowMessage(“File open error”);
return;
}
fseek(f,0,0);//移動到開頭
//———-讀BMP文件頭
BITMAPFILEHEADER_ *bmph=new BITMAPFILEHEADER_();
if(fread((char*)bmph,sizeof(BITMAPFILEHEADER_),1,f)==NULL)
{
ShowMessage(“File read error”);
return;
}
//———–讀BMP信息頭
BITMAPINFO_ *bmpi=new BITMAPINFO_();
if(fread((char*)bmpi,sizeof(BITMAPINFO_),1,f)==NULL)
{
ShowMessage(“File read error2”);
return;
}
//————–讀彩色表
long *c=new long[bmph-Offbits-sizeof(BITMAPFILEHEADER_)-sizeof(BITMAPINFO_)];
fread((char*)c,bmph-Offbits-sizeof(BITMAPFILEHEADER_)-sizeof(BITMAPINFO_),1,f);
//———-顯示一些信息
Form1-Edit1-Text=IntToStr(bmph-bfSize);
Form1-Edit2-Text=IntToStr(bmpi-width);
Form1-Edit3-Text=IntToStr(bmpi-height);
Form1-Edit4-Text=IntToStr(bmpi-comp);
Form1-Edit5-Text=IntToStr(bmpi-used);
int i,j,k,wc;
long N=bmph-bfSize- bmph-Offbits;//象素總數
unsigned char *image=new char[N]; //點陣圖矩陣
unsigned char *newimage=new char[N];//變換後的點陣圖矩陣
fread(image,N,1,f);//讀入點陣圖矩陣
//———直方圖數列初始化
//———直方圖數列用來存儲正規化後的灰度
double *h=new double[255];//255個灰度級,保存原始圖像正規化灰度直方圖數據
for(i=0;i255;i++)
h[i]=0.0;
double *nh=new double[255];//255個灰度級,保存變換後的圖像正規化灰度直方圖
for(i=0;i255;i++)
nh[i]=0.0;
long *count=new long[255]; //每一灰度級的象素數量統計
for(i=0;i255;i++)
count[i]=0;
for(i=0;iN;i++)
{
count[image[i]]++;
}
//-----正規化灰度概率統計
for(i=0;i255;i++)
{
h[i]=count[i]/(double)N;
}
//——正規化新灰度圖
double hc;
for(i=0;iN;i++)
{
hc=0;
for(j=0;jimage[i];j++)
hc+=h[j];
nh[image[i]]+=hc; //保存新正規化灰度圖
newimage[i]=hc*255; //保存新圖像灰度索引
}
//———-顯示直方圖
for(i=0;i255;i++)
{
//原始直方圖
Form1-Canvas-MoveTo(10+i,200);
Form1-Canvas-LineTo(10+i,200+h[i]*N);
//新直方圖
Form1-Canvas-MoveTo(300+i,200);
Form1-Canvas-LineTo(300+i,200+nh[i]*255);
}
//——顯示圖形
TColor *tc;
if(bmpi-width%4==0)//———–因為BMP圖像4位元組對齊
wc=bmpi-width/4*4;
else
wc=(bmpi-width/4+1)*4;
long a;
long pos=0;
for( i=0;ibmpi-height;i++)
{
for(j=0;jwc;j++)
{
//—–原始圖形
a= c[image[pos]];
SwitchColor(a);
Form1-Canvas-Pixels[10+j][600-i]=a;
//——新圖形
a= c[newimage[pos]];
SwitchColor(a);
Form1-Canvas-Pixels[300+j][600-i]=a;
pos++;
}
}
fclose(f);
}
這個程序使用256色BMP文件,但程序代碼是針對灰度圖像的,用於彩色圖像時得出一些古怪色彩配合而已。
在對灰度圖像均衡化時
如果原始圖像對比度本來就很高,如果再均衡化則灰度調和,對比度降低。
在泛白緩和的圖像中,由於均衡化過程中會合併一些象素灰度,則會增大對比度,這裡255灰度級太多,合併不明顯。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/256598.html