跳转至

拉普拉斯锐化

图像锐化通过增加邻域像素的对比度来减弱或消除图像的模糊程度,使图像变得清晰,锐化和平滑恰恰相反。拉普拉斯锐化是采用拉普拉斯算子对图像进行操作。

在这里插入图片描述

对于扩散现象引起的图像模糊,可以用下式来进行锐化:g(i, j)=f(i, j)-k\tau\nabla^2f(i, j),这里k\tau是与扩散效应有关的系数。该系数取值要合理,如果k\tau过大,图像轮廓会产生过冲;反之如果k\tau过小,锐化效果就不明显。如果令k\tau=1,则变换公式为:g(i,j)=5f(i,j)-f(i-1,j)-f(i+1,j)-f(i,j+1)-f(i,j-1),用模板表示如下:

\begin{bmatrix} 0 & -1 &0 \\ -1 & 5 & -1\\ 0 & -1 & 0 \end{bmatrix}

在日常中,还有一种比较常用的8邻域拉普拉斯算子:

\begin{bmatrix} -1 & -1 &-1 \\ -1 & 9 & -1\\ -1 & -1 & -1 \end{bmatrix}

代码

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;
}