掩膜操作的数学表示
- 公式:
I ( i , j ) = 5 ∗ I ( i , j ) − [ I ( i − 1 , j ) + I ( i + 1 , j ) + I ( i , j − 1 ) + I ( i , j + 1 ) ] I(i,j)=5∗I(i,j)−[I(i−1,j)+I(i+1,j)+I(i,j−1)+I(i,j+1)] I(i,j)=5∗I(i,j)−[I(i−1,j)+I(i+1,j)+I(i,j−1)+I(i,j+1)]
I ∗ [ 0 − 1 0 − 1 5 − 1 0 − 1 0 ] = O I* \left[ \begin{matrix} 0 &-1 & 0 \\ -1 & 5 & -1 \\ 0 & -1 &0 \end{matrix} \right] =O I∗⎣⎡0−10−15−10−10⎦⎤=O
注意:如果是多通道,那么是对应通道进行掩膜操作,不同通道之间不进行任何运算。
代码:
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
void Sharpen(const Mat& myImage, Mat& Result);
int main(void)
{
Mat src ,dst0,dst1;
src=imread("../res/fruits.jpg",IMREAD_COLOR);
namedWindow("Input");
namedWindow("Output");
imshow("Input",src);
double t=(double)cv::getTickCount();
Sharpen(src,dst0);
t=((double)getTickCount()-t)/getTickFrequency();
cout << "Hand Witten function time passed in "<< t << "seconds"<< endl;
imshow("Output",dst0);
///用库函数
Mat kernel =(Mat_<char>(3,3) << 0,-1,0,
-1,5,-1,
0,-1,0); //定义一个Mask
t= (double)getTickCount();
cv::filter2D(src,dst1,src.depth(),kernel);
t=((double)getTickCount()-t)/getTickFrequency();
cout << "build in filter2D time passed in" << t << "seconds" << endl;
namedWindow("Output1");
imshow("Output1",dst1);
waitKey();
return 0;
}
void Sharpen(const Mat& myImage,Mat& Result)
{
CV_Assert(myImage.depth() == CV_8U);
const int nChannels = myImage.channels();
Result.create(myImage.size(),myImage.type());
for(int i=1; i<myImage.rows-1;++i)
{
const uchar* previous = myImage.ptr<uchar>(i-1); //得到三个相邻行的首地址
const uchar* current = myImage.ptr<uchar>(i);
const uchar* next = myImage.ptr<uchar>(i+1);
uchar* output = Result.ptr<uchar>(i);
for(int j=nChannels;j<nChannels*(myImage.cols-1);++j)
{
*output++=saturate_cast<uchar>(5*current[j]
-current[j-nChannels]
-current[j+nChannels]
-previous[j]
-next[j]);
}
}
//边界置0
Result.row(0).setTo(Scalar(0));
Result.row(Result.rows-1).setTo(Scalar(0));
Result.col(0).setTo(Scalar(0));
Result.col(Result.cols-1).setTo(Scalar(0));
}
结果:
input:
手写output
Filter2D:
方法 | 运行时间 |
---|---|
手写掩膜 | 0.01237ms |
Filter2D | 0.00288ms |
可见:两种方法效果差不多,但是运行时间差距很大,Opencv对Filter2D函数做了优化