数据增强(噪声,模糊,缩放,色域变换,均衡化,色彩抖动)

Posted 小谭爱学习

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据增强(噪声,模糊,缩放,色域变换,均衡化,色彩抖动)相关的知识,希望对你有一定的参考价值。

本篇为处女作,请大家多多指教。

在做深度学习时,数据的处理是重中之重。在做自己的数据集时,可能会面临数据图像数目不均衡,数据量少的困扰。本篇文章就是介绍图像增强的方法,对图像进行增强,增加图像的数目。

一、增加噪声

在图像中增加适量噪声可以增强学习能力。噪声有很多种,常见的有椒盐噪声,高斯噪声等。

1.椒盐噪声:一种随机出现的白点或者黑点,可能是亮的区域有黑色像素或是在暗的区域有白色像素(或是两者皆有)。

#添加椒盐噪声
def sp_noise(image):
      output = np.zeros(image.shape,np.uint8)
      prob=rand(0.0005,0.001)  #随机噪声比例
      thres = 1 - prob 
      for i in range(image.shape[0]):
          for j in range(image.shape[1]):
              rdn = random.random()
              if rdn < prob:
                output[i][j] = 0
              elif rdn > thres:
                output[i][j] = 255
              else:
                output[i][j] = image[i][j]
      return output

2.高斯噪声:概率密度函数服从高斯分布。

def gasuss_noise(image, mean=0, var=0.001):

    '''
        添加高斯噪声
        mean : 均值
        var : 方差
    '''
    image = np.array(image/255, dtype=float)
    noise = np.random.normal(mean, var ** 0.5, image.shape)
    out = image + noise
    if out.min() < 0:
        low_clip = -1.
    else:
        low_clip = 0.
    out = np.clip(out, low_clip, 1.0)
    out = np.uint8(out*255)
    return out

     

                                          

            

二、滤波(模糊)处理

滤波处理主要是让图像变得模糊,提取图像的重要信息。常见的模糊处理有:高斯模糊,中值模糊,均值(椒盐)模糊。

卷积核大小一般为奇数:(3,3)、(5,5)、(7,7)

#利用opencv模块
img1 = cv2.blur(img,(5,5))  #中值滤波
img2 = cv2.medianBlur(img,5)  #椒盐滤波
img3 = cv2.GaussianBlur(img,(5,5),0)  #高斯滤波

                    

三、旋转

图像的大小不变,可以将图像进行上下旋转,左右旋转等增加数据量,一般根据自己的需求,有些数据旋转之后就不符合原数据的要求了。

#利用pil模块
img=Iamge.open('xxx')

#1.自定义旋转的角度 
img2 = img.rotate(90) 

#2.引用固定的常量值  
img2 = im.transpose(Image.FLIP_LEFT_RIGHT)    #镜像旋转
img2 = im.transpose(Image.FLIP_TOP_BOTTOM)    #上下旋转

 

                                    

 

      此处其实没必要进行翻转,因为会不符合要求。所以要根据自己的需求进行选择。

四、图像缩放

可以通过改变图像的大小对数据增强,但有可能会引起图像的失真。

def change_scale(image,input_shape,jitter=.5) 
    iw, ih = image.size
    h, w = input_shape 
    # 对图像进行缩放并且进行长和宽的扭曲 
    new_ar = w/h * rand(1-jitter,1+jitter)/rand(1-jitter,1+jitter) 
    scale = rand(.15,2.5) 
    if new_ar < 1: 
        nh = int(scale*h) 
        nw = int(nh*new_ar) 
    else: 
        nw = int(scale*w) 
        nh = int(nw/new_ar) 
        image = image.resize((nw,nh), Image.BICUBIC) 
    retuen image

          

五、色彩抖动

色彩抖动是通过随机调整原始图片的饱和度,亮度,对比度来对产生新的图像,增加数据集

def randomColor(image):
    #随机生成0,1来随机确定调整哪个参数,可能会调整饱和度,也可能会调整图像的饱和度和亮度
    saturation=random.randint(0,1)
    brightness=random.randint(0,1)
    contrast=random.randint(0,1)
    sharpness=random.randint(0,1)

    #当三个参数中一个参数为1,就可执行相应的操作
    if random.random() < saturation:
        random_factor = np.random.randint(0, 31) / 10.  # 随机因子
        image = ImageEnhance.Color(image).enhance(random_factor)  # 调整图像的饱和度
    if random.random() < brightness:
        random_factor = np.random.randint(10, 21) / 10.  # 随机因子
        image = ImageEnhance.Brightness(image).enhance(random_factor)  # 调整图像的亮度
    if random.random() < contrast:
        random_factor = np.random.randint(10, 21) / 10.  # 随机因1子
        image = ImageEnhance.Contrast(image).enhance(random_factor)  # 调整图像对比度
    if random.random() < sharpness:
        random_factor = np.random.randint(0, 31) / 10.  # 随机因子
        ImageEnhance.Sharpness(image).enhance(random_factor)  # 调整图像锐度
    return image

                               

 色彩抖动之后的图像可以根据自己的需求进行删减,对于一些阴间图像可以剔除掉。

六、图像均衡化

#限制对比度自适应直方图均衡
def clahe(image):
    b, g, r = cv2.split(image)
    clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
    b = clahe.apply(b)
    g = clahe.apply(g)
    r = clahe.apply(r)
    image_clahe = cv2.merge([b, g, r])
    return image_clahe

#伽马变换
def gamma(image):
        fgamma = rand(0,2)
        image_gamma = np.uint8(np.power((np.array(image) / 255.0), fgamma) * 255.0)
        cv2.normalize(image_gamma, image_gamma, 0, 255, cv2.NORM_MINMAX)
        cv2.convertScaleAbs(image_gamma, image_gamma)
        return image_gamma

#直方图均衡
def hist(image):
        r, g, b = cv2.split(image)
        r1 = cv2.equalizeHist(r)
        g1 = cv2.equalizeHist(g)
        b1 = cv2.equalizeHist(b)
        image_equal_clo = cv2.merge([r1, g1, b1])
        return image_equal_clo

                         

全部代码

#已有:翻转,色域变换,噪声,大小改变,模糊,色彩抖动,均衡化
import cv2
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image,ImageEnhance
from matplotlib.colors import rgb_to_hsv, hsv_to_rgb
import os
import random

#限制对比度自适应直方图均衡
def clahe(image):
    b, g, r = cv2.split(image)
    clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
    b = clahe.apply(b)
    g = clahe.apply(g)
    r = clahe.apply(r)
    image_clahe = cv2.merge([b, g, r])
    return image_clahe
#伽马变换
def gamma(image):
        fgamma = 2
        image_gamma = np.uint8(np.power((np.array(image) / 255.0), fgamma) * 255.0)
        cv2.normalize(image_gamma, image_gamma, 0, 255, cv2.NORM_MINMAX)
        cv2.convertScaleAbs(image_gamma, image_gamma)
        return image_gamma
#直方图均衡
def hist(image):
        r, g, b = cv2.split(image)
        r1 = cv2.equalizeHist(r)
        g1 = cv2.equalizeHist(g)
        b1 = cv2.equalizeHist(b)
        image_equal_clo = cv2.merge([r1, g1, b1])
        return image_equal_clo
#椒盐噪声
def sp_noise(image):
      output = np.zeros(image.shape,np.uint8)
      prob=rand(0.0005,0.001)
      thres = 1 - prob 
      for i in range(image.shape[0]):
          for j in range(image.shape[1]):
              rdn = random.random()
              if rdn < prob:
                output[i][j] = 0
              elif rdn > thres:
                output[i][j] = 255
              else:
                output[i][j] = image[i][j]
      return output
#色彩抖动
def randomColor(image):
    saturation=random.randint(0,1)
    brightness=random.randint(0,1)
    contrast=random.randint(0,1)
    sharpness=random.randint(0,1)
    if random.random() < saturation:
        random_factor = np.random.randint(0, 31) / 10.  # 随机因子
        image = ImageEnhance.Color(image).enhance(random_factor)  # 调整图像的饱和度
    if random.random() < brightness:
        random_factor = np.random.randint(10, 21) / 10.  # 随机因子
        image = ImageEnhance.Brightness(image).enhance(random_factor)  # 调整图像的亮度
    if random.random() < contrast:
        random_factor = np.random.randint(10, 21) / 10.  # 随机因1子
        image = ImageEnhance.Contrast(image).enhance(random_factor)  # 调整图像对比度
    if random.random() < sharpness:
        random_factor = np.random.randint(0, 31) / 10.  # 随机因子
        ImageEnhance.Sharpness(image).enhance(random_factor)  # 调整图像锐度
    return image
def rand(a=0, b=1): 
    return np.random.rand()*(b-a) + a 

def get_data(image,input_shape=[200,200],random=True, jitter=.5,hue=.1, sat=1.5, val=1.5, proc_img=True):
    iw, ih = image.size
    h, w = input_shape 
    # 对图像进行缩放并且进行长和宽的扭曲 
    new_ar = w/h * rand(1-jitter,1+jitter)/rand(1-jitter,1+jitter) 
    scale = rand(.15,2.5) 
    if new_ar < 1: 
        nh = int(scale*h) 
        nw = int(nh*new_ar) 
    else: 
        nw = int(scale*w) 
        nh = int(nw/new_ar) 
        image = image.resize((nw,nh), Image.BICUBIC) 
     # 翻转图像 
    flip = rand()<.5 
    if flip:
      image = image.transpose(Image.FLIP_LEFT_RIGHT)
    #噪声或者虚化,二选一
    image = cv2.cvtColor(np.asarray(image), cv2.COLOR_RGB2BGR)
    a1=np.random.randint(0, 3)
    if a1==0:   
      image=sp_noise(image)
    elif a1==1:
      image=cv2.GaussianBlur(image, (5, 5), 0)
    else:
      image=image
    #均衡化
    index_noise = np.random.randint(0, 10)
    print(index_noise)
    if index_noise==0:
        image = hist(image)
        print('hist,done')
    elif index_noise==1:
         image = clahe(image)
         print('clahe,done')
    elif index_noise==2:
         image = gamma(image)
         print('gamma,done')
    else:
         image=image
    
    image = Image.fromarray(cv2.cvtColor(image,cv2.COLOR_BGR2RGB))
    #色彩抖动
    image=randomColor(image)
    print(image.size)
    # 色域扭曲 
    hue = rand(-hue, hue) 
    sat = rand(1, sat) if rand()<.5 else 1/rand(1, sat) 
    val = rand(1, val) if rand()<.5 else 1/rand(1, val) 
    x = rgb_to_hsv(np.array(image)/255.)
    x[..., 0] += hue 
    x[..., 0][x[..., 0]>1] -= 1 
    x[..., 0][x[..., 0]<0] += 1 
    x[..., 1] *= sat 
    x[..., 2] *= val 
    x[x>1] = 1 
    x[x<0] = 0 
    image_data = hsv_to_rgb(x)

    image_data=np.array(image)
    return image_data

if __name__ == "__main__":
   
    #图像批量处理
    dirs='./class_pic3/407_3/'   #原始图像所在的文件夹
    dets='./class_pic3/dets/407_3/'   #图像增强后存放的文件夹
    mylist=os.listdir(dirs)
    l=len(mylist)       #文件夹图片的数量
    for j in range(0,l):
        image = cv2.imread(dirs+mylist[j])
        img = Image.fromarray(np.uint8(image))
        for i in range(0,2):      #自定义增强的张数
            img_ret=get_data(img)   
            #imwrite(存入图片路径+图片名称+‘.jpg’,img)
            #注意:名称应该是变化的,不然会覆盖原来的图片        
            cv2.imwrite(dets+'1'+str(j)+'0'+str(i)+'.jpg',img_ret)   
            print('done')

    #单个图像处理
    '''          
    image=cv2.imread("./class_pic3/323/002.jpg")
    img = Image.fromarray(np.uint8(image))
    for i in range(0,4):
      img_ret=get_data(img)
      cv2.imwrite('./class_pic3/323'+'02'+str(i)+'.jpg',img_ret)
      print('done')
    '''

大家可以根据自己的需求对代码有所调整。

以上是关于数据增强(噪声,模糊,缩放,色域变换,均衡化,色彩抖动)的主要内容,如果未能解决你的问题,请参考以下文章

深度学习正则化---数据增强

OpenCV图像增强---灰度变换直方图均衡化

直方图均衡化

现有一含有椒盐噪声的图像image.jpg如何增强该图像,写出matlab程序

为啥原图像减去拉普拉斯变换的图像是锐化

图像增强基于模糊集的图像增强matlab源码