python提高图像质量
概述
调研了一些提高图像质量的方式
- 深度学习方法,如微软的Bringing-Old-Photos-Back-to-Life的模型等。存在一些问题,首先是使用深度学习方法没有刚好的模型,得在自己的数据集上微调,比较麻烦,其次是带来的推理时间开销会比较大,不是特别划算,毕竟只是一个小环节。
- 商用API,发现百度智能云提供了很多这方面的API,调用相当方便,但是免费次数有限啊。
- 基于python自带的PIL 实现图片亮度增强、饱和度增强、对比度增强以及锐度增强。
- 基于opencv实现数字图像处理!!!
百度智能云
官方教程:链接
参考代码(方便的一塌糊涂):
from aip import AipImageProcess
import base64
import os
APP_ID = ''
API_KEY = ''
SECRET_KEY = ''
client = AipImageProcess(APP_ID, API_KEY, SECRET_KEY)
""" 读取图片 """
def get_file_content(filePath):
with open(filePath, 'rb') as fp:
return fp.read()
def get_all_file(path):
all_file=[]
for i in os.listdir(path):
file_name=os.path.join(path,i)
all_file.append(file_name)
return all_file
for img_path in get_all_file('img'):
image = get_file_content(img_path)
""" 调用图像清晰度增强 """
if not os.path.exists('output'):
os.mkdir('output')
response = client.imageDefinitionEnhance(image)
imgdata = base64.b64decode(response['image'])
file = open(os.path.join('output', img_path.split('\\')[-1]), 'wb')
file.write(imgdata)
file.close()
PIL实现
from PIL import Image
from PIL import ImageEnhance
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['FangSong'] # 设置字体以便正确显示汉字
plt.rcParams['axes.unicode_minus'] = False # 正确显示连字符
# 原图
image = Image.open('img/timg.jpg')
# 亮度增强
enh_bri = ImageEnhance.Brightness(image)
brightness = 2
image_brightened = enh_bri.enhance(brightness)
# 色度增强(饱和度↑)
enh_col = ImageEnhance.Color(image)
color = 2
image_colored = enh_col.enhance(color)
# 对比度增强
enh_con = ImageEnhance.Contrast(image)
contrast = 2
image_contrasted = enh_con.enhance(contrast)
# 锐度增强
enh_sha = ImageEnhance.Sharpness(image)
sharpness = 4.0
image_sharped = enh_sha.enhance(sharpness)
fig,axes=plt.subplots(nrows=2,ncols=3,figsize=(10,8),dpi=100)
axes[0,0].imshow(np.array(image, dtype=np.uint8)[:,:,::-1])
axes[0,0].set_title("原图")
axes[0,1].imshow(np.array(image_brightened, dtype=np.uint8)[:,:,::-1])
axes[0,1].set_title("亮度增强")
axes[0,2].imshow(np.array(image_colored, dtype=np.uint8)[:,:,::-1])
axes[0,2].set_title("饱和度增强")
axes[1,0].imshow(np.array(image_contrasted, dtype=np.uint8)[:,:,::-1])
axes[1,0].set_title("对比度增强")
axes[1,1].imshow(np.array(image_sharped, dtype=np.uint8)[:,:,::-1])
axes[1,1].set_title("锐度增强")
axes[1,2].imshow(np.array(image_sharped, dtype=np.uint8)[:,:,::-1])
axes[1,2].set_title("锐度增强")
plt.show()
opencv实现
链接
python实现图像质量评价准则PSNR
计算PSNR的Python代码,网上有下面两种:
import cv2
import numpy as np
import math
def psnr1(img1, img2):
mse = np.mean((img1 - img2) ** 2 )
if mse < 1.0e-10:
return 100
return 10 * math.log10(255.0**2/mse)
def psnr2(img1, img2):
mse = np.mean( (img1/255. - img2/255.) ** 2 )
if mse < 1.0e-10:
return 100
PIXEL_MAX = 1
return 20 * math.log10(PIXEL_MAX / math.sqrt(mse))
理论上,这两种计算方式都对应上面的计算公式,在输入图像一样的情况下,这两段代码的结果应该是一样的。
但是,在调用这段代码的时候,我发现这两者的结果却相差很远,同样的图片,psnr1的结果大概是29,而psnr2的结果是12。
gt = cv2.imread('1.jpg')
img= cv2.imread('2.jpg')
print(psnr1(gt,img))
print(psnr2(gt,img))
单看代码的话完全看不出来任何问题,后来我输出了这两张图像作差的结果,发现所有的值都是在0-255之间的,比如img1的一个像素值是30,img2的一个像素值是60,二者作差,本来应该是-30,但是结果却是226,即对于负值,输出要加上256。
所以,问题就出在这行代码上:
mse = np.mean((img1 - img2) ** 2 )
如果img1某个点的像素比img2小,而两者差别又比较大,这个绝对值比较大的负值就会变成一个比较小的正值,MSE的结果也会偏小,那么PSNR的值就会偏大。
只要把上面那行代码改成mse = np.mean((img1/1.0 - img2/1.0) ** 2 )就可以了。
最后,我们发现这两个结果是一样的了。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。