android使用OpenCV之圖像濾波處理

圖像濾波:
儘量保留圖像細節特徵的條件下對目標圖像的噪聲進行抑制和平滑處理,是圖像預處理中不可缺少的操作,其處理效果的好壞將直接影響到後續圖像處理和分析的有效性和可靠性。
濾波器
低通濾波器(允許低頻通過),高通濾波器,帶通濾波器,帶阻濾波器,全通濾波器,陷波濾波器。
我在這兒主要介紹OpenCV中所提供的濾波操作,線性濾波與非線性濾波
opencv中線性濾波操作有:方框濾波、均值濾波和高斯濾波。非線性濾波操作有:中值濾波和雙邊濾波。

方框濾波

講到方框濾波,我們不能不提及的是線性鄰域濾波算子,即用不同的權重去結合一個小鄰域內的像素,來得到應有的處理效果。鄰域濾波(卷積):左邊圖像與中間圖像的卷積產生右邊圖像。目標圖像中綠色標記的像素是利用原圖像中藍色標記的像素計算得到的。線性濾波處理的輸出像素值g(i,j)是輸入像素值f(j+k,j+l)的加權和 ,其中加權和稱之爲“核”,濾波器的加權係數,即濾波器的“濾波係數”。

這裏寫圖片描述

這裏寫圖片描述

  /**
      * opencv中方框濾波函數
      * 第一個參數:輸入的圖片
      * 第二個參數:輸出的圖片
      * 第三個參數:圖片的深度(存儲每個像素所用的位數)一般情況使用-1也就是原有的圖像深度
      * 第四個參數:核心的大小
      * 第五個參數:錨點的位置,就是我們要進行處理的點,默認值(-1,-1)表示錨點在覈的中心
      * 第六個參數:normalize默認值爲true,表示內核是否被其區域歸一化(normalized)了,當normalize=true的時候,方框濾波就變成了我們熟悉的均值濾波。也就是說,均值濾波是方框濾波歸一化(normalized)後的特殊情況。其中,歸一化就是把要處理的量都縮放到一個範圍內,比如(0,1),以便統一處理和直觀量化。而非歸一化(Unnormalized)的方框濾波用於計算每個像素鄰域內的積分特性,比如密集光流算法(dense optical flow algorithms)中用到的圖像倒數的協方差矩陣(covariance matrices of image derivatives)如果我們要在可變的窗口中計算像素總和,可以使用integral()函數
      * 第七個參數:邊界模式,默認值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;
    }

這裏寫圖片描述

均值濾波
方框濾波歸一化之後就是均值濾波。也就是輸出圖像的每一個像素是核窗口內輸入圖像對應像素的像素平均值( 所有像素加權係數相等)。

 /**
 * 均值濾波(歸一化之後又進行了方框濾波)
 * 第一個參數:輸入的圖片
 * 第二個參數:輸出的圖片
 * 第三個參數:核心的大小
 * 第四個參數:錨點的位置,就是我們要進行處理的點,默認值(-1,-1)表示錨點在覈的中心
 * 第五個參數:邊界模式,默認值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;
    }

引用塊內容

高斯濾波

高斯濾波是一種線性平滑濾波,適用於消除高斯噪聲,廣泛應用於圖像處理的減噪過程。通俗的講,高斯濾波就是對整幅圖像進行加權平均的過程,每一個像素點的值,都由其本身和鄰域內的其他像素值經過加權平均後得到。高斯濾波的具體操作是:用一個模板(或稱卷積、掩模)掃描圖像中的每一個像素,用模板確定的鄰域內像素的加權平均灰度值去替代模板中心像素點的值。從數學的角度來看,圖像的高斯模糊過程就是圖像與正態分佈做卷積。由於正態分佈又叫作高斯分佈,所以這項技術就叫作高斯模糊。圖像與圓形方框模糊做卷積將會生成更加精確的焦外成像效果。由於高斯函數的傅立葉變換是另外一個高斯函數,所以高斯模糊對於圖像來說就是一個低通濾波操作。高斯濾波器是一類根據高斯函數的形狀來選擇權值的線性平滑濾波器。高斯平滑濾波器對於抑制服從正態分佈的噪聲非常有效。一維零均值高斯函數爲:G(x)=exp(-x^2/2sigma^2)。其中,高斯分佈參數Sigma決定了高斯函數的寬度。對於圖像處理來說,常用二維零均值離散高斯函數作平滑濾波器。這裏寫圖片描述

   /**
     * 高斯濾波
     * 第一個參數:傳入的圖片
     * 第二個參數:傳出的圖片
     * 第三個參數:核心(必須是正數和奇數)
     * 第四個參數:sigmaX代表高斯函數在x方向的標準偏差
     * 第五個參數:sigmaY代表高斯函數在Y方向的標準偏差,有默認值爲0
     * 第六個參數:邊界模式,使用默認值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;
    }

中值濾波

中值濾波很簡單,一種非線性濾波操作,就是孔徑範圍內的所有像素進行排序,然後取中位數,賦值給核心。

  /**
     * 中值濾波,孔徑範圍內的所有像素進行排序,然後取中位數,賦值給核心。
     * 第一個參數:傳入的圖片
     * 第二個參數:傳出的圖片
     * 第三個參數:孔徑的線性尺寸,必須是大於1的奇數
     */
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)是一種非線性的濾波方法,是結合圖像的空間鄰近度和像素值相似度的一種折中處理,同時考慮空域信息和灰度相似性,達到保邊去噪的目的。具有簡單、非迭代、局部的特點 。雙邊濾波器的好處是可以做邊緣保存(edge preserving),一般過去用的維納濾波或者高斯濾波去降噪,都會較明顯地模糊邊緣,對於高頻細節的保護效果並不明顯。雙邊濾波器顧名思義比高斯濾波多了一個高斯方差sigma-d,它是基於空間分佈的高斯濾波函數,所以在邊緣附近,離的較遠的像素不會太多影響到邊緣上的像素值,這樣就保證了邊緣附近像素值的保存。但是由於保存了過多的高頻信息,對於彩色圖像裏的高頻噪聲,雙邊濾波器不能夠乾淨的濾掉,只能夠對於低頻信息進行較好的濾波。

 /**
   * 雙邊濾波
   * 第一個參數:傳入的圖片(必須是CV_8UC1或者CV_8UC3)
   * 第二個參數:傳出的圖片
   * 第三個參數:每個像素領域的直徑
   * 第四個參數:sigmaColor,這個值越大,該像素領域內會有更廣的顏色被混合到一起
   * 第五個參數:sigmaSpace,這個值越大,越遠的像素會互相影響,第三個參數大於0時,領域的大小和這個值無關,否則成正比
   * 第六個參數:使用默認值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;
    }

這裏寫圖片描述
本文章著作版權所屬:微笑面對,請關注我的CSDN博客:博客地址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章