以图像锐化为内容,介绍有关卷积核的遍历,main.cpp 代码如下:
#include <QCoreApplication>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
void sharpen(const Mat &source, Mat &result)
{
result.create( source.size(), source.type() );
for ( int i = 1; i < source.rows-1; i ++ )//第一行和最后一行不处理
{
const uchar* previous = source.ptr<const uchar>(i-1);//上一行
const uchar* current = source.ptr<const uchar>(i);//当前行
const uchar* next = source.ptr<const uchar>(i+1);//下一行
uchar* output = result.ptr<uchar>(i);//输出行
for ( int j = 1; j < source.cols-1; j ++ )//第一列和最后一列不处理
{
*output = saturate_cast<uchar>(5*current[j] - current[j-1]
-current[j+1]-previous[j]-next[j]);
output ++;
}
}
//将未处理的像素设置成0
result.row(0).setTo(Scalar(0));
result.row(result.rows-1).setTo(Scalar(0));
result.col(0).setTo(Scalar(0));
result.row(result.cols-1).setTo(Scalar(0));
}
int main()
{
Mat src = imread("lena.jpg",0);
Mat dst;
sharpen(src, dst);
namedWindow("dst",0);
imshow("dst",dst);
waitKey(0);
return 0;
}
函数介绍:
1、因为函数以单通道灰度图像为原图像处理,所以在用 imread() 函数读取图像第二个参数要用0,即以灰度图像读取。
2、函数操作原理是锐化原理,即将一副图像减去它经过拉普拉斯滤波之后的图像,这幅图像的边缘部分将得到放大,细节部分更加锐化。
3、saturate_cast<uchar>() 函数用来保证圆括号内的数不会超过尖括号中数据类型的截断范围,即 uchar 的范围是0~255,括号内的数在小于0被截断则返回0,大于255被截断则返回255。
4、Mat 类中的 create() 方法用来创建指定大小,指定数据类型的矩阵。
对于滤波核较大的情况,使用OpenCV中的滤波函数效率会更高,代码如下:
void sharpen(const Mat &source, Mat &result)
{
Mat kernel(3, 3, CV_32F, Scalar(0));//初始化滤波核
kernel.at<float>(1, 1) = 5.0;//设置滤波核系数
kernel.at<float>(0, 1) = -1.0;
kernel.at<float>(2, 1) = -1.0;
kernel.at<float>(1, 0) = -1.0;
kernel.at<float>(1, 2) = -1.0;
filter2D(source, result, source.depth(), kernel);//滤波操作
}