圖像濾波:
盡量保留圖像細(xì)節(jié)特征的條件下對目標(biāo)圖像的噪聲進(jìn)行抑制和平滑處理,是圖像預(yù)處理中不可缺少的操作,其處理效果的好壞將直接影響到后續(xù)圖像處理和分析的有效性和可靠性。
濾波器:
低通濾波器(允許低頻通過)占遥,高通濾波器理盆,帶通濾波器痘煤,帶阻濾波器,全通濾波器猿规,陷波濾波器衷快。
我在這兒主要介紹OpenCV中所提供的濾波操作,線性濾波與非線性濾波姨俩。
opencv中線性濾波操作有:方框濾波蘸拔、均值濾波和高斯濾波师郑。非線性濾波操作有:中值濾波和雙邊濾波。
方框濾波
講到方框濾波调窍,我們不能不提及的是線性鄰域濾波算子宝冕,即用不同的權(quán)重去結(jié)合一個小鄰域內(nèi)的像素,來得到應(yīng)有的處理效果邓萨。鄰域濾波(卷積):左邊圖像與中間圖像的卷積產(chǎn)生右邊圖像地梨。目標(biāo)圖像中綠色標(biāo)記的像素是利用原圖像中藍(lán)色標(biāo)記的像素計算得到的。線性濾波處理的輸出像素值g(i,j)是輸入像素值f(j+k,j+l)的加權(quán)和 先誉,其中加權(quán)和稱之為“核”湿刽,濾波器的加權(quán)系數(shù),即濾波器的“濾波系數(shù)”褐耳。
/**
* opencv中方框濾波函數(shù)
* 第一個參數(shù):輸入的圖片
* 第二個參數(shù):輸出的圖片
* 第三個參數(shù):圖片的深度(存儲每個像素所用的位數(shù))一般情況使用-1也就是原有的圖像深度
* 第四個參數(shù):核心的大小
* 第五個參數(shù):錨點的位置诈闺,就是我們要進(jìn)行處理的點,默認(rèn)值(-1铃芦,-1)表示錨點在核的中心
* 第六個參數(shù):normalize默認(rèn)值為true雅镊,表示內(nèi)核是否被其區(qū)域歸一化(normalized)了,當(dāng)normalize=true的時候刃滓,方框濾波就變成了我們熟悉的均值濾波仁烹。也就是說,均值濾波是方框濾波歸一化(normalized)后的特殊情況咧虎。其中卓缰,歸一化就是把要處理的量都縮放到一個范圍內(nèi),比如(0,1),以便統(tǒng)一處理和直觀量化砰诵。而非歸一化(Unnormalized)的方框濾波用于計算每個像素鄰域內(nèi)的積分特性征唬,比如密集光流算法(dense optical flow algorithms)中用到的圖像倒數(shù)的協(xié)方差矩陣(covariance matrices of image derivatives)如果我們要在可變的窗口中計算像素總和,可以使用integral()函數(shù)
* 第七個參數(shù):邊界模式茁彭,默認(rèn)值BORDER_DEFAULT
*/
CV_EXPORTS_W void boxFilter( InputArray src, OutputArray dst, int ddepth,
Size ksize, Point anchor = Point(-1,-1),
bool normalize = true,
int borderType = BORDER_DEFAULT );
extern "C"
JNIEXPORT jintArray JNICALL
Java_com_xy_opencv_ndk_1opencv002_MainActivity_blurImage(JNIEnv *env, jclass type,jintArray pixels_, jint w, jint h) {
jint *pixels = env->GetIntArrayElements(pixels_, NULL);
Mat img(h, w, CV_8UC4, pixels);
boxFilter(img,img,-1,Size(30,30));
int size = w * h;
jintArray array = env->NewIntArray(size);
env->SetIntArrayRegion(array, 0, size, pixels);
env->ReleaseIntArrayElements(pixels_, pixels, 0);
return array;
}
均值濾波
方框濾波歸一化之后就是均值濾波总寒。也就是輸出圖像的每一個像素是核窗口內(nèi)輸入圖像對應(yīng)像素的像素平均值( 所有像素加權(quán)系數(shù)相等)。
/**
* 均值濾波(歸一化之后又進(jìn)行了方框濾波)
* 第一個參數(shù):輸入的圖片
* 第二個參數(shù):輸出的圖片
* 第三個參數(shù):核心的大小
* 第四個參數(shù):錨點的位置理肺,就是我們要進(jìn)行處理的點摄闸,默認(rèn)值(-1,-1)表示錨點在核的中心
* 第五個參數(shù):邊界模式妹萨,默認(rèn)值BORDER_DEFAULT
*/
CV_EXPORTS_W void blur( InputArray src, OutputArray dst,
Size ksize, Point anchor = Point(-1,-1),
int borderType = BORDER_DEFAULT );
extern "C"
JNIEXPORT jintArray JNICALL
Java_com_xy_opencv_ndk_1opencv002_MainActivity_blurImage(JNIEnv *env, jclass type,jintArray pixels_, jint w, jint h) {
jint *pixels = env->GetIntArrayElements(pixels_, NULL);
Mat img(h, w, CV_8UC4, pixels);
blur(img,img,Size(30,30));
int size = w * h;
jintArray array = env->NewIntArray(size);
env->SetIntArrayRegion(array, 0, size, pixels);
env->ReleaseIntArrayElements(pixels_, pixels, 0);
return array;
}
高斯濾波
高斯濾波是一種線性平滑濾波年枕,適用于消除高斯噪聲,廣泛應(yīng)用于圖像處理的減噪過程乎完。通俗的講熏兄,高斯濾波就是對整幅圖像進(jìn)行加權(quán)平均的過程,每一個像素點的值,都由其本身和鄰域內(nèi)的其他像素值經(jīng)過加權(quán)平均后得到霍弹。高斯濾波的具體操作是:用一個模板(或稱卷積、掩模)掃描圖像中的每一個像素娃弓,用模板確定的鄰域內(nèi)像素的加權(quán)平均灰度值去替代模板中心像素點的值典格。從數(shù)學(xué)的角度來看,圖像的高斯模糊過程就是圖像與正態(tài)分布做卷積台丛。由于正態(tài)分布又叫作高斯分布耍缴,所以這項技術(shù)就叫作高斯模糊。圖像與圓形方框模糊做卷積將會生成更加精確的焦外成像效果挽霉。由于高斯函數(shù)的傅立葉變換是另外一個高斯函數(shù)防嗡,所以高斯模糊對于圖像來說就是一個低通濾波操作。高斯濾波器是一類根據(jù)高斯函數(shù)的形狀來選擇權(quán)值的線性平滑濾波器侠坎。高斯平滑濾波器對于抑制服從正態(tài)分布的噪聲非常有效蚁趁。一維零均值高斯函數(shù)為:G(x)=exp(-x2/2sigma2)。其中实胸,高斯分布參數(shù)Sigma決定了高斯函數(shù)的寬度他嫡。對于圖像處理來說,常用二維零均值離散高斯函數(shù)作平滑濾波器庐完。
/**
* 高斯濾波
* 第一個參數(shù):傳入的圖片
* 第二個參數(shù):傳出的圖片
* 第三個參數(shù):核心(必須是正數(shù)和奇數(shù))
* 第四個參數(shù):sigmaX代表高斯函數(shù)在x方向的標(biāo)準(zhǔn)偏差
* 第五個參數(shù):sigmaY代表高斯函數(shù)在Y方向的標(biāo)準(zhǔn)偏差钢属,有默認(rèn)值為0
* 第六個參數(shù):邊界模式,使用默認(rèn)值BORDER_DEFAULT
*/
CV_EXPORTS_W void GaussianBlur( InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY = 0, int borderType = BORDER_DEFAULT );
extern "C"
JNIEXPORT jintArray JNICALL
Java_com_xy_opencv_ndk_1opencv002_MainActivity_blurImage(JNIEnv *env, jclass type,jintArray pixels_, jint w, jint h) {
jint *pixels = env->GetIntArrayElements(pixels_, NULL);
Mat img(h, w, CV_8UC4, pixels);
GaussianBlur(img,img,Size(31,31),0);
int size = w * h;
jintArray array = env->NewIntArray(size);
env->SetIntArrayRegion(array, 0, size, pixels);
env->ReleaseIntArrayElements(pixels_, pixels, 0);
return array;
}
中值濾波
中值濾波很簡單门躯,一種非線性濾波操作淆党,就是孔徑范圍內(nèi)的所有像素進(jìn)行排序,然后取中位數(shù)讶凉,賦值給核心染乌。
/**
* 中值濾波,孔徑范圍內(nèi)的所有像素進(jìn)行排序,然后取中位數(shù)缀遍,賦值給核心慕匠。
* 第一個參數(shù):傳入的圖片
* 第二個參數(shù):傳出的圖片
* 第三個參數(shù):孔徑的線性尺寸,必須是大于1的奇數(shù)
*/
CV_EXPORTS_W void medianBlur( InputArray src, OutputArray dst, int ksize );
extern "C"
JNIEXPORT jintArray JNICALL
Java_com_xy_opencv_ndk_1opencv002_MainActivity_blurImage(JNIEnv *env, jclass type,jintArray pixels_, jint w, jint h) {
jint *pixels = env->GetIntArrayElements(pixels_, NULL);
Mat img(h, w, CV_8UC4, pixels);
medianBlur(img,img,31);
int size = w * h;
jintArray array = env->NewIntArray(size);
env->SetIntArrayRegion(array, 0, size, pixels);
env->ReleaseIntArrayElements(pixels_, pixels, 0);
return array;
}
雙邊濾波
雙邊濾波(Bilateral filter)是一種非線性的濾波方法域醇,是結(jié)合圖像的空間鄰近度和像素值相似度的一種折中處理台谊,同時考慮空域信息和灰度相似性,達(dá)到保邊去噪的目的譬挚。具有簡單锅铅、非迭代、局部的特點 减宣。雙邊濾波器的好處是可以做邊緣保存(edge preserving)盐须,一般過去用的維納濾波或者高斯濾波去降噪,都會較明顯地模糊邊緣漆腌,對于高頻細(xì)節(jié)的保護(hù)效果并不明顯贼邓。雙邊濾波器顧名思義比高斯濾波多了一個高斯方差sigma-d阶冈,它是基于空間分布的高斯濾波函數(shù),所以在邊緣附近塑径,離的較遠(yuǎn)的像素不會太多影響到邊緣上的像素值女坑,這樣就保證了邊緣附近像素值的保存。但是由于保存了過多的高頻信息统舀,對于彩色圖像里的高頻噪聲匆骗,雙邊濾波器不能夠干凈的濾掉,只能夠?qū)τ诘皖l信息進(jìn)行較好的濾波誉简。
/**
* 雙邊濾波
* 第一個參數(shù):傳入的圖片(必須是CV_8UC1或者CV_8UC3)
* 第二個參數(shù):傳出的圖片
* 第三個參數(shù):每個像素領(lǐng)域的直徑
* 第四個參數(shù):sigmaColor碉就,這個值越大,該像素領(lǐng)域內(nèi)會有更廣的顏色被混合到一起
* 第五個參數(shù):sigmaSpace闷串,這個值越大瓮钥,越遠(yuǎn)的像素會互相影響,第三個參數(shù)大于0時烹吵,領(lǐng)域的大小和這個值無關(guān)骏庸,否則成正比
* 第六個參數(shù):使用默認(rèn)值BORDER_DEFAULT
*/
CV_EXPORTS_W void bilateralFilter( InputArray src, OutputArray dst, int d,
double sigmaColor, double sigmaSpace, int borderType = BORDER_DEFAULT );
extern "C"
JNIEXPORT jintArray JNICALL
Java_com_xy_opencv_ndk_1opencv002_MainActivity_blurImage(JNIEnv *env, jclass type,jintArray pixels_, jint w, jint h) {
jint *pixels = env->GetIntArrayElements(pixels_, NULL);
Mat img(h, w, CV_8UC3, pixels);
Mat out(h,w,CV_8UC4);
bilateralFilter(img,out,25,25*2,25/2);
int size = w * h;
jint *re = (jint *) out.data;
jintArray array = env->NewIntArray(size);
env->SetIntArrayRegion(array, 0, size, re);
env->ReleaseIntArrayElements(pixels_, pixels, 0);
return array;
}
本文章著作版權(quán)所屬:微笑面對,請關(guān)注我的CSDN博客:博客地址