圖像增強

import numpy as np
import matplotlib.pyplot as plt
from skimage.io import *
from skimage.transform import *
import scipy.ndimage as ndi


img = imread('test_image/0--Parade_0_Parade_marchingband_1_353.jpg')
print(img.shape)
# 修改圖片尺寸(resize)
resized_image = resize(img,(1024,1280))
print(resized_image.shape)

# plt.imshow(resized_image)

#按比例縮放(rescale)
rescaled_img = rescale(img,[0.6,0.5])
print(rescaled_img.shape)
imshow(rescaled_img)
plt.show()

#隨機生成5000個椒鹽噪聲
height,weight,channel = img.shape
img1=img.copy()
for i in range(5000):
    x = np.random.randint(0,height)
    y = np.random.randint(0,weight)
    img1[x ,y ,:] = 255

plt.imshow(img1)
plt.show()

#垂直翻轉
vertical_flip = img[::-1,:,:]
imshow(vertical_flip)
plt.show()

#水平翻轉
horizontal_flip = img[:,::-1,:]
imshow(horizontal_flip)
plt.show()

#旋轉
rotate_img = rotate(img,30)#逆時針旋轉30°
imshow(rotate_img)
plt.show()



def transform_matrix_offset_center(matrix, x, y):
    o_x = float(x) / 2 + 0.5
    o_y = float(y) / 2 + 0.5
    offset_matrix = np.array([[1, 0, o_x], [0, 1, o_y], [0, 0, 1]])
    reset_matrix = np.array([[1, 0, -o_x], [0, 1, -o_y], [0, 0, 1]])
    transform_matrix = np.dot(np.dot(offset_matrix, matrix), reset_matrix)
    return transform_matrix
def apply_transform(x,
                    transform_matrix,
                    channel_axis=0,
                    fill_mode='nearest',
                    cval=0.):
    """Apply the image transformation specified by a matrix.
    應用矩陣指定的圖像變換。
    # Arguments
    參數
        x: 2D numpy array, single image.
        x: 二維數字陣列,單個圖像。
        transform_matrix: Numpy array specifying the geometric transformation.
        transform_matrix: 指定幾何變換的Numpy數組。
        channel_axis: Index of axis for channels in the input tensor.
        channel_axis: 輸入張量中的通道的軸的索引。
        fill_mode: Points outside the boundaries of the input
            are filled according to the given mode
            (one of `{'constant', 'nearest', 'reflect', 'wrap'}`).
        fill_mode: 輸入的邊界之外的點根據給定的模式({常數”、“最近”、“反射”、“包裝”}中的一個填充。
        cval: Value used for points outside the boundaries
            of the input if `mode='constant'`.
        cval: 如果mode='constant',則用於輸入邊界以外的點的值。
    # Returns
    返回
        The transformed version of the input.
        輸入的轉換版本。
    """
    x = np.rollaxis(x, channel_axis, 0)
    final_affine_matrix = transform_matrix[:2, :2]
    final_offset = transform_matrix[:2, 2]
    channel_images = [ndi.interpolation.affine_transform(
        x_channel,
        final_affine_matrix,
        final_offset,
        order=1,
        mode=fill_mode,
        cval=cval) for x_channel in x]
    x = np.stack(channel_images, axis=0)
    x = np.rollaxis(x, 0, channel_axis + 1)
    return x

#原圖大小旋轉
def rotate(x, theta, row_axis=0, col_axis=1, channel_axis=2, fill_mode='nearest', cval=0.):
    rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0],
                                [np.sin(theta), np.cos(theta), 0],
                                [0, 0, 1]])
    h, w = x.shape[row_axis], x.shape[col_axis]
    transform_matrix = transform_matrix_offset_center(rotation_matrix, h, w)
    x = apply_transform(x, transform_matrix, channel_axis, fill_mode, cval)
    return x

rotate_limit=(-30, 30)
theta = np.pi / 180 * np.random.uniform(rotate_limit[0], rotate_limit[1]) #逆時針旋轉角度
#rotate_limit= 30 #自定義旋轉角度
#theta = np.pi /180 *rotate_limit #將其轉換爲PI
img_rot = rotate(img, theta)
plt.imshow(img_rot)
plt.show()

#分別向左和向上偏移原尺寸的0.1倍
def shift(x, wshift, hshift, row_axis=0, col_axis=1, channel_axis=2, fill_mode='nearest', cval=0.):
    h, w = x.shape[row_axis], x.shape[col_axis] #讀取圖片的高和寬
    tx = hshift * h #高偏移大小,若不偏移可設爲0,若向上偏移設爲正數
    ty = wshift * w #寬偏移大小,若不偏移可設爲0,若向左偏移設爲正數
    translation_matrix = np.array([[1, 0, tx],
                                  [0, 1, ty],
                                  [0, 0, 1]])
    transform_matrix = translation_matrix
    x = apply_transform(x, transform_matrix, channel_axis, fill_mode, cval)
    return x

w_limit=(-0.2, 0.2)
h_limit=(-0.2, 0.2)
wshift = np.random.uniform(w_limit[0], w_limit[1])
hshift = np.random.uniform(h_limit[0], h_limit[1])
#wshift = 0.1 #自定義平移尺寸
#hshift = 0.1 #自定義平移尺寸

img_shift = shift(img, wshift, hshift)
plt.imshow(img_shift)
plt.show()

def zoom(x, zx, zy, row_axis=0, col_axis=1, channel_axis=2, fill_mode='nearest', cval=0.):
    zoom_matrix = np.array([[zx, 0, 0],
                            [0, zy, 0],
                            [0, 0, 1]])
    h, w = x.shape[row_axis], x.shape[col_axis]
    transform_matrix = transform_matrix_offset_center(zoom_matrix, h, w) #保持中心座標不改變
    x = apply_transform(x, transform_matrix, channel_axis, fill_mode, cval)
    return x

zoom_range=(0.7, 1)
zx, zy = np.random.uniform(zoom_range[0], zoom_range[1], 2)

#zx = 0.5
#zy = 0.5 #自定義zoom尺寸
img_zoom = zoom(img, zx, zy)
plt.imshow(img_zoom)
plt.show()

#帶角度剪切
def shear(x, shear, row_axis=0, col_axis=1, channel_axis=2, fill_mode='nearest', cval=0.):
    shear_matrix = np.array([[1, -np.sin(shear), 0],
                            [0, np.cos(shear), 0],
                            [0, 0, 1]])
    h, w = x.shape[row_axis], x.shape[col_axis]
    transform_matrix = transform_matrix_offset_center(shear_matrix, h, w)
    x = apply_transform(x, transform_matrix, channel_axis, fill_mode, cval)
    return x

intensity = 0.5
sh = np.random.uniform(-intensity, intensity) #逆時針方向剪切強度爲正
img_shear = shear(img, sh)

plt.imshow(img_shear)
plt.show()

#對比度變換,圖像的HSV顏色空間,改變H,S和V亮度分量,增加光照變化
from skimage import color

def randomHueSaturationValue(image, hue_shift_limit=(-180, 180),
                            sat_shift_limit=(-255, 255),
                            val_shift_limit=(-255, 255), u=0.5):
    if np.random.random() < u:
        img = color.rgb2hsv(image)
        h, s ,v = img[:,:,0],img[:,:,1],img[:,:,2]
        hue_shift = np.random.uniform(hue_shift_limit[0], hue_shift_limit[1])

        h = h + hue_shift

        sat_shift = np.random.uniform(sat_shift_limit[0], sat_shift_limit[1])
        s = s + sat_shift

        val_shift = np.random.uniform(val_shift_limit[0], val_shift_limit[1])
        v = v + val_shift

        img[:,:,0],img[:,:,1],img[:,:,2] = h, s ,v

        image = color.hsv2rgb(img)

    return image

contrast_img = randomHueSaturationValue(img)
plt.imshow(contrast_img)
plt.show()

#隨機通道偏移(channel shift)
def random_channel_shift(x, intensity, channel_index=0):
    x = np.rollaxis(x, channel_index, 0)
    min_x, max_x = np.min(x), np.max(x)
    channel_images = [np.clip(x_channel + np.random.uniform(-intensity, intensity), min_x, max_x)
                      for x_channel in x]
    x = np.stack(channel_images, axis=0)
    x = np.rollaxis(x, 0, channel_index+1)
    return x
img_chsh = random_channel_shift(img, intensity = 0.05)

plt.imshow(img_chsh)
plt.show()

#PCA
def RGB_PCA(images):
    pixels = images.reshape(-1, images.shape[-1])
    idx = np.random.random_integers(0, pixels.shape[0], 1000000)
    pixels = [pixels[i] for i in idx]
    pixels = np.array(pixels, dtype=np.uint8).T
    m = np.mean(pixels)/256.
    C = np.cov(pixels)/(256.*256.)
    l, v = np.linalg.eig(C)
    return l, v, m


def RGB_variations(image, eig_val, eig_vec):
    a = np.random.randn(3)
    v = np.array([a[0]*eig_val[0], a[1]*eig_val[1], a[2]*eig_val[2]])
    variation = np.dot(eig_vec, v)
    return image + variation

l,v,m = RGB_PCA(img)
img_pca = RGB_variations(img,l,v)
plt.imshow(img_pca)
plt.show()

另:

Augmentor

Augmentor的目的是進行自動的圖像增強(生成人造數據)爲了擴展數據集作爲機器學習算法的輸入,特別是神經網絡和深度學習。

這個包通過創建一個增強的pipeline,即定義一系列的操作。這些操作有比如旋轉和變換,一個加一個成爲一個增強的pipeline,當完成的時候,pipeline可以執行,增強之後的數據也創建成功。

我們可以使用一張圖像來完成一個增強的任務,演示一下Augmentor的pipeline和一些功能。

首先,導入包,初始化Pipeline對象,指定一個文件夾,這個文件夾裏放着你的圖像。

import Augmentor

p = Augmentor.Pipeline("/home/user/augmentor_data_tests")
然後你可以在pipeline中添加各種操作:

p.rotate90(probability=0.5)
p.rotate270(probability=0.5)
p.flip_left_right(probability=0.8)
p.flip_top_bottom(probability=0.3)
p.crop_random(probability=1, percentage_area=0.5)
p.resize(probability=1.0, width=120, height=120)
操作添加完了之後,可以進行採樣:

p.sample(100)


使用生成器和Keras集成
Augmentor 可以用來替換Keras中的augmentation功能。Augmentor 可以創建一個生產器來產生增強後的圖像,細節可以查看下面的notebook:

從本地文件夾中讀取圖像進行增強,然後使用生成器將增強的圖像流送到卷積神經網絡中,參見 https://github.com/mdbloice/Augmentor/blob/master/notebooks/Augmentor_Keras.ipynb

增強內存中的圖像,使用生成器將新的圖像送到Keras的網絡中,參見 https://github.com/mdbloice/Augmentor/blob/master/notebooks/Augmentor_Keras_Array_Data.ipynb

Augmentor 允許每個類定義不同的pipelines,這意味着你可以在分類問題中爲不同的類別定義不同的增強策略。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章