先体总结: 锐化就是增加便边缘和轮廓信息
平滑滤波器主要是使用邻域的均值(或者中值、积分)来代替模板中心的像素,消弱和邻域间的差别,以达到平滑图像和抑制噪声的目的;模糊图像,称为低通滤波器
锐化滤波器则使用邻域的微分作为算子,增大邻域间像素的差值,使图像的突变部分变的更加明显。锐化的作用是加强图像的边沿和轮廓,通常也成为高通滤波器
使用二阶微分进行图像锐化——拉普拉斯算子(Laplace)
先定义一个二阶微分的离散公式,然后构造一个基于该公式的滤波器模板,然后再把该模板与原图片卷积,从而实现锐化。
拉普拉斯算法模板
§ Laplacian()
void cv::Laplacian ( InputArray src,
OutputArray dst,
int ddepth,
int ksize = 1,
double scale = 1,
double delta = 0,
int borderType = BORDER_DEFAULT
)
参数:
src 源图片
dst 与src相同大小和相同通道数的目标图像。
ddepth 目标图像的所需深度。
ksize 用于计算二阶导数滤波器的孔径大小。有关详细信息,请参阅getDerivKernels。大小必须是正面和奇数。
scale 计算的拉普拉斯算子值的可选比例因子。默认情况下,不应用缩放。有关详细信息,请参阅getDerivKernels。
delta 在将结果存储在dst之前添加到结果中的可选增量值。
borderType 像素外推方法,cv :: BorderTypes
代码示例:
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include
using namespace cv;
int main( int argc, char** argv )
{undefined
Mat src, dst;
int kernel_size = 1;
int scale = 1;
int delta = 0;
int ddepth = CV_16S;
Mat imageName = "123.tif";
src = imread( imageName, IMREAD_GRAYSCALE ); // Load an image
// Check if image is loaded fine
if(src.empty()){undefined
printf(" Error opening image\n");
printf(" Program Arguments: [image_name -- default ../data/lena.jpg] \n");
return -1;
}
Mat imageEnhance;
Mat kernel = (Mat_(3, 3) << 0, 1, 0, 1, -4, 1, 0, 1, 0);
filter2D(src, imageEnhance, CV_8UC3, kernel);
imshow("filter2D", imageEnhance);
// GaussianBlur( src, src, Size(3, 3), 0, 0, BORDER_DEFAULT );
// cvtColor( src, src_gray, COLOR_BGR2GRAY ); // Convert the image to grayscale
Mat abs_dst;
Laplacian( src, dst, ddepth, kernel_size, scale, delta, BORDER_DEFAULT );
// converting back to CV_8U
convertScaleAbs( dst, abs_dst );
imshow( "Laplace Demo", abs_dst );
Mat sub;
cv::subtract(imageEnhance, abs_dst, sub);
// 计算图像的最大最小值
double pixMin,pixMax;
cv::minMaxLoc(sub,&pixMin,&pixMax);
std::cout << "min_a=" << pixMin << " max_b=" << pixMax << std::endl;
waitKey(0);
return 0;
}
filter2D用算子(0,1,0, 1,-4,1, 0,1,0)和Laplacian函数ksize==1时效果一样;
k_size=3时:
例子2:
思路:单独创建模板,使用卷积进行锐化
#include
#include
using namespace cv;
using namespace std;
int main(int artc, char** argv) {
Mat src = imread("./test.png");
if (src.empty()) {
printf("could not load image...\n");
return -1;
}
namedWindow("input", CV_WINDOW_AUTOSIZE);
imshow("input", src);
Mat sharpen_op = (Mat_(3, 3) << 0, -1, 0,
-1, 5, -1,
0, -1, 0);
Mat result;
filter2D(src, result, CV_32F, sharpen_op);
convertScaleAbs(result, result);
imshow("sharpen image", result);
waitKey(0);
return 0;
}