【VC影象處理】直方圖均衡化
阿新 • • 發佈:2019-01-06
/*img 為輸入原圖 outimg為輸出直方圖 probality為輸出的灰度直方概率,是陣列*/ void Histogram(Mat img,Mat &outImg,float *probality) { outImg.create(500,256,CV_8UC3); outImg.setTo(Scalar(0,255,0));//outImg.setTo(Scalar::all(255)); float tmp[256]={0}; int gray[256]={0}; int i,j; int Width=img.cols; int Height=img.rows; for( i=0;i<Height;i++) { for( j=0;j<Width;j++) { gray[(int)(img.at<uchar>(i,j))]++; } } for(i=0;i<256;i++) { probality[i]=(float)(gray[i]*1.0f/(Width*Height*1.0f)); // tmp[i]=probality[i]; } int max=0; for(i=0;i<256;i++) if(gray[i]>max) max=gray[i]; for(i=0;i<256;i++) { tmp[i]=(float)(gray[i]*1.0f/(float)(max*1.0f)); tmp[i]*=500; //cout<<"tmp"<<i<<"="<<tmp[i]<<endl; } for(i=0;i<256;i++) { line(outImg,Point(i,500),Point(i,500-(int)tmp[i]),Scalar(255,0,0)); } } /*img原圖 outimg為輸出直方均衡化後的圖 probality為輸入的灰度直方概率,是陣列*/ void Histogram_Equalization(Mat img,Mat &OutImg,float *probality) { int Height=img.rows; int Width=img.cols; OutImg.create(Height,Width,CV_8UC1); float temp[256]; int tab[256]; int i,j; for(i=0;i<256;i++) { if(i==0) { temp[0]=probality[0]; } else { temp[i]=temp[i-1]+probality[i]; } tab[i]=(int)(255.0f*temp[i]+0.5f); //cout<<"tab "<<i<<"="<<tab[i]<<endl; } for(i=0;i<Height;i++) for(j=0;j<Width;j++) OutImg.at<uchar>(i,j)=(uchar)(tab[(int)(img.at<uchar>(i,j))]); }
void main() { Mat SrcImg=imread("C:\\Users\\Administrator\\Desktop\\工作\\testp\\1.jpg",0);//01.jpg",0); if(!SrcImg.data) cout<<"讀取圖片錯誤\n"; Mat ResultImg1,ResultImg2,ResultImg3; float a[256]; Histogram(SrcImg,ResultImg1,a); Histogram_Equalization(SrcImg,ResultImg2,a); Histogram(ResultImg2,ResultImg3,a); imshow("直方圖",ResultImg1); imshow("直方圖均衡化處理圖",ResultImg2); imshow("處理後的直方圖",ResultImg3); imshow("src",SrcImg); waitKey(0); }
多少天過去了,再重新讀、分析,一開始發現都忘光了,但是看了一會兒就懂了,這就是當初做筆記的好處,要不然又得翻書查資料費好大勁兒才能弄明白,記憶就是不斷重複的過程。現在把直方圖再總結如下:
直方圖均衡化:首先要獲得一張圖片的直方圖資料,一張灰度影象的直方圖灰度值0,1,2,3,4,5,6,...,254,255 需要統計這些灰度值的個數gray[(int)(img.at<uchar>(i,j))]++; 特別需要注意這種陣列格式,下標是灰度值索引值,陣列值是個數。這些其實就是直方圖的資料了,為了在一張圖上顯示直方圖,需要歸一化處理,就是找出個數最大的值作為分母。
但是均衡化的話也需要歸一化,他的歸一化方法是用影象的長和寬乘積做分母(總共有多少資料,所有歸一化資料累加和為1)。均衡化就是用這個歸一化的陣列再計算累積積分,所謂的累積積分就是當前項等於前面所有的和,這是一種概率分佈,在累積積分陣列中當是255時候它的值自然為1,然後255*積分陣列,這是最重要的,這就是接下來的對映表。這個對映陣列其實就是對灰度值的一種重新分佈。上面舉得例子灰度值123很多,佔的比重就很大,在積分圖中縱座標就會很高,再乘以255的話就更突出了,這可能就是直方圖均衡化的真諦了。 就是多的灰度值就讓他和其他一般的灰度值有明顯的差距,所謂的拉伸對比度。分析完畢!