OpenCV中直方图均衡化
OpenCV中直方圖均衡化
首先知道直方圖是個(gè)什么鬼?在一幅圖像中,直方圖所體現(xiàn)的是每個(gè)像素值在所有的像素中所占的比例:例值為127的像素點(diǎn)的個(gè)數(shù)/圖像總的像素點(diǎn)的個(gè)數(shù)\color{#f00}值為127的像素點(diǎn)的個(gè)數(shù)/圖像總的像素點(diǎn)的個(gè)數(shù)值為127的像素點(diǎn)的個(gè)數(shù)/圖像總的像素點(diǎn)的個(gè)數(shù)
根據(jù)這個(gè)可以想到在比較 暗的圖像中,直方圖主要分布在0的附近,而在比較亮的圖像中,直方圖主要分布在255附近,為了使圖像更加清晰,體現(xiàn)出更多的紋理等,需要將像素均勻的分布在0-255之間,這樣圖像看起來(lái)就不會(huì)太暗或者太亮,這就是直方圖均衡化的思想。
具體的步驟:
圖片來(lái)自:https://blog.csdn.net/macunshi/article/details/79815870
根據(jù)這個(gè)圖片上所說(shuō),我將均衡化分為以下幾個(gè)步驟,并在最后根據(jù)這個(gè)步驟手寫代碼實(shí)現(xiàn)直方圖的均衡化:
1、統(tǒng)計(jì)各個(gè)像素出現(xiàn)的頻率。
2、計(jì)算每個(gè)像素頻率的向前累積。
3、根據(jù)計(jì)算的頻率,得到均衡化后的圖像像素值。
4、根據(jù)像素值之間的映射將原圖像進(jìn)行相應(yīng)的處理。
當(dāng)然了,我們可以不用這麼麻煩,因?yàn)镺penCV再一次給我們了一個(gè)方便至極的API函數(shù):
equalizeHist(輸入圖像,要求是但通道灰度圖。輸出圖像。 );下面看一下手動(dòng)實(shí)現(xiàn)吧!效果沒(méi)有使用API來(lái)的好,所以推薦使用API,但也要知道如何實(shí)現(xiàn)。在一個(gè)小白看來(lái)API確實(shí)開(kāi)發(fā)方便,但如果只是會(huì)使用API,而對(duì)實(shí)現(xiàn)的原理一無(wú)所知,不僅API函數(shù)用不好,基礎(chǔ)也沒(méi)法得到鍛煉。
int a[256][3];//定義一個(gè)256行3列的數(shù)組,第一列存貯0-255像素值,第二列存儲(chǔ)出 現(xiàn)的次數(shù),第三列存儲(chǔ)均衡化后的像素值。這樣第一列和第三列就構(gòu)成了原像素到新像素的映射關(guān)系。for(int i = 0 ;i < 256;i++){a[i][0] = i;a[i][1] = 0;a[i][2] = 0;}for(int row = 0;row < dst.rows;row++){for(int col = 0;col < dst.cols;col++){a[dst.at<uchar>(row,col)][1] += 1;}}double p[256];//定義一個(gè)數(shù)組用來(lái)存儲(chǔ)每個(gè)像素出現(xiàn)的頻率。for(int i = 1;i < 256;i++){p[0] = (float)a[0][1]/(dst.rows*dst.cols);p[i] = (float)a[i][1]/(dst.rows*dst.cols) + p[i-1];a[i][2] = int(p[i]*255+0.5);}for(int row = 0;row < dst.rows;row++){for(int col = 0;col < dst.cols;col++){dst.at<uchar>(row,col) = a[dst.at<uchar>(row,col)][2];//根據(jù)映射關(guān)系將原像素值由新像素值替代。}}imshow("dst",dst);以下是完整的代碼:
#include "opencv2/opencv.hpp"using namespace std; using namespace cv;int main() {Mat src = imread("/home/dynamicw/Project/C++_Project/opencvtest/src/lesson01/source/map.png");Mat dst;cvtColor(src,dst,CV_RGB2GRAY);imshow("yuan",dst);equalizeHist(dst,src);imshow("src",src);int a[256][3];for(int i = 0 ;i < 256;i++){a[i][0] = i;a[i][1] = 0;a[i][2] = 0;}for(int row = 0;row < dst.rows;row++){for(int col = 0;col < dst.cols;col++){a[dst.at<uchar>(row,col)][1] += 1;}}double p[256];for(int i = 1;i < 256;i++){p[0] = (float)a[0][1]/(dst.rows*dst.cols);p[i] = (float)a[i][1]/(dst.rows*dst.cols) + p[i-1];a[i][2] = int(p[i]*255+0.5);}for(int row = 0;row < dst.rows;row++){for(int col = 0;col < dst.cols;col++){dst.at<uchar>(row,col) = a[dst.at<uchar>(row,col)][2];}}imshow("dst",dst);waitKey(0);return 0; } 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的OpenCV中直方图均衡化的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。