openCV中值濾波和均值濾波的代碼實(shí)現(xiàn)
在開始我們今天的博客之前,我們需要先了解一下什么是濾波:
首先我們看一下圖像濾波的概念。圖像濾波,即在盡量保留圖像細(xì)節(jié)特征的條件下對(duì)目標(biāo)圖像的噪聲進(jìn)行抑制,是圖像預(yù)處理中不可缺少的操作,其處理效果的好壞將直接影響到后續(xù)圖像處理和分析的有效性和可靠性。
下圖左邊是原圖右邊是噪聲圖:


消除圖像中的噪聲成分叫作圖像的平滑化或?yàn)V波操作。信號(hào)或圖像的能量大部分集中在幅度譜的低頻和中頻段是很常見的,而在較高頻段,感興趣的信息經(jīng)常被噪聲淹沒(méi)。因此一個(gè)能降低高頻成分幅度的濾波器就能夠減弱噪聲的影響。
圖像濾波的目的有兩個(gè):一是抽出對(duì)象的特征作為圖像識(shí)別的特征模式;另一個(gè)是為適應(yīng)圖像處理的要求,消除圖像數(shù)字化時(shí)所混入的噪聲。
而對(duì)濾波處理的要求也有兩條:一是不能損壞圖像的輪廓及邊緣等重要信息;二是使圖像清晰視覺效果好。
平滑濾波是低頻增強(qiáng)的空間域?yàn)V波技術(shù)。它的目的有兩類:一類是模糊;另一類是消除噪音。
空間域的平滑濾波一般采用簡(jiǎn)單平均法進(jìn)行,就是求鄰近像元點(diǎn)的平均亮度值。鄰域的大小與平滑的效果直接相關(guān),鄰域越大平滑的效果越好,但鄰域過(guò)大,平滑會(huì)使邊緣信息損失的越大,從而使輸出的圖像變得模糊,因此需合理選擇鄰域的大小。
關(guān)于濾波器,一種形象的比喻法是:我們可以把濾波器想象成一個(gè)包含加權(quán)系數(shù)的窗口,當(dāng)使用這個(gè)濾波器平滑處理圖像時(shí),就把這個(gè)窗口放到圖像之上,透過(guò)這個(gè)窗口來(lái)看我們得到的圖像。
舉一個(gè)濾波在我們生活中的應(yīng)用:美顏的磨皮功能。如果將我們臉上坑坑洼洼比作是噪聲的話,那么濾波算法就是來(lái)取出這些噪聲,使我們自拍的皮膚看起來(lái)很光滑。
這篇博文會(huì)介紹中值濾波以及均值濾波兩種算法
一.均值濾波
圖片中一個(gè)方塊區(qū)域(一般為3*3)內(nèi),中心點(diǎn)的像素為全部點(diǎn)像素值的平均值。均值濾波就是對(duì)于整張圖片進(jìn)行以上操作。
我們可以看下圖的矩陣進(jìn)行理解


缺陷:均值濾波本身存在著固有的缺陷,即它不能很好地保護(hù)圖像細(xì)節(jié),在圖像去噪的同時(shí)也破壞了圖像的細(xì)節(jié)部分,從而使圖像變得模糊,不能很好地去除噪聲點(diǎn)。特別是椒鹽噪聲
實(shí)現(xiàn)代碼:
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include<ctime>
using namespace cv;
using namespace std;
//均值濾波
void AverFiltering(const Mat &src,Mat &dst) {
if (!src.data) return;
//at訪問(wèn)像素點(diǎn)
for (int i = 1; i<src.rows; ++i)
for (int j = 1; j < src.cols; ++j) {
if ((i - 1 >= 0) && (j - 1) >= 0 && (i + 1)<src.rows && (j + 1)<src.cols) {//邊緣不進(jìn)行處理
dst.at<Vec3b>(i, j)[0] = (src.at<Vec3b>(i, j)[0] + src.at<Vec3b>(i - 1, j - 1)[0] + src.at<Vec3b>(i - 1, j)[0] + src.at<Vec3b>(i, j - 1)[0] +
src.at<Vec3b>(i - 1, j + 1)[0] + src.at<Vec3b>(i + 1, j - 1)[0] + src.at<Vec3b>(i + 1, j + 1)[0] + src.at<Vec3b>(i, j + 1)[0] +
src.at<Vec3b>(i + 1, j)[0]) / 9;
dst.at<Vec3b>(i, j)[1] = (src.at<Vec3b>(i, j)[1] + src.at<Vec3b>(i - 1, j - 1)[1] + src.at<Vec3b>(i - 1, j)[1] + src.at<Vec3b>(i, j - 1)[1] +
src.at<Vec3b>(i - 1, j + 1)[1] + src.at<Vec3b>(i + 1, j - 1)[1] + src.at<Vec3b>(i + 1, j + 1)[1] + src.at<Vec3b>(i, j + 1)[1] +
src.at<Vec3b>(i + 1, j)[1]) / 9;
dst.at<Vec3b>(i, j)[2] = (src.at<Vec3b>(i, j)[2] + src.at<Vec3b>(i - 1, j - 1)[2] + src.at<Vec3b>(i - 1, j)[2] + src.at<Vec3b>(i, j - 1)[2] +
src.at<Vec3b>(i - 1, j + 1)[2] + src.at<Vec3b>(i + 1, j - 1)[2] + src.at<Vec3b>(i + 1, j + 1)[2] + src.at<Vec3b>(i, j + 1)[2] +
src.at<Vec3b>(i + 1, j)[2]) / 9;
}
else {//邊緣賦值
dst.at<Vec3b>(i, j)[0] = src.at<Vec3b>(i, j)[0];
dst.at<Vec3b>(i, j)[1] = src.at<Vec3b>(i, j)[1];
dst.at<Vec3b>(i, j)[2] = src.at<Vec3b>(i, j)[2];
}
}
}
//圖像椒鹽化
void salt(Mat &image, int num) {
if (!image.data) return;//防止傳入空?qǐng)D
int i, j;
srand(time(NULL));
for (int x = 0; x < num; ++x) {
i = rand() % image.rows;
j = rand() % image.cols;
image.at<Vec3b>(i, j)[0] = 255;
image.at<Vec3b>(i, j)[1] = 255;
image.at<Vec3b>(i, j)[2] = 255;
}
}
void main() {
Mat image = imread("路飛.jpg");
Mat Salt_Image;
image.copyTo(Salt_Image);
salt(Salt_Image, 3000);
Mat image1(image.size(), image.type());
Mat image2;
AverFiltering(Salt_Image, image1);
blur(Salt_Image, image2, Size(3, 3));//openCV庫(kù)自帶的均值濾波函數(shù)
imshow("原圖", image);
imshow("自定義均值濾波", image1);
imshow("openCV自帶的均值濾波", image2);
waitKey();
}效果圖:


可以看到圖片變模糊而且噪聲并沒(méi)有很有效的去除,該算法只是模糊化了圖片而已。
二.中值濾波
首先,我們復(fù)習(xí)中值。在一連串?dāng)?shù)字{1,4,6,8,9}中,數(shù)字6就是這串?dāng)?shù)字的中值。由此我們可以應(yīng)用到圖像處理中。依然我們?cè)趫D像中去3*3的矩陣,里面有9個(gè)像素點(diǎn),我們將9個(gè)像素進(jìn)行排序,最后將這個(gè)矩陣的中心點(diǎn)賦值為這九個(gè)像素的中值。


代碼:
//求九個(gè)數(shù)的中值
uchar Median(uchar n1, uchar n2, uchar n3, uchar n4, uchar n5,
uchar n6, uchar n7, uchar n8, uchar n9) {
uchar arr[9];
arr[0] = n1;
arr[1] = n2;
arr[2] = n3;
arr[3] = n4;
arr[4] = n5;
arr[5] = n6;
arr[6] = n7;
arr[7] = n8;
arr[8] = n9;
for (int gap = 9 / 2; gap > 0; gap /= 2)//希爾排序
for (int i = gap; i < 9; ++i)
for (int j = i - gap; j >= 0 && arr[j] > arr[j + gap]; j -= gap)
swap(arr[j], arr[j + gap]);
return arr[4];//返回中值
}
//圖像椒鹽化
void salt(Mat &image, int num) {
if (!image.data) return;//防止傳入空?qǐng)D
int i, j;
srand(time(NULL));
for (int x = 0; x < num; ++x) {
i = rand() % image.rows;
j = rand() % image.cols;
image.at<Vec3b>(i, j)[0] = 255;
image.at<Vec3b>(i, j)[1] = 255;
image.at<Vec3b>(i, j)[2] = 255;
}
}
//中值濾波函數(shù)
void MedianFlitering(const Mat &src, Mat &dst) {
if (!src.data)return;
Mat _dst(src.size(), src.type());
for(int i=0;i<src.rows;++i)
for (int j=0; j < src.cols; ++j) {
if ((i - 1) > 0 && (i + 1) < src.rows && (j - 1) > 0 && (j + 1) < src.cols) {
_dst.at<Vec3b>(i, j)[0] = Median(src.at<Vec3b>(i, j)[0], src.at<Vec3b>(i + 1, j + 1)[0],
src.at<Vec3b>(i + 1, j)[0], src.at<Vec3b>(i, j + 1)[0], src.at<Vec3b>(i + 1, j - 1)[0],
src.at<Vec3b>(i - 1, j + 1)[0], src.at<Vec3b>(i - 1, j)[0], src.at<Vec3b>(i, j - 1)[0],
src.at<Vec3b>(i - 1, j - 1)[0]);
_dst.at<Vec3b>(i, j)[1] = Median(src.at<Vec3b>(i, j)[1], src.at<Vec3b>(i + 1, j + 1)[1],
src.at<Vec3b>(i + 1, j)[1], src.at<Vec3b>(i, j + 1)[1], src.at<Vec3b>(i + 1, j - 1)[1],
src.at<Vec3b>(i - 1, j + 1)[1], src.at<Vec3b>(i - 1, j)[1], src.at<Vec3b>(i, j - 1)[1],
src.at<Vec3b>(i - 1, j - 1)[1]);
_dst.at<Vec3b>(i, j)[2] = Median(src.at<Vec3b>(i, j)[2], src.at<Vec3b>(i + 1, j + 1)[2],
src.at<Vec3b>(i + 1, j)[2], src.at<Vec3b>(i, j + 1)[2], src.at<Vec3b>(i + 1, j - 1)[2],
src.at<Vec3b>(i - 1, j + 1)[2], src.at<Vec3b>(i - 1, j)[2], src.at<Vec3b>(i, j - 1)[2],
src.at<Vec3b>(i - 1, j - 1)[2]);
}
else
_dst.at<Vec3b>(i, j) = src.at<Vec3b>(i, j);
}
_dst.copyTo(dst);//拷貝
}
void main() {
Mat image = imread("路飛.jpg");
Mat Salt_Image;
image.copyTo(Salt_Image);
salt(Salt_Image, 3000);
Mat image3, image4;
MedianFlitering(Salt_Image, image3);
medianBlur(Salt_Image, image4, 3);
imshow("自定義中值濾波處理后", image3);
imshow("openCV自帶的中值濾波", image4);
waitKey();
}效果圖:


可以看到,椒鹽噪聲很好的被平滑了,而且也沒(méi)均值那樣模糊化太過(guò)于嚴(yán)重。
到此這篇關(guān)于openCV中值濾波和均值濾波的代碼實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)openCV中值濾波和均值濾波內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Anaconda安裝tensorflow報(bào)錯(cuò)問(wèn)題解決方法
這篇文章主要介紹了Anaconda安裝tensorflow報(bào)錯(cuò)問(wèn)題解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
Python技巧之實(shí)現(xiàn)批量統(tǒng)一圖片格式和尺寸
大家在工作的時(shí)候基本都會(huì)接觸到很多的圖片,有時(shí)為了不同的工作需求需要修改圖片的尺寸或者大小。本文為大家整理了Python批量轉(zhuǎn)換圖片格式和統(tǒng)一圖片尺寸,希望對(duì)大家有所幫助2023-05-05
python 實(shí)現(xiàn)客戶端與服務(wù)端的通信
這篇文章主要介紹了python 實(shí)現(xiàn)客戶端與服務(wù)端的通信的方法,幫助大家更好的理解和使用python,感興趣的朋友可以了解下2020-12-12
python matplotlib坐標(biāo)軸設(shè)置的方法
本篇文章主要介紹了python matplotlib坐標(biāo)軸設(shè)置的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12
Pycharm配置遠(yuǎn)程調(diào)試的方法步驟
這篇文章主要介紹了Pycharm配置遠(yuǎn)程調(diào)試的方法步驟,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-12-12
Tensorflow全局設(shè)置可見GPU編號(hào)操作
這篇文章主要介紹了Tensorflow全局設(shè)置可見GPU編號(hào)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-06-06
DRF之請(qǐng)求與響應(yīng)的實(shí)現(xiàn)
本文主要介紹了DRF請(qǐng)求與響應(yīng)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-07-07

