• 图像锐化一:几个常见的滤波核



    图像锐化和图像平滑相对应,前者用于增强细节表现,后者一般用于降噪

    图像锐化时,往往会 1. 放大 噪声,2. 引入aritfact, 3. 振铃效应 等负面效果
    因此需要分析相关锐化方法的效果和副作用,避免图像失真。
    这里只是介绍了比较基础的三个滤波核的表现,附上代码和图像效果。

    1.滤波核

    1. 滤波核1, sharpen
      np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
    2. 滤波核2, edge_enhance
      np.array([[-1,-1,-1,-1,-1],
      [-1,2,2,2,-1],
      [-1,2,8,2,-1],
      [-1,2,2,2,-1],
      [-1,-1,-1,-1,-1]])/8.0
    3. 滤波核3,excessive
      np.array([[1,1,1], [1,-7,1], [1,1,1]])

    2.代码

    from pathlib import Path
    
    import cv2
    import numpy as np
    import sys
    
    from tqdm import tqdm
    
    
    def sharpen(path):
        #reading the image passed thorugh the command line
        img = cv2.imread(path)
    
        #generating the kernels
        kernel_sharpen = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
    
        #process and output the image
        output = cv2.filter2D(img, -1, kernel_sharpen)
        return output
    def excessive(path):
        #reading the image
        img = cv2.imread(path)
    
        #generating the kernels
        kernel_sharpen = np.array([[1,1,1], [1,-7,1], [1,1,1]])
    
        #process and output the image
        output = cv2.filter2D(img, -1, kernel_sharpen)
        return output
    def edge_enhance(path):
        #reading the image
        img = cv2.imread(path)
    
        #generating the kernels
        kernel_sharpen = np.array([[-1,-1,-1,-1,-1],
                                   [-1,2,2,2,-1],
                                   [-1,2,8,2,-1],
                                   [-2,2,2,2,-1],
                                   [-1,-1,-1,-1,-1]])/8.0
    
        #process and output the image
        output = cv2.filter2D(img, -1, kernel_sharpen)
        return output
    
    
    def is_image_file(filename):
        return any(filename.endswith(extension) for extension in [
            '.png', '.tif', '.jpg', '.jpeg', '.bmp', '.pgm', '.PNG'
        ])
    if __name__ == "__main__":
    
        input_list = [
            str(f) for f in Path(r'D:\superresolution\sharpen\cubic').iterdir() if is_image_file(f.name)
        ]
        print(len(input_list))
        for input_file in tqdm(input_list):
            # filename = r'D:\superresolution\sharpen\cubic\10_bicubic.png'
            filename = input_file
            out1 = sharpen(filename)
            out2 = excessive(filename)
            out3 = edge_enhance(filename)
            cv2.imwrite(filename[:-4] + '_shaprpen.png', out1)
            cv2.imwrite(filename[:-4] + '_shaprpen_excessive.png', out2)
            cv2.imwrite(filename[:-4] + '_shaprpen_edge.png', out3)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    3. 效果分析

    示例1.

    四个图分别是
    原图, sharpen
    enhance edge, excessive

    对字体的锐化, sharpen的效果最好
    enhance edge也有增强效果,但是背景颜色发生了变化
    excessive 变化较大。
    在这里插入图片描述

    示例2.

    sharpen会有较多artifact,锐化太强
    edge_enhance 效果较好,但是略微的亮度色彩偏差需要想办法避免

    会有

    4. usm方法

    int run_sharp_denoise() {//string file, float thr, float weight, float radius
        string file = "D:\\code\\denoise\\denoise_video\\guide_filter_image\\ccode\\cap_frame_143_gamma.png";
        
        Mat I = imread(file, 1);
        imwrite("src.png", I);
        // resize(I, I, Size(400, 400));
        //imwrite(file.substr(0, len - 4) + "_001.png", I);
        //printf("info : %d,%d,%d", I.rows, I.cols, I.channels());
        float thr = 10.0f/255;
        float weight = 0.5f;
        int radius = 25;
       
        Mat I1, blur, residual, mask, soft_mask;
        I.convertTo(I1, CV_32FC3, 1.0f/ 255);
        GaussianBlur(I1, blur, Size(radius, radius),  0);
        subtract(I1, blur, residual);
    
        mask = cv::abs(residual) > thr;
        mask.convertTo(mask, CV_32FC3, 1.0f/255);
        GaussianBlur(mask, soft_mask, Size(radius, radius),  0);
      
        Mat sharp = I1 + weight * residual;
        sharp = cv::max(cv::min(sharp, 1), 0);
    
        Mat Ione(soft_mask.cols, soft_mask.rows, CV_32FC3, cv::Scalar::all(1));
        Mat ret = sharp.mul(soft_mask) + I1.mul(Ione - soft_mask);
        //ret = cv::max(cv::min(ret, 1), 0);
        ret.convertTo(I, CV_8UC3, 255);
        imwrite("ret2.png", I);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    c++版本主要参考python版本:(from BasicSR)

    def usm_sharp(img, weight=0.5, radius=50, threshold=10):
        """USM sharpening.
    
        Input image: I; Blurry image: B.
        1. sharp = I + weight * (I - B)
        2. Mask = 1 if abs(I - B) > threshold, else: 0
        3. Blur mask:
        4. Out = Mask * sharp + (1 - Mask) * I
    
    
        Args:
            img (Numpy array): Input image, HWC, BGR; float32, [0, 1].
            weight (float): Sharp weight. Default: 1.
            radius (float): Kernel size of Gaussian blur. Default: 50.
            threshold (int):
        """
        if radius % 2 == 0:
            radius += 1
        blur = cv2.GaussianBlur(img, (radius, radius), 0)
        residual = img - blur
        mask = np.abs(residual) * 255 > threshold
        mask = mask.astype('float32')
        soft_mask = cv2.GaussianBlur(mask, (radius, radius), 0)
        #print('softmask :', soft_mask[:5,:5])
        sharp = img + weight * residual
        #print('sharp :',sharp[:5, :5, 1])
        #print('img', img[:5, :5, 0])
        sharp = np.clip(sharp, 0, 1)
        #print('I1:', img[:5, :5, 1])
        #print('1-soft:', (1 - soft_mask)[:5, :5])
        return soft_mask * sharp + (1 - soft_mask) * img
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
  • 相关阅读:
    轻松学会jQuery选择器的用法
    lunar-1.5.jar
    【算法】滑动窗口破解长度最小子数组
    水墨屏超高频电子标签|RFID电子纸之可视化标签组态软件操作流程
    丢掉乱七八糟的软件,留下这4个,让你告别索然无味
    Java集合(个人整理笔记)
    摄影后期色彩管理流程(Lightroom篇)
    Spring(十四)- Spring注解原理解析
    【机械仿真】基于matlab GUI直齿圆柱齿轮应力计算【含Matlab源码 2077期】
    PyTorch常用5个抽样函数
  • 原文地址:https://blog.csdn.net/tywwwww/article/details/127881063