【OpenCV】給圖像加入噪聲


圖像噪聲使圖像在獲取或是傳輸過程中收到隨機信號干擾,妨礙人們對圖像理解及分析處理的信號。非常多時候將圖像噪聲看做多維隨機過程,因而描寫敘述噪聲的方法全然能夠借用隨機過程的描寫敘述,也就是使用隨機過程的描寫敘述,也就是用它的高綠分布函數和概率密度分布函數。圖像噪聲的產生來自圖像獲取中的環境條件和傳感元器件自身的質量,圖像在傳輸過程中產生圖像噪聲的主要因素是所用的傳輸信道收到了噪聲的污染。

以下簡介兩種圖像噪聲。即椒鹽噪聲和高斯噪聲。

1.椒鹽噪聲

椒鹽噪聲也稱為脈沖噪聲,是圖像中常常見到的一種噪聲,它是一種隨機出現的白點或者黑點,可能是亮的區域有黑色像素或是在暗的區域有白色像素(或是兩者皆有)。

鹽和胡椒噪聲的成因可能是影像訊號受到突如其來的強烈干擾而產生、類比數位轉換器或位元傳輸錯誤等。比如失效的感應器導致像素值為最小值。飽和的感應器導致像素值為最大值。

圖像模擬加入椒鹽噪聲是通過隨機獲取像素點並設置為高亮度點和低灰度點來實現的

圖像加入椒鹽噪聲的程序例如以下:

//利用程序給原圖像添加椒鹽噪聲
//圖象模擬加入椒鹽噪聲是通過隨機獲取像素點斌那個設置為高亮度點來實現的

#include <cstdlib>
#include <iostream>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>

using namespace cv;
using namespace std;

Mat addSaltNoise(const Mat srcImage, int n);


int main()
{
	Mat srcImage = imread("2345.jpg");
	if (!srcImage.data)
	{
		cout << "讀入圖像有誤!" << endl;
		system("pause");
		return -1;
	}
	imshow("原圖像", srcImage);
	Mat dstImage = addSaltNoise(srcImage, 3000);
	imshow("加入椒鹽噪聲的圖像", dstImage);
	//存儲圖像
	imwrite("salt_pepper_Image.jpg", dstImage);
	waitKey();
	return 0;
}

Mat addSaltNoise(const Mat srcImage, int n)
{
	Mat dstImage = srcImage.clone();
	for (int k = 0; k < n; k++)
	{
		//隨機取值行列
		int i = rand() % dstImage.rows;
		int j = rand() % dstImage.cols;
		//圖像通道判定
		if (dstImage.channels() == 1)
		{
			dstImage.at<uchar>(i, j) = 255;		//鹽噪聲
		}
		else
		{
			dstImage.at<Vec3b>(i, j)[0] = 255;
			dstImage.at<Vec3b>(i, j)[1] = 255;
			dstImage.at<Vec3b>(i, j)[2] = 255;
		}
	}
	for (int k = 0; k < n; k++)
	{
		//隨機取值行列
		int i = rand() % dstImage.rows;
		int j = rand() % dstImage.cols;
		//圖像通道判定
		if (dstImage.channels() == 1)
		{
			dstImage.at<uchar>(i, j) = 0;		//椒噪聲
		}
		else
		{
			dstImage.at<Vec3b>(i, j)[0] = 0;
			dstImage.at<Vec3b>(i, j)[1] = 0;
			dstImage.at<Vec3b>(i, j)[2] = 0;
		}
	}
	return dstImage;
}

運行程序后,輸出的效果例如以下:



2.高斯噪聲

高斯噪聲是指高綠密度函數服從高斯分布的一類噪聲。特別的,假設一個噪聲,它的幅度分布服從高斯分布,而它的功率譜密度有事均勻分布的,則稱這個噪聲為高斯白噪聲。

高斯白噪聲二階矩不相關。一階矩為常數,是指先后信號在時間上的相關性。高斯噪聲包含熱噪聲和三里噪聲。

高斯噪聲萬有由它的事變平均值和兩瞬時的協方差函數來確定,若噪聲是平穩的。則平均值與時間無關,而協方差函數則變成僅和所考慮的兩瞬時之差有關的相關函數。在意義上它等同於功率譜密度。高斯早生能夠用大量獨立的脈沖產生,從而在不論什么有限時間間隔內。這些脈沖中的每個買充值與全部脈沖值得總和相比都可忽略不計。

依據Box-Muller變換原理,建設隨機變量U1、U2來自獨立的處於(0,1)之間的均勻分布,則經過以下兩個式子產生的隨機變量Z0。Z1服從標准高斯分布。


上式中Z0,Z1滿足正態分布,當中均值為0,方差為1,變量U1和U2能夠改動為下式:


給圖像加入高斯噪聲的程序例如以下:

//給圖像加入高斯噪聲
#include <cmath>
#include <limits>
#include <cstdlib>
#include <iostream>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>

using namespace cv;
using namespace std;

double generateGaussianNoise(double m, double sigma);
Mat addGaussianNoise(Mat &srcImag);

int main()
{
	Mat srcImage = imread("2345.jpg");
	if (!srcImage.data)
	{
		cout << "讀入圖片錯誤!

" << endl; system("pause"); return -1; } imshow("原圖像", srcImage); Mat dstImage = addGaussianNoise(srcImage); imshow("加入高斯噪聲后的圖像", dstImage); waitKey(); return 0; } //生成高斯噪聲 double generateGaussianNoise(double mu, double sigma) { //定義小值 const double epsilon = numeric_limits<double>::min(); static double z0, z1; static bool flag = false; flag = !flag; //flag為假構造高斯隨機變量X if (!flag) return z1 * sigma + mu; double u1, u2; //構造隨機變量 do { u1 = rand() * (1.0 / RAND_MAX); u2 = rand() * (1.0 / RAND_MAX); } while (u1 <= epsilon); //flag為真構造高斯隨機變量 z0 = sqrt(-2.0*log(u1))*cos(2 * CV_PI*u2); z1 = sqrt(-2.0*log(u1))*sin(2 * CV_PI*u2); return z0*sigma + mu; } //為圖像加入高斯噪聲 Mat addGaussianNoise(Mat &srcImag) { Mat dstImage = srcImag.clone(); int channels = dstImage.channels(); int rowsNumber = dstImage.rows; int colsNumber = dstImage.cols*channels; //推斷圖像的連續性 if (dstImage.isContinuous()) { colsNumber *= rowsNumber; rowsNumber = 1; } for (int i = 0; i < rowsNumber; i++) { for (int j = 0; j < colsNumber; j++) { //加入高斯噪聲 int val = dstImage.ptr<uchar>(i)[j] + generateGaussianNoise(2, 0.8) * 32; if (val < 0) val = 0; if (val>255) val = 255; dstImage.ptr<uchar>(i)[j] = (uchar)val; } } return dstImage; }


程序運行后的效果圖例如以下:




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM