图像锐化通过增加邻域像素的对比度来减弱或消除图像的模糊程度,使图像变得清晰,锐化和平滑恰恰相反。拉普拉斯锐化是采用拉普拉斯算子对图像进行操作。
对于扩散现象引起的图像模糊,可以用下式来进行锐化: g ( i , j ) = f ( i , j ) − k τ ∇ 2 f ( i , j ) g(i, j)=f(i, j)-k\tau\nabla^2f(i, j) g(i,j)=f(i,j)−kτ∇2f(i,j),这里 k τ k\tau kτ是与扩散效应有关的系数。该系数取值要合理,如果 k τ k\tau kτ过大,图像轮廓会产生过冲;反之如果 k τ k\tau kτ过小,锐化效果就不明显。如果令 k τ = 1 k\tau=1 kτ=1,则变换公式为: g ( i , j ) = 5 f ( i , j ) − f ( i − 1 , j ) − f ( i + 1 , j ) − f ( i , j + 1 ) − f ( i , j − 1 ) g(i,j)=5f(i,j)-f(i-1,j)-f(i+1,j)-f(i,j+1)-f(i,j-1) g(i,j)=5f(i,j)−f(i−1,j)−f(i+1,j)−f(i,j+1)−f(i,j−1),用模板表示如下:
[ 0 − 1 0 − 1 5 − 1 0 − 1 0 ] \begin{bmatrix} 0 & -1 &0 \\ -1 & 5 & -1\\ 0 & -1 & 0 \end{bmatrix} ⎣⎡0−10−15−10−10⎦⎤
在日常中,还有一种比较常用的8邻域拉普拉斯算子:
[ − 1 − 1 − 1 − 1 9 − 1 − 1 − 1 − 1 ] \begin{bmatrix} -1 & -1 &-1 \\ -1 & 9 & -1\\ -1 & -1 & -1 \end{bmatrix} ⎣⎡−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(i, j)[k] - src.at(i - 1, j - 1)[k] - src.at(i - 1, j)[k]
- src.at(i - 1, j + 1)[k] - src.at(i, j - 1)[k] - src.at(i, j + 1)[k]
- src.at(i + 1, j - 1)[k] - src.at(i + 1, j)[k] - src.at(i + 1, j + 1)[k];
if (sum > 255) sum = 255;
else if (sum < 0) sum = 0;
dst.at(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(i, j)[k] - src.at(i - 1, j - 1)[k] - src.at(i - 1, j)[k]
- src.at(i - 1, j + 1)[k] - src.at(i, j - 1)[k] - src.at(i, j + 1)[k]
- src.at(i + 1, j - 1)[k] - src.at(i + 1, j)[k] - src.at(i + 1, j + 1)[k];
sum = sum * sharpDegree + 0.5;
if (sum > 255) sum = 255;
else if (sum < 0) sum = 0;
dst.at(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(i, j)[k] - dst.at(i, j)[k];
if (sum > 255) sum = 255;
else if (sum < 0) sum = 0;
dst.at(i, j)[k] = sum;
}
}
}
return dst;
}