OpenCV实验系列之Mask操作
注意:以下内容根据opencv官网提供的教程结合个人理解所得,仅是个人学习笔记,可能存在错误或偏差,欢迎指正。
Mask矩阵的计算法则
Mask operations on matrices are quite simple. The idea is that we recalculate each pixels value in an image according to a mask matrix (also known as kernel). This mask holds values that will adjust how much influence neighboring pixels (and the current pixel) have on the new pixel value. From a mathematical point of view we make a weighted average, with our specified values.
Mask矩阵有时也称为kernel其实是描述某个像素点受到周围的像素点影响的程度。在OpenCV官网上给出的例子可清楚的说明其计算的方式
其中我们所计算的像素点位于(0,0)处,而计算内容是将该像素及其周围的像素点乘上对应的权重再求和之后重新赋值于该点。
Mask操作的C++实现
在opencv库中提供了
//! applies non-separable 2D linear filter to the image
CV_EXPORTS_W void filter2D( InputArray src,
OutputArray dst, int ddepth,
InputArray kernel,
Point anchor=Point(-1,-1),
double delta=0,
int borderType=BORDER_DEFAULT
);
The function even has a fifth optional argument to specify the center of the kernel, a sixth for adding an optional value to the filtered pixels before storing them in K and a seventh one for determining what to do in the regions where the operation is undefined (borders).
该函数的锚点默认为Mask矩阵的中心(与上图表述不同)
以下为使用例程
#include<iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
void main()
{
Mat src;
Mat dst;
src=imread("timg.jpg");
imshow("src",src);
dst.create(src.size(),src.type());
//基本运算实现
const int nChannels = src.channels();//获取通道数
dst.create(src.size(),src.type());
double t = (double)getTickCount();//计时开始
for(int j = 1 ; j < src.rows-1; ++j)
{
const uchar* previous = src.ptr<uchar>(j - 1);//获取相关行指针
const uchar* current = src.ptr<uchar>(j );
const uchar* next = src.ptr<uchar>(j + 1);
uchar* output = dst.ptr<uchar>(j);
for(int i= nChannels;i < nChannels*(src.cols-1); ++i)
{
*output++ = saturate_cast<uchar>(5*current[i] - current[i-nChannels]
- current[i+nChannels] - previous[i] - next[i]);//计算并防止溢出
}
}
t = ((double)getTickCount() - t)/getTickFrequency();//计算耗时
cout << "Times passed in seconds: " << t << endl;
imshow("dst",dst);
//线性滤波器运算实现
Mat kernel = (Mat_<char>(3,3) << 0, -1, 0,
-1, 5, -1,
0, -1, 0);
t = (double)getTickCount();//计时开始
filter2D( src, dst, src.depth(), kernel );
t = ((double)getTickCount() - t)/getTickFrequency();//计算耗时
cout << "Times passed in seconds: " << t << endl;
imshow("dst1",dst);
waitKey(0);
}
原图
处理图,锐化