1. 程式人生 > >基於opencv2利用卷積運算元實現高斯模糊

基於opencv2利用卷積運算元實現高斯模糊

    我們都知道,卷積是一種好玩的東西,通過卷積可以實現很多功能,例如photoshop中的各種濾鏡也可以通過對一副影象進行卷積獲得。而目前大火的機器學習中的CNN演算法也是利用卷積來實現的,至於CNN的演算法以後再講,今天主要是介紹卷積的原理以及利用它來實現高斯模糊。

    我們先來看下卷積是將兩個矩陣相乘在求和,而具體原理可在這篇文章中看。而影象中高斯模糊則是根據二維的正態分佈(高斯分佈)來產生高斯模糊卷積子。

    一維的正態分佈:,其中我們的u取0。

    二維的正態分佈

        

    利用這個二維高斯模糊公式,我們可以產生N*N的卷積核,然後利用這個核與圖片中的每個畫素進行卷積便是高斯模糊。

    這個過程可以通過以下幾張圖來理解,假如我產生一個3*3的卷積核,取1,因此我們就可以產生以下的矩陣:

                                            

我們取影象中的某個畫素周圍3*3的矩陣:

                                            

而矩陣中的78對應的是(0,0)座標,而這個矩陣我們是圍繞著這個畫素點在半徑為1的範圍內取得矩陣,因此我們卷積獲得的值也應替代該值。

通過卷積:(0.0585*0+0.0965*0+0.0585*7+0.0965*4+0.1592*78+0.0965*8+0.0585*69+0.0965*2+0.0585*4)=18.4486

    因此78這個位置的值也就變為18.4486。高斯模糊便是通過對每個畫素以半徑r範圍取一N*N矩陣與N*N卷積核進行卷積並改變改畫素點的值以獲得濾波效果。

以下便是灰度圖的高斯模糊程式:

#include<iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<math.h>

#define sigma 1   //定義sigma的大小越大越模糊
#define PI 3.14159
#define N 5 //定義卷積核大小

int main()
{
	float liv_conv[N][N] = {0}; //定義卷積核

	cv::Mat lMv_src = cv::imread("E:\\temp\\3D\\pad.jpg");//開啟圖片

	cv::resize(lMv_src,lMv_src,cv::Size(lMv_src.cols/4,lMv_src.rows/4),0,0,cv::INTER_LINEAR);//因為我的圖片太大,不方便顯示,我就利用這個函式縮小

	cv::Mat lMv_gray, lMv_OutPut = cv::Mat::zeros(lMv_src.rows, lMv_src.cols, CV_8UC1); //定義灰度圖,與輸出影象
	cv::cvtColor(lMv_src,lMv_gray,CV_BGR2GRAY);//將彩色圖轉換灰度圖

	int liv_n = N/2; //獲取半徑
	float all = 0.0; 

	/**************
	產生卷積核
	***************/
	for(int i = 0; i<N; i++)
	{
		for(int j = 0; j<N; j++)
		{
			liv_conv[i][j] = exp(-((i-liv_n)*(i-liv_n)+(j-liv_n)*(j-liv_n))/(2.0*sigma*sigma))/(2*PI*sigma*sigma);//二維正態分佈公式
			all+=liv_conv[i][j];
		}
	}
	/******************
	逐個畫素進行卷積
	*******************/
	for(int i = 0; i<lMv_gray.rows-N; i++)
	{
		for(int j = 0; j<lMv_gray.cols-N; j++)
		{
			float lfv_sum = 0.0;
			for(int y = 0; y<N; y++)
			{
				for(int x = 0; x<N; x++)
				{
					lfv_sum+=lMv_gray.at<uchar>(i+y,j+x)*liv_conv[y][x];//相稱求和
				}
			}
			lMv_OutPut.at<uchar>(i,j) = lfv_sum/all;
		}
	}

	cv::imshow("Gaussian",lMv_OutPut);//顯示高斯模糊後的影象
	cv::imshow("Src",lMv_gray);//顯示原圖
	cv::waitKey(0);
	return 0;
}

原圖:


sigma = 1:


sigma = 10:


sigma = 0.1:


其實彩色圖片的高斯模糊的原理是一樣,程式也是基本一樣的:

#include<iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<math.h>

#define sigma 1  //定義sigma的大小越大越模糊
#define PI 3.14159
#define N 5 //定義卷積核大小

int main()
{
	float liv_conv[N][N] = {0}; //定義卷積核

	cv::Mat lMv_src = cv::imread("E:\\temp\\3D\\pad.jpg");//開啟圖片

	cv::resize(lMv_src,lMv_src,cv::Size(lMv_src.cols/2,lMv_src.rows/2),0,0,cv::INTER_LINEAR);//因為我的圖片太大,不方便顯示,我就利用這個函式縮小

	cv::Mat lMv_gray, lMv_OutPut = cv::Mat::zeros(lMv_src.rows, lMv_src.cols, CV_8UC3); //定義灰度圖,與輸出影象
	cv::cvtColor(lMv_src,lMv_gray,CV_BGR2GRAY);//將彩色圖轉換灰度圖

	int liv_n = N/2; //獲取半徑
	float all = 0.0; 

	/**************
	產生卷積核
	***************/
	for(int i = 0; i<N; i++)
	{
		for(int j = 0; j<N; j++)
		{
			liv_conv[i][j] = exp(-((i-liv_n)*(i-liv_n)+(j-liv_n)*(j-liv_n))/(2.0*sigma*sigma))/(2*PI*sigma*sigma);//二維正態分佈公式
			all+=liv_conv[i][j];
		}
	}
	/******************
	逐個畫素進行卷積
	*******************/
	for(int i = 0; i<lMv_gray.rows-N; i++)
	{
		for(int j = 0; j<lMv_gray.cols-N; j++)
		{
			float lfv_sum_b = 0.0, lfv_sum_g = 0.0, lfv_sum_r = 0.0;
			for(int y = 0; y<N; y++)
			{
				for(int x = 0; x<N; x++)
				{
					lfv_sum_b+=lMv_src.at<cv::Vec3b>(i+y,j+x)[0]*liv_conv[y][x];//相稱求和
					lfv_sum_g+=lMv_src.at<cv::Vec3b>(i+y,j+x)[1]*liv_conv[y][x];
					lfv_sum_r+=lMv_src.at<cv::Vec3b>(i+y,j+x)[2]*liv_conv[y][x];
				}
			}
			lMv_OutPut.at<cv::Vec3b>(i,j)[0] = lfv_sum_b/all;
			lMv_OutPut.at<cv::Vec3b>(i,j)[1] = lfv_sum_g/all;
			lMv_OutPut.at<cv::Vec3b>(i,j)[2] = lfv_sum_r/all;
		}
	}

	cv::imshow("Gaussian",lMv_OutPut);//顯示高斯模糊後的影象
	cv::imshow("Src",lMv_src);//顯示原圖
	cv::waitKey(0);
	return 0;
}

結果:


然後我們加入椒鹽噪聲測試下效能:

#define sigma 3  //定義sigma的大小越大越模糊
#define PI 3.14159
#define N 8 //定義卷積核大小
#define NN 1600
/*************************
建立椒鹽噪點
*************************/
for(int i = 0; i<NN; i++)
{
	int x = rand()%(lMv_src.cols-1)+1; //建立隨機數
        int y = rand()%(lMv_src.rows-1)+1;
	lMv_src.at<cv::Vec3b>(y,x)[0] = 255;
	lMv_src.at<cv::Vec3b>(y,x)[1] = 255;
	lMv_src.at<cv::Vec3b>(y,x)[2] = 255;
}

由此看來效果還是可以的,接下來我會跟大家分享去模糊的演算法。

歡迎喜歡影象處理或人工智慧的朋友通過郵箱[email protected]來聯絡我,一起交流。

相關推薦

基於opencv2利用運算元實現模糊

    我們都知道,卷積是一種好玩的東西,通過卷積可以實現很多功能,例如photoshop中的各種濾鏡也可以通過對一副影象進行卷積獲得。而目前大火的機器學習中的CNN演算法也是利用卷積來實現的,至於CNN的演算法以後再講,今天主要是介紹卷積的原理以及利用它來實現高斯模糊。 

c#實現影象影象與濾波——平滑

使用C#語言編寫高斯平滑。 一、線性濾波與卷積的基本概念 2D卷積需要4個巢狀迴圈4-double loop,所以它並不快,除非我們使用很小的卷積核。這裡一般使用3×3或者5×5。而且,對於濾波器,也有一定的規則要求: 1)濾波器的大小應該是奇數,這樣它才有一箇中心

Java實現模糊演算法處理影象

高斯模糊(英語:Gaussian Blur),也叫高斯平滑,是在Adobe Photoshop、GIMP以及Paint.NET等影象處理軟體中廣泛使用的處理效果,通常用它來減少影象噪聲以及降低細節層次。 簡介 高斯模糊(Gaussian Blur)是美國

iOS自帶實現模糊效果

引 什麼叫高斯模糊效果,通俗地說,就是毛玻璃效果,從iOS 7以來,就頻繁地被設計使用,如果用得好,效果會顯得非常的好。我們來看一個例子: 圖中下面一小部分就是高斯模糊效果。要實現也很簡單,iOS自身就支援這種效果。 iOS 7 UIToolbar

Android實現模糊(也叫毛玻璃效果)

/*** 高斯模糊* @param bkg* @param view*/private void blur(Bitmap bkg, View view) {float radius = 25;Bitmap overlay = Bitmap.createBitmap((int) (view.getMeasure

C#呼叫GDI+1.1中的函式實現模糊、USM銳化等經典效果。

/// <summary> /// 對影象進行高斯模糊,參考:http://msdn.microsoft.com/en-us/library/ms534057(v=vs.85).aspx /// </summary> /// <

使用RenderScript來實現模糊,相容低版本

這兩天看到公司工程裡有用到高斯模糊,是通過java實現的,很慢,所以找了一些資料,看到RenderScript,效能很好,而且RenderScript是可以相容低版本的,實現方式也是jni。相容低版本的教程網上有很多,就是在sdk目錄裡把RenderScript v8包新增

簡單css實現模糊(毛玻璃效果)

img標籤新增class  設定filter:blur (0-npx)模糊半徑 filter: url(blur.svg#blur); /* FireFox, Chrome, Opera */    

CSS: filter: blur(); 實現模糊效果,不可不知的細節優化

前言 在專案中,要實現如下的效果: 頁面頂部的設計稿,前面一個卡片式的輪播,後邊的背景(是橢圓的一部分)取前面的圖片,進行一個高斯模糊的處理。 開始 前面的輪播部分,使用了第三方的輪播外掛,非常好用,推薦給大家(地址)。輪播,不作為今天的主要內容,暫時簡單描述下,

android 實現模糊

方法一 (1)RenderScript RenderScript是Google在Android 3.0(API 11)中引入的一個高效能圖片處理框架。 使用RenderScriprt實現高斯模糊: 首先在在build.gradle的defaultConf

android實現模糊功能

最近專案要求android客戶端模仿IOS的一種模糊背景的效果,高斯模糊在PS裡邊常用。大體思路是兩步: 第一步獲取Activity的螢幕截圖。 第二步對截圖進行高斯模糊演算法。 總之感覺體驗不是很好,主要原因是對Bitmap進行操作,這種東西本來就是安卓的噩夢,搞不好還會

Android實現模糊

心血來潮再來一篇部落格,和大家分享一下高斯模糊技巧 核心程式碼如下: /** * bitmap 物件進行模糊處理 * @param sentBitmap 原圖bitmap

圖片實現模糊

最近在搞圖片的顯示,做了一個高斯模糊的效果,使用的是gitgub上寫好的效果, 效果圖如下, 1. (1)xml檔案: <?xml version="1.0" encoding="utf-8"?> <LinearLay

[原始碼和文件分享]基於CUDA的神經網路演算法實現

摘 要 卷積神經網路是近年來人工智慧領域取得重大突破的一種重要手段,給出了影象識別、語音識別和自然語言處理領域中關鍵問題的優化解決方案,尤其適合處理影象方面的任務,如人臉識別和手寫體識別。手寫數字識別是用卷積神經網路解決的經典問題,採用一般方法訓練出來的神經網路達到了97%的識別率,幾乎與人類的

機器學習:利用神經網路實現影象風格遷移 (一)

相信很多人都對之前大名鼎鼎的 Prisma 早有耳聞,Prisma 能夠將一張普通的影象轉換成各種藝術風格的影象,今天,我們將要介紹一下Prisma 這款軟體背後的演算法原理。就是發表於 2016 CVPR 一篇文章, “ Image Style Transf

深度學習入門——利用神經網路實現MNIST手寫數字識別

MNIST(Modified National Institute of Standards and Technology)資料庫是一個大型手寫數字資料庫,通常用於訓練各種影象處理系統。該資料庫還廣泛用於機器學習領域的培訓和測試。它是通過重新打亂來自NIST原始資料集的樣本而

Tensorflow2.0——利用神經網路實現簡單的驗證碼識別

之前用tensorflow1.13做了一個驗證碼識別的小東西準確率還是相當高的(當然其中大部分邏輯都是從網上很多大神的部落格中借鑑

利用redis主從+keepalived實現可用

linux 運維 redisRedis簡介: Redis是一個開源的使用ANSI C語言編寫、支持網絡、可基於內存亦可持久化的日誌型、Key-Value數據庫,並提供多種語言的API。從2010年3月15日起,Redis的開發工作由VMware主持。 redis是一個key-value存儲系統。和Memc

Opencv3 Robert算子 Sobel算子 拉普拉斯算子 自定義核——實現漸進模糊

ima png har [] int turn src stream esp #include <iostream>#include <opencv2/opencv.hpp> using namespace std;using namespace c

學習筆記之——基於pytorch的神經網路

本博文為本人的學習筆記。參考材料為《深度學習入門之——PyTorch》 pytorch中文網:https://www.pytorchtutorial.com/  關於反捲積:https://github.com/vdumoulin/conv_arithmetic/blob/ma