在图像处理中,对当前位置像素的相邻像素计算新的像素值是很常见的操作,当邻域包括图像的前几行和下几行时,你就需要同时扫描图像的若干行
本篇介绍的这个例子是对图像进行锐化,它是基于拉普拉斯算子的。将一幅图像减去它经过拉普拉斯滤波之后的图像,这幅图像的边缘部分得到放大,即细节部分得到锐化,这个锐化的算子计算方式如下:
sharpened——pixel=5*current-left-right-up-down;
//彩色图片锐化
void
sharpend(const
Mat&
image,
Mat&
result)
{
result.create(image.size(),
image.type());
for
(int
j = 1; j <
image.rows-1; j++)
{
const
uchar* previous =
image.ptr<const
uchar>(j - 1);
const
uchar* current =
image.ptr<const
uchar>(j);
const
uchar* next =
image.ptr<const
uchar>(j + 1);
uchar*
output =
result.ptr<uchar>(j);
for
(int
i = 1*
image.channels(); i < (image.cols-1)*image.channels();
i++)
{
output[i] = cv::saturate_cast<uchar>
(5 * current[i] - previous[i]-current[i-3]-current[i+3]-next[i]);
}
}
result.row(0).setTo(cv::Scalar(0,0,0));
result.row(result.rows-1).setTo(cv::Scalar(0,0,0));
result.col(0).setTo(cv::Scalar(0,0,0));
result.col(result.cols
- 1).setTo(cv::Scalar(0,0,0));
}
其中模板函数cv::saturate_cast用来对计算结果进行截断;cv::Scalar(0,0,0)指定像素的三个通道的目标值
当然,对于本例子中的锐化滤波器,核矩阵为:[ 0 -1 0; -1 5 -1; 0 -1 1]这样一个3*3 的矩阵,OpenCV定义了一个特殊的函数来完成滤波处理:
cv::filter2D
下面是本例的第二种实现方法:
void
sharpen2D(const
Mat&
image,
Mat&
result)
{
Mat
kernel(3, 3,
CV_32F, cv::Scalar(0));
kernel.at<float>(1,
1) = 5.0;
kernel.at<float>(0,
1) = -1.0;
kernel.at<float>(1,
0) = -1.0;
kernel.at<float>(1,
2) = -1.0;
kernel.at<float>(2,
1) = -1.0;
cv::filter2D(image,
result,
image.depth(), kernel);
}