在图像锐化时,往往会 1. 放大 噪声,2. 引入aritfact, 3. 振铃效应 等负面效果
因此需要分析相关锐化方法的效果和副作用,避免图像失真。
这里只是介绍了比较基础的三个滤波核的表现,附上代码和图像效果。
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)
四个图分别是
原图, sharpen
enhance edge, excessive
对字体的锐化, sharpen的效果最好
enhance edge也有增强效果,但是背景颜色发生了变化
excessive 变化较大。
sharpen会有较多artifact,锐化太强
edge_enhance 效果较好,但是略微的亮度色彩偏差需要想办法避免
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;
}
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