直接上代码
"""
Created on Thu Apr 23 22:29:54 2020
@author: Administrator
"""
import numpy as np
import cv2
from PIL import Image
from matplotlib import pyplot as plt
class VisualEffect:
"""
生成从给定间隔均匀采用的视觉效果参数
参数:
contrast_factor: 对比度因子:调整对比度的因子区间,应该在0-3之间
brightness_delta: 亮度增量:添加到像素的量在-1和1之间的间隔
hue_delta:色度增量:为添加到色调通道的量在-1和1之间的间隔
saturation_factor:饱和系数:因子乘以每个像素的饱和值的区间
"""
def __init__(
self,
contrast_factor,
brightness_delta,
hue_delta,
saturation_factor
):
self.contrast_factor = contrast_factor
self.brightness_delta = brightness_delta
self.hue_delta = hue_delta
self.saturation_factor = saturation_factor
def __call__(self, image):
"""
将视觉效果应用到图片上
"""
if self.contrast_factor:
image = self.adjust_contrast(image, self.contrast_factor)
if self.brightness_delta:
image = self.adjust_brightness(image, self.brightness_delta)
if self.hue_delta or self.saturation_factor:
image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
if self.hue_delta:
image = self.adjust_hue(image, self.hue_delta)
if self.saturation_factor:
image = self.adjust_saturation(image, self.saturation_factor)
image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
return image
def adjust_saturation(self, image, factor):
"""
调整图片的饱和度
"""
image[..., 1] = np.clip(image[..., 1] * factor, 0, 255)
return image
def adjust_hue(self, image, delta):
"""
调整图片的色度
添加到色调通道的量在-1和1之间的间隔。
如果值超过180,则会旋转这些值。
"""
image[...,0] = np.mod(image[...,0] + delta * 180, 180)
return image
def adjust_contrast(self, image, factor):
"""
调整一张图像的对比度
"""
mean = image.mean(axis=0).mean(axis=0)
return self._clip((image - mean) * factor + mean)
def adjust_brightness(self,image,delta):
"""
调整一张图片的亮度
"""
return self._clip(image + delta * 255)
def _clip(self,image):
"""
剪辑图像并将其转换为np.uint8
"""
return np.clip(image, 0, 255).astype(np.uint8)
def _uniform(val_range):
"""
随机返回值域之间的数值
"""
return np.random.uniform(val_range[0], val_range[1])
def _check_range(val_range, min_val=None, max_val=None):
"""
检查间隔是否有效
"""
if val_range[0] > val_range[1]:
raise ValueError('interval lower bound > upper bound')
if min_val is not None and val_range[0] < min_val:
raise ValueError('invalid interval lower bound')
if max_val is not None and val_range[1] > max_val:
raise ValueError('invalid interval upper bound')
def random_visual_effect_generator(
contrast_range=(0.9 ,1.1),
brightness_range=(-.1, .1),
hue_range=(-0.05, 0.05),
saturation_range=(0.95, 1.05)):
_check_range(contrast_range, 0)
_check_range(brightness_range, -1, 1)
_check_range(hue_range, -1, 1)
_check_range(saturation_range, 0)
def _generate():
while True:
yield VisualEffect(
contrast_factor=_uniform(contrast_range),
brightness_delta=_uniform(brightness_range),
hue_delta=_uniform(hue_range),
saturation_factor=_uniform(saturation_range)
)
return _generate()
if __name__ == "__main__":
path = "C:/Users/Administrator/Desktop/learning_image/lena.jpg"
image = np.asarray(Image.open(path))
visual_effect_generator = random_visual_effect_generator(
contrast_range=(0.9, 1.1),
brightness_range=(-0.1, 0.1),
hue_range=(-0.05, 0.05),
saturation_range=(0.95, 1.05)
)
visual_effect = next(visual_effect_generator)
image = visual_effect(image)
plt.imshow(image)
以lena图为例
调整之前
调整后