熱線(xian)電話(hua):0755-23712116
郵箱(xiang):contact@legoupos.cn
地址:深圳市寶安(an)區沙井街(jie)道后亭茅洲山工業園(yuan)工業大廈(sha)全至科技(ji)創新園(yuan)科創大廈(sha)2層2A
總結學習下圖像處理方面基礎知識(shi)。
這是(shi)第(di)一篇,簡單(dan)的(de)介紹下使用OpenCV的(de)三個基本功能:
然后概述下圖像噪聲的類型,并為圖像添加兩種常見的噪聲:高斯噪聲和椒鹽噪聲。
最后,使(shi)用中值(zhi)濾波(bo)(bo)和(he)均值(zhi)濾波(bo)(bo)來(lai)處理(li)帶有噪(zao)聲的圖像。
在(zai)OpenCV中,完成圖像的輸(shu)入輸(shu)出(chu)以(yi)及顯示(shi),只需要以(yi)下(xia)幾個函數:
namedWindow
創建一(yi)個(ge)可以(yi)(yi)通過其名字引(yin)用(yong)的窗(chuang)口(kou)(kou)。第(di)一(yi)個(ge)參(can)數,設(she)置窗(chuang)口(kou)(kou)的name,可以(yi)(yi)通過name引(yin)用(yong)該窗(chuang)口(kou)(kou);第(di)二個(ge)參(can)數,設(she)置窗(chuang)口(kou)(kou)的大小。有以(yi)(yi)下幾(ji)個(ge)選(xuan)擇:
imshow
顯示圖像
imread
讀取圖像數據到Mat
中,第(di)(di)一個參數(shu)(shu)是圖像(xiang)的(de)文件名;第(di)(di)二(er)個參數(shu)(shu)是標(biao)志,標(biao)識(shi)怎么處(chu)理(li)圖像(xiang)的(de)色(se)彩(cai)。常用的(de)幾個選項:
Mat
是OpenCV中最重要的數據結構,在做圖像處理時基本都是對該結構體的操作。Mat
由兩部分構成:矩(ju)陣(zhen)頭(tou)和矩陣數據,矩陣頭較小,創建的每個Mat
實例都擁有一個矩陣頭,而矩陣數據通常占有較大的空間,OpenCV中通過引(yin)用計數來管理這部分內存空(kong)間,當(dang)調(diao)用賦值運算符(fu)和拷貝(bei)構造函數時,并不會只復制(zhi)矩陣頭,并不會復制(zhi)矩陣數據,只是將其的引用計數加1.例如:
Mat m = imread("img.jpg");
Mat a = m; // 賦值運(yun)算符
Mat b(m); // 拷貝(bei)構造函(han)數
上面代碼中的a
,b
和m
各自擁有自己(ji)的(de)矩陣頭,其(qi)(qi)引用(yong)的(de)數據卻(que)指向同一(yi)份(fen)。也就(jiu)是說,修改(gai)了其(qi)(qi)中任意一(yi)個,都會影響到其(qi)(qi)余的(de)兩個。
要想復制矩陣數據,可以調用clone
和copyTo
這兩個函數
Mat m = imread("img.jpg");
Mat f = m.clone();
Mat g ;
m.copyTo(g);
將圖像讀入到Mat
后,有三種方式訪問Mat
中的數據:
圖(tu)像(xiang)噪聲是圖(tu)像(xiang)在(zai)獲取或(huo)傳(chuan)輸的(de)(de)(de)過(guo)程中受到隨(sui)機信號的(de)(de)(de)干擾,在(zai)圖(tu)像(xiang)上(shang)出現的(de)(de)(de)一(yi)些隨(sui)機的(de)(de)(de)、離散的(de)(de)(de)、孤(gu)立的(de)(de)(de)像(xiang)素點(dian),這些點(dian)會干擾人(ren)眼對圖(tu)像(xiang)信息(xi)的(de)(de)(de)分析。圖(tu)像(xiang)的(de)(de)(de)噪聲通常是比較復雜的(de)(de)(de),很多(duo)時(shi)候將(jiang)其看成是多(duo)維(wei)隨(sui)機過(guo)程,因(yin)而可(ke)以借助于隨(sui)即(ji)過(guo)程描(miao)述噪聲,即(ji)使用概(gai)率(lv)分布(bu)函數和概(gai)率(lv)密(mi)度函數。
圖像的噪聲很多,性質也千差萬別, 可以通過不同的方法給噪聲分類。
按照產生的原因:
噪聲和圖像(xiang)信號(hao)的關系,可(ke)以分為(wei):
最重要的來(lai)了,按照概率密度函數(PDF)分類:
按(an)照指(zhi)定的噪聲類型,生(sheng)成一個隨(sui)機數,然后將這(zhe)個隨(sui)機數加(jia)到(dao)(dao)源像素值上,并將得(de)到(dao)(dao)的值所放(fang)到(dao)(dao)[0,255]區(qu)間即(ji)可(ke)。
新的隨機數生成器被抽象成了兩個部分:隨機數生成引擎和要生成的隨機數符合的分布。
隨機數引擎有三種:
第一種(zhong)最常用,而且速度比(bi)較快(kuai);第二種(zhong)號稱最好的偽隨機數生成(cheng)器(qi)
#include
std::random_device rd; // 隨機(ji)數種(zhong)子
std::mt19937 mt(rd()); // 隨機(ji)數(shu)引擎
std::normal_distribution<> d(5,20); // 高斯分布
std::map<int,int> hist;
for(int n = 0; n < 10000; n ++)
++hist[std::round(d(mt))]; // 生成符合高斯分布的(de)隨機數(shu)
使用C++的隨機數發生器為圖像添加兩種噪聲:椒鹽噪聲和高斯噪聲。
椒鹽噪聲是(shi)圖(tu)像(xiang)中(zhong)離散(san)分(fen)布的白點或者黑(hei)點,其(qi)代碼如下:
// 添(tian)加椒鹽噪聲(sheng)
void addSaltNoise(Mat &m, int num)
{
// 隨機數產生器
std::random_device rd; //種(zhong)子
std::mt19937 gen(rd()); // 隨機數引擎
auto cols = m.cols * m.channels();
for (int i = 0; i < num; i++)
{
auto row = static_cast<int>(gen() % m.rows);
auto col = static_cast<int>(gen() % cols);
auto p = m.ptr(row);
p[col++] = 255;
p[col++] = 255;
p[col] = 255;
}
}
上述代碼中使用ptr
獲取圖像(xiang)某一(yi)行的行首(shou)指針,得到行首(shou)指針后就可以任意的訪問改行的像(xiang)素值。
高斯噪聲是一種(zhong)加性噪聲,為圖像添加高斯噪聲的(de)代(dai)碼如(ru)下(xia):
// 添加Gussia噪聲
// 使用指針訪問
void addGaussianNoise(Mat &m, int mu, int sigma)
{
// 產生高斯(si)分布隨機數發(fa)生器
std::random_device rd;
std::mt19937 gen(rd());
std::normal_distribution<> d(mu, sigma);
auto rows = m.rows; // 行數
auto cols = m.cols * m.channels(); // 列數
for (int i = 0; i < rows; i++)
{
auto p = m.ptr(i); // 取(qu)得(de)行首指(zhi)針
for (int j = 0; j < cols; j++)
{
auto tmp = p[j] + d(gen);
tmp = tmp > 255 ? 255 : tmp;
tmp = tmp < 0 ? 0 : tmp;
p[j] = tmp;
}
}
}
隨(sui)機產生符合高斯分布的(de)隨(sui)機數,然后將(jiang)該值和(he)圖像原有的(de)像素值相加,并將(jiang)得到(dao)的(de)和(he)壓縮到(dao)[0,255]區(qu)間內。
左邊是原圖,中間(jian)的(de)是添加高斯噪聲(sheng)后的(de)圖像,最(zui)右邊的(de)是添加椒鹽(yan)噪聲(sheng)后的(de)圖像。
根據噪聲類型的不同,選擇不同的濾波器過濾掉噪聲。通常,對于椒鹽噪聲,選擇中值濾波器(Median Filter),在去掉噪聲的同時,不會模糊圖像;對于高斯噪聲,選擇均值濾波器(Mean Filter),能夠去掉噪聲,但會對圖像造成一定的模糊。
在OpenCV中,對應于均值濾波器的函數是blur
,該函數需要5個參數,通常只設置前3個后兩個使用默認值即可。blur(m, m2, Size(5, 5));
第一個參數是輸入的圖像,第二個參數是輸出的圖像,第三個參數是濾波器的大小,這里使用的是的矩形。
對應于中值濾波器的函數是medianBlur(m1, m3, 5);
前(qian)兩個(ge)參數是(shi)輸入輸出(chu)的(de)圖像,第三個(ge)參數是(shi)濾(lv)波器(qi)的(de)大(da)小,由于是(shi)選(xuan)取的(de)是(shi)中(zhong)值,濾(lv)波器(qi)的(de)大(da)小通(tong)常是(shi)一個(ge)奇數。
下圖是對有噪聲圖像使用濾波器后的結果,中間的是原始圖像,左邊的是使用均值濾波器過濾高斯噪聲后的結果;右邊的是使用中值濾波器過濾椒鹽噪聲后的結果。可以明顯的看出,這兩種濾波器都能夠很好的去掉圖像的噪聲,但會對圖像造成一定的模糊,尤其是均值濾波器造成的模糊比較明顯。
本文算是第一篇文章,簡單的介紹下OpenCV的基本使(shi)用;接著訪問圖(tu)像(xiang)(xiang)中(zhong)的像(xiang)(xiang)素,并借助于C++11的隨機數庫,為(wei)圖(tu)像(xiang)(xiang)添加高(gao)斯噪聲和椒鹽噪聲;最(zui)后使(shi)用中(zhong)值濾波器(qi)和均值濾波器(qi)除去(qu)圖(tu)像(xiang)(xiang),并對結(jie)果進(jin)行了對比。
以后堅持每日對(dui)圖像處理的一些知識進(jin)行(xing)整(zheng)理。