在图像处理中,对当前位置像素的相邻像素计算新的像素值是很常见的操作,当邻域包括图像的前几行和下几行时,你就需要同时扫描图像的若干行
本篇介绍的这个例子是对图像进行锐化,它是基于拉普拉斯算子的。将一幅图像减去它经过拉普拉斯滤波之后的图像,这幅图像的边缘部分得到放大,即细节部分得到锐化,这个锐化的算子计算方式如下:
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);
}