C++ OpenCV實現(xiàn)與添加椒鹽噪聲和高斯噪音
一、什么是圖像噪音
圖像噪聲是圖像在獲取或是傳輸過程中受到隨機信號干擾,妨礙人們對圖像理解及分析處理的信號。很多時候將圖像噪聲看做多維隨機過程,因而描述噪聲的方法完全可以借用隨機過程的描述, 也就是用它的概率分布函數(shù)和概率密度分布函數(shù)。圖像噪聲的產(chǎn)生來自圖像獲取中的環(huán)境條件和傳感元器件自身的質量,圖像在傳輸過程中產(chǎn)生圖像噪聲的主要因素是所用的傳輸信道受到了噪聲的污染。
二、椒鹽噪聲
椒鹽噪聲是數(shù)字圖像中的常見噪聲,一般是由圖像傳感器、傳輸信道及解碼處理等產(chǎn)生的黑白相見的亮暗點噪聲,椒鹽噪聲常由圖像切割產(chǎn)生。椒鹽噪聲是指兩種噪聲:鹽噪聲(salt noise)及椒噪聲(pepper noise)。鹽噪聲一般是白色噪聲,椒噪聲一般是黑色噪聲,前者高灰度噪聲,后者屬于低灰度噪聲,一般兩種噪聲同時出現(xiàn),呈現(xiàn)在圖像上就是黑白雜點。圖像去除脈沖干擾及椒鹽噪聲最常用的算法是中值濾波,圖像模擬添加椒鹽噪聲是通過隨機獲取像素值點并設置為高亮點來實現(xiàn)的。
示例代碼
#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <cstdlib> using namespace cv; // 向圖像添加椒鹽噪聲的函數(shù) Mat addSaltNoise(Mat srcImage, int n) { Mat resultImage = srcImage.clone(); // 循環(huán)添加椒鹽噪聲'n'次 for (int k = 0; k < n; k++) { // 隨機選擇一個像素位置 int i = rand() % resultImage.cols; int j = rand() % resultImage.rows; // 檢查圖像的通道數(shù) // 如果是灰度圖像(1個通道),將像素值設置為255 if (resultImage.channels() == 1) resultImage.at<uchar>(j, i) = 255; else // 如果是彩色圖像(3個通道),將所有通道的值都設置為255 { resultImage.at<Vec3b>(j, i)[0] = 255; resultImage.at<Vec3b>(j, i)[1] = 255; resultImage.at<Vec3b>(j, i)[2] = 255; } } return resultImage; } int main() { // 從文件加載源圖像 Mat srcImage = imread("C://Users//86173//Desktop//cc.png"); // 檢查圖像數(shù)據(jù)是否成功加載 if (!srcImage.data) return -1; // 調用addSaltNoise函數(shù),傳入源圖像和要添加的噪聲像素數(shù)量 Mat resultImage = addSaltNoise(srcImage, 5000); // 顯示原始圖像和帶有噪聲的圖像 imshow("srcImage", srcImage); imshow("resultImage", resultImage); // 等待按鍵輸入,然后退出程序 waitKey(0); return 0; }
效果圖
三、高斯噪聲
高斯噪聲是指概率密度函數(shù)服從高斯分布(即正態(tài)分布)的一類噪聲。如果一個噪聲,它的幅度服從高斯分布,而它的功率譜密度又是分布均勻的,則稱它為高斯白噪聲。高斯白噪聲的二階矩不想關,一階矩為常數(shù),是指先后信號在時間上的相關性。高斯白噪聲包括熱噪聲和散粒噪聲。高斯噪聲完全由其時變平均值和兩瞬時的協(xié)方差函數(shù)來確定,若噪聲為平穩(wěn)的,則平均值與時間無關,而協(xié)方差函數(shù)則變成僅和所考慮的兩瞬時之方差有關的相關函數(shù),它在意義上等效于功率譜密度。高斯噪聲可以由大量獨立的脈沖產(chǎn)生,從而在任何有限時間間隔內,這些脈沖中的每一個脈沖值與所有脈沖值的總和相比都可以忽略不計。
#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> #include <cstdlib> #include <limits> #include <cmath> using namespace cv; using namespace std; // 生成高斯分布的隨機數(shù) double generateGaussianNoise(double mu, double sigma) { // 定義一個特別小的值 const double epsilon = numeric_limits<double>::min(); static double z0, z1; static bool flag = false; flag = !flag; // flag為假,構造高斯隨機變量 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為真構造高斯隨機變量X z0 = sqrt(-2.0 * log(u1)) * cos(2 * CV_PI * u2); z1 = sqrt(-2.0 * log(u1)) * sin(2 * CV_PI * u2); return z1 * sigma + mu; } // 為圖像添加高斯噪聲 Mat addGaussianNoise(Mat& srcImage) { Mat resultImage = srcImage.clone(); // 深拷貝,克隆 int channels = resultImage.channels(); // 獲取圖像的通道 int nRows = resultImage.rows; // 圖像的行數(shù) int nCols = resultImage.cols * channels; // 圖像的總列數(shù) // 判斷圖像的連續(xù)性 if (resultImage.isContinuous()) // 判斷矩陣是否連續(xù),若連續(xù),我們相當于只需要遍歷一個一維數(shù)組 { nCols *= nRows; nRows = 1; } for (int i = 0; i < nRows; i++) { for (int j = 0; j < nCols; j++) { // 添加高斯噪聲 int val = resultImage.ptr<uchar>(i)[j] + generateGaussianNoise(2, 0.8) * 32; if (val < 0) val = 0; if (val > 255) val = 255; resultImage.ptr<uchar>(i)[j] = (uchar)val; } } return resultImage; } int main() { Mat srcImage = imread("C://Users//86173//Desktop//cc.png"); if (!srcImage.data) return -1; imshow("srcImage", srcImage); Mat resultImage = addGaussianNoise(srcImage); imshow("resultImage", resultImage); waitKey(0); return 0; }
效果圖
以上就是C++ OpenCV實現(xiàn)與添加椒鹽噪聲和高斯噪音的詳細內容,更多關于C++ OpenCV噪聲的資料請關注腳本之家其它相關文章!
相關文章
淺談帶緩沖I/O 和不帶緩沖I/O的區(qū)別與聯(lián)系
下面小編就為大家?guī)硪黄獪\談帶緩沖I/O 和不帶緩沖I/O的區(qū)別與聯(lián)系。小編覺得挺不錯的現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-01-01C++實現(xiàn)Window環(huán)境聊天室功能
這篇文章主要為大家詳細介紹了C++實現(xiàn)Window環(huán)境聊天室功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-06-06