拉普拉斯锐化
图像锐化通过增加邻域像素的对比度来减弱或消除图像的模糊程度,使图像变得清晰,锐化和平滑恰恰相反。拉普拉斯锐化是采用拉普拉斯算子对图像进行操作。
对于扩散现象引起的图像模糊,可以用下式来进行锐化: g(i,j)=f(i,j)−kτ∇2f(i,j),这里 kτ是与扩散效应有关的系数。该系数取值要合理,如果 kτ过大,图像轮廓会产生过冲;反之如果 kτ过小,锐化效果就不明显。如果令 kτ=1,则变换公式为: g(i,j)=5f(i,j)−f(i−1,j)−f(i+1,j)−f(i,j+1)−f(i,j−1),用模板表示如下:
⎣⎡0−10−15−10−10⎦⎤
在日常中,还有一种比较常用的8邻域拉普拉斯算子:
⎣⎡−1−1−1−19−1−1−1−1⎦⎤
代码
Mat LaplaceSharp(Mat src) {
int row = src.rows;
int col = src.cols;
int border = 1;
Mat dst(row, col, CV_8UC3);
for (int i = border; i < row - border; i++) {
for (int j = border; j < col - border; j++) {
for (int k = 0; k < 3; k++) {
int sum = 9 * src.at<Vec3b>(i, j)[k] - src.at<Vec3b>(i - 1, j - 1)[k] - src.at<Vec3b>(i - 1, j)[k]
- src.at<Vec3b>(i - 1, j + 1)[k] - src.at<Vec3b>(i, j - 1)[k] - src.at<Vec3b>(i, j + 1)[k]
- src.at<Vec3b>(i + 1, j - 1)[k] - src.at<Vec3b>(i + 1, j)[k] - src.at<Vec3b>(i + 1, j + 1)[k];
if (sum > 255) sum = 255;
else if (sum < 0) sum = 0;
dst.at<Vec3b>(i, j)[k] = sum;
}
}
}
return dst;
}
自由锐化
这个算法实际上还是拉普拉斯锐化,不过添加了一个参数来调节锐化度,以实现调整整体的视觉效果。使得图像看起来更加自然,更符合审美。
Mat FreeSharp(Mat src, float sharpDegree = 0.3) {
int row = src.rows;
int col = src.cols;
int border = 1;
Mat dst(row, col, CV_8UC3);
for (int i = border; i < row - border; i++) {
for (int j = border; j < col - border; j++) {
for (int k = 0; k < 3; k++) {
int sum = 9 * src.at<Vec3b>(i, j)[k] - src.at<Vec3b>(i - 1, j - 1)[k] - src.at<Vec3b>(i - 1, j)[k]
- src.at<Vec3b>(i - 1, j + 1)[k] - src.at<Vec3b>(i, j - 1)[k] - src.at<Vec3b>(i, j + 1)[k]
- src.at<Vec3b>(i + 1, j - 1)[k] - src.at<Vec3b>(i + 1, j)[k] - src.at<Vec3b>(i + 1, j + 1)[k];
sum = sum * sharpDegree + 0.5;
if (sum > 255) sum = 255;
else if (sum < 0) sum = 0;
dst.at<Vec3b>(i, j)[k] = sum;
}
}
}
return dst;
}
钝化蒙版
先根据用户指定的钝化度对图像进行高斯模糊处理,再对高斯模糊处理结果与原图像进行钝化处理。 钝化度用来改变像素间的对比度强弱,钝化度,取值(0~100),钝化值越小,钝化的部分就越窄,仅仅会影响边缘像素; 钝化值越大,钝化的范围越宽,效果更明显。
代码
// degree:钝化度,取值(0~100)
// 钝化度用来改变像素间的对比度强弱,钝化值越小,钝化的部分就越窄,仅仅会影响边缘像素
// 钝化值越大,钝化的范围越宽,效果更明显
Mat UnsharpMask(Mat src, int degree) {
int row = src.rows;
int col = src.cols;
if (degree < 1) degree = 1;
if (degree > 100) degree = 100;
Mat dst(row, col, CV_8UC3);
src.copyTo(src);
int border = 1;
for (int i = 0; i < degree; i++) {
GaussianBlur(dst, dst, Size(3, 3), 1.0);
}
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
for (int k = 0; k < 3; k++) {
int sum = 2 * src.at<Vec3b>(i, j)[k] - dst.at<Vec3b>(i, j)[k];
if (sum > 255) sum = 255;
else if (sum < 0) sum = 0;
dst.at<Vec3b>(i, j)[k] = sum;
}
}
}
return dst;
}