1. 圖像噪聲
圖像降噪(Image Denoising)是指從圖像中去除噪聲的過程,目的是提高圖像質(zhì)量,增強(qiáng)圖像的視覺效果。
圖像噪聲是指圖像中不希望出現(xiàn)的隨機(jī)亮度或顏色變化,通常會降低圖像的清晰度和可辨識度,以及會降低圖像的質(zhì)量并使圖像分析和理解更加困難。
圖像噪聲主要有以下幾個(gè)原因來產(chǎn)生的:
- 光線不足:光線不足會導(dǎo)致光子噪聲增加,從而降低圖像的信噪比。
- 電子元器件的熱噪聲:電子元器件在工作時(shí)會產(chǎn)生熱噪聲,這種噪聲會影響圖像的質(zhì)量。
- 電路噪聲:電路中的電磁干擾也會導(dǎo)致圖像噪聲的產(chǎn)生。
- 圖像傳輸過程中的錯(cuò)誤:圖像在傳輸過程中可能會受到各種干擾,從而導(dǎo)致圖像噪聲的產(chǎn)生。
根據(jù)噪聲的統(tǒng)計(jì)特性來分類,可以將圖像噪聲分為以下幾類:
- 椒鹽噪聲:圖像中隨機(jī)出現(xiàn)黑白像素的噪聲。
- 高斯噪聲:最常見的噪聲類型,其概率密度函數(shù)服從高斯分布。
- 泊松噪聲:光子噪聲的一種類型,其概率密度函數(shù)服從泊松分布。
- 斑點(diǎn)噪聲:由圖像傳感器壞點(diǎn)或污點(diǎn)引起的噪聲。
下面的例子,分別展示了在圖像中添加椒鹽噪聲、高斯噪聲、泊松噪聲和斑點(diǎn)噪聲。
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <random>
using namespace std;
using namespace cv;
void addSaltNoise(Mat &src, int num, Mat &dst)
{
dst = src.clone();
// 隨機(jī)數(shù)產(chǎn)生器
std::random_device rd; //種子
std::mt19937 gen(rd()); // 隨機(jī)數(shù)引擎
auto rows = src.rows; // 行數(shù)
auto cols = src.cols * src.channels();
for (int i = 0; i < num; i++)
{
auto row = static_cast<int>(gen() % rows);
auto col = static_cast<int>(gen() % cols);
auto p = dst.ptr<uchar>(row);
p[col++] = 255;
p[col++] = 255;
p[col] = 255;
}
}
void addGaussianNoise(Mat &src, int mu, int sigma, Mat &dst)
{
dst = src.clone();
// 產(chǎn)生高斯分布的隨機(jī)數(shù)發(fā)生器
std::random_device rd;
std::mt19937 gen(rd());
std::normal_distribution<> d(mu, sigma);
auto rows = src.rows; // 行數(shù)
auto cols = src.cols * src.channels(); // 列數(shù)
for (int i = 0; i < rows; i++)
{
auto p = dst.ptr<uchar>(i); // 取得行首指針
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;
}
}
}
typedef cv::Point3_<uint8_t> Pixel;
void addPoissonNoise(const Mat& src, double lambda, Mat& dst) {
dst = src.clone();
// 產(chǎn)生泊松分布的隨機(jī)數(shù)生成器
std::random_device rd;
std::mt19937 gen(rd());
std::poisson_distribution<int> distribution(lambda);
dst.forEach<Pixel>([&](Pixel &p, const int * position) -> void {
int row = position[0];
int col = position[1];
int count = distribution(gen);
dst.at<Vec3b>(row, col) = dst.at<Vec3b>(row, col) + Vec3b(count, count, count);
});
}
void addSpeckleNoise(Mat& image, double scale, Mat &dst) {
dst = image.clone();
RNG rng;
dst.forEach<Pixel>([&](Pixel &p, const int * position) -> void {
int row = position[0];
int col = position[1];
double random_value = rng.uniform(0.0, 1.0);
double noise_intensity = random_value * scale;
dst.at<Vec3b>(row, col) = dst.at<Vec3b>(row, col) + Vec3b(noise_intensity * 255, noise_intensity * 255, noise_intensity * 255);
});
}
int main() {
Mat src = imread(".../girl.jpg");
imshow("src", src);
Mat dst1;
addSaltNoise(src,100000,dst1);
imshow("addSaltNoise", dst1);
Mat dst2;
addGaussianNoise(src, 0, 50,dst2);
imshow("addGaussianNoise", dst2);
Mat dst3;
addPoissonNoise(src, 60, dst3);
imshow("addPoissonNoise", dst3);
Mat dst4;
addSpeckleNoise(src,0.5,dst4);
imshow("addSpeckleNoise", dst4);
waitKey(0);
return 0;
}
2. 圖像降噪方法
傳統(tǒng)的圖像處理是基于濾波器的方式進(jìn)行降噪,比如使用空域?yàn)V波、頻域?yàn)V波、非局部均值濾波等等,還有使用形態(tài)學(xué)降噪,當(dāng)然也可以深度學(xué)習(xí)的方式進(jìn)行降噪。
本文介紹兩種空域?yàn)V波的方式進(jìn)行降噪。
2.1 中值濾波
中值濾波是一種非線性濾波器,它通過對圖像中的像素值進(jìn)行排序并取中間值來進(jìn)行濾波處理。
中值濾波的特性:
- 對于圖像中的每個(gè)像素,選取其周圍一定區(qū)域內(nèi)的所有像素值,并對其進(jìn)行排序。
- 將排序后的像素值的中位數(shù)賦予該像素。
中值濾波的優(yōu)點(diǎn):
- 能夠有效去除椒鹽噪聲和脈沖噪聲,對圖像中的孤立噪聲點(diǎn)具有較強(qiáng)的抑制能力。
- 能夠較好地保留圖像的邊緣和細(xì)節(jié)信息,不會造成圖像模糊。
中值濾波的缺點(diǎn):
- 對高斯噪聲的去除效果不佳。
- 計(jì)算量相對較大,特別是對于大尺寸圖像而言。
2.2 高斯濾波
高斯濾波是一種線性平滑濾波器,它利用高斯函數(shù)對圖像進(jìn)行加權(quán)平均,可以有效地去除高斯噪聲,同時(shí)平滑圖像。
高斯濾波的優(yōu)點(diǎn):
- 高斯濾波具有良好的平滑效果,能夠有效地抑制圖像中的噪聲。
- 高斯濾波是一種線性濾波器,具有可分離性,可以提高計(jì)算效率。
- 高斯濾波在頻域上具有低通濾波器的特性,能夠去除圖像中的高頻噪聲。
高斯濾波的缺點(diǎn):
- 高斯濾波會造成圖像細(xì)節(jié)丟失,降低圖像銳度。
- 高斯濾波對椒鹽噪聲等非平滑噪聲的去除效果不佳。
高斯濾波以使用兩種方法實(shí)現(xiàn):一種是離散化窗口滑窗卷積,另一種方法是通過傅里葉變化。最常見的就是滑窗卷積實(shí)現(xiàn)。
先來回顧一下一維高斯函數(shù):
其中,是 x 的均值,
是 x 的方差。x 是卷積核內(nèi)任意一點(diǎn)的坐標(biāo),
是卷積核中心的坐標(biāo)。當(dāng)
= 0 時(shí),
由于圖像是二維的,二維的高斯函數(shù)則是對 x、y 兩個(gè)方向的一維高斯函數(shù)的乘積:
當(dāng)時(shí),就是我們比較熟悉的二維高斯函數(shù)公式:
常用的高斯模板有如下幾種形式,它們是基于高斯函數(shù)計(jì)算出來的。
高斯濾波具有以下性質(zhì):
- 線性: 高斯濾波器是線性的,這意味著它可以與其他濾波器組合使用。例如,可以先使用高斯濾波器去除噪聲,然后再使用邊緣檢測濾波器檢測邊緣。
- 可分離性: 高斯濾波器可以分離為兩個(gè)一維濾波器,即水平方向和垂直方向的濾波器。這使得高斯濾波器的計(jì)算效率更高。
- 傅里葉變換: 高斯濾波器的傅里葉變換是一個(gè)低通濾波器,這意味著它可以抑制圖像中的高頻成分,而保留低頻成分。
- 旋轉(zhuǎn)不變性: 高斯濾波器在各個(gè)方向上具有相同的平滑效果,這意味著它不會改變圖像的旋轉(zhuǎn)方向。
- 尺度不變性: 高斯濾波器的尺度可以通過調(diào)整高斯函數(shù)的標(biāo)準(zhǔn)差來控制。標(biāo)準(zhǔn)差越大,濾波器的平滑效果越強(qiáng)。
下面的例子,分別使用中值濾波和高斯濾波消除椒鹽噪聲和高斯噪聲。
int main() {
Mat src = imread(".../girl.jpg");
imshow("src", src);
Mat result;
Mat dst1;
addSaltNoise(src,100000,dst1);
imshow("addSaltNoise", dst1);
int a = 7;
medianBlur(dst1, result,a);
imshow("removeSaltNoise", result);
Mat dst2;
addGaussianNoise(src, 0, 50,dst2);
imshow("addGaussianNoise", dst2);
GaussianBlur(dst2, result, Size(15, 15), 0, 0);
imshow("removeGaussianNoise", result);
waitKey(0);
return 0;
}
3. 總結(jié)
圖像降噪可以提高圖像質(zhì)量、提高圖像分析和處理的準(zhǔn)確性、提高圖像壓縮效率以及擴(kuò)展圖像應(yīng)用范圍。
本文介紹了兩種簡單的降噪算法。中值濾波適用于去除椒鹽噪聲和脈沖噪聲,常用于圖像修復(fù)和增強(qiáng)。高斯濾波適用于去除高斯噪聲、平滑圖像,常用于圖像預(yù)處理和模糊處理。