使用OpenCV進行圖片模糊處理(歸一化濾波器)
本篇部落格主要介紹如何使用OpenCV自帶的歸一化濾波器來對圖片進行處理,達到模糊圖片的效果。在程式碼中通過使用一個TrackerBar動態改變。具體的還是根據程式碼來進行解釋吧:
先看一下效果圖:
gif效果圖雖然不清晰,但是可以很明顯的通過拖動TrackerBar使得圖片更加模糊或者清晰了,下面來看一下具體實現的程式碼:
#include <iostream>
#include <opencv2\opencv.hpp>
using namespace cv;
using namespace std;
const char* source_window = "source" ;
int initial_size = 1;
Mat source, result;
void onSizeChange(int position) {
if (position == 0) {
position = 1;
}
cout << "position" << position << endl;
initial_size = position;
try {
blur(source, result, Size(initial_size, initial_size));
imshow(source_window, result);
}
catch (Exception e) {
std::cout << "Exception message = " << e.msg << std::endl;
}
}
int main()
{
source = imread("fifth.jpg", IMREAD_UNCHANGED);
result.create(source.rows,source.cols,source.channels());
cvNamedWindow(source_window, CV_WINDOW_AUTOSIZE);
cvCreateTrackbar("changeSize" , source_window, &initial_size, 100, onSizeChange);
cvSetTrackbarPos("changeSize", source_window, 0);
waitKey(0);
return 0;
}
主要實現模糊的程式碼就是blur(source, result, Size(initial_size, initial_size)),其中source是輸入的影象,result是輸出的影象,Size代表的是核視窗的大小,原有的畫素點的通過計算將被核視窗內所有畫素的均值取代,隨意這個Size越大代表參與平均的畫素點數量越多,反應到結果上就是原有畫素的值可能變化更大,值受到影響越大。
看一下相關理論方面的東西:
平滑 也稱 模糊, 是一項簡單且使用頻率很高的影象處理方法。
平滑處理的用途有很多, 但是在本教程中我們僅僅關注它減少噪聲的功用 (其他用途在以後的教程中會接觸到)。
平滑處理時需要用到一個 濾波器 。 最常用的濾波器是 線性 濾波器,線性濾波處理的輸出畫素值 (i.e. g(i,j)) 是輸入畫素值 (i.e. f(i+k,j+l))的加權和 :
h(k,l) 稱為 核, 它僅僅是一個加權係數。
不妨把 濾波器 想象成一個包含加權係數的視窗,當使用這個濾波器平滑處理影象時,就把這個視窗滑過影象。
歸一化塊濾波器 (Normalized Box Filter)¶
最簡單的濾波器, 輸出畫素值是核視窗內畫素值的 均值 ( 所有畫素加權係數相等)
核如下:
blur的函式原型:
/** @brief Blurs an image using the normalized box filter.
The function smoothes an image using the kernel:
\f[\texttt{K} = \frac{1}{\texttt{ksize.width*ksize.height}} \begin{bmatrix} 1 & 1 & 1 & \cdots & 1 & 1 \\ 1 & 1 & 1 & \cdots & 1 & 1 \\ \hdotsfor{6} \\ 1 & 1 & 1 & \cdots & 1 & 1 \\ \end{bmatrix}\f]
The call `blur(src, dst, ksize, anchor, borderType)` is equivalent to `boxFilter(src, dst, src.type(),
anchor, true, borderType)`.
@param src input image; it can have any number of channels, which are processed independently, but
the depth should be CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.
@param dst output image of the same size and type as src.
@param ksize blurring kernel size.
@param anchor anchor point; default value Point(-1,-1) means that the anchor is at the kernel
center.
@param borderType border mode used to extrapolate pixels outside of the image, see cv::BorderTypes
@sa boxFilter, bilateralFilter, GaussianBlur, medianBlur
*/
CV_EXPORTS_W void blur( InputArray src, OutputArray dst,
Size ksize, Point anchor = Point(-1,-1),
int borderType = BORDER_DEFAULT );
src: 輸入影象
dst: 輸出影象
Size( w,h ): 定義核心大小( w 畫素寬度, h 畫素高度)
Point(-1, -1): 指定錨點位置(被平滑點), 如果是負值,取核的中心為錨點。
好了,函式的註解也已經提供了,不知道我理解的對不對,如果有什麼不正確的地方還請大神指正,我早點改正,不勝感激!!!有興趣的朋友可以以關注我,遇到問題大家一起討論一下!!
這是我的微信公眾號,如果可以的話,希望您可以幫忙關注一下,這將是對我最大的鼓勵了,謝謝!!