画像データの水増し

画像データの水増し

Yolov8で使うファイルの水増しをする

回転以外で行うことは

1. 反転(Flipping): 画像を水平または垂直に反転させることで、新たな画像を生成します。物体が画像中で異なる方向に存在する場合の学習が可能になります。
2. スケーリング(Scaling): 画像のサイズを変更します。これにより、モデルが異なる解像度の画像に対しても頑健になります。
3. クロッピング(Cropping): 画像から一部を切り取ることで、モデルが部分的な視覚情報からも物体を識別できるようになります。ランダムクロッピングは特に有効です。
4. 色調の変更(Color Modification): 色の明度、コントラスト、彩度を変化させることで、異なる照明条件下での物体の見え方に対する耐性を高めます。
5. ノイズの追加: 画像にランダムなノイズを加えることで、モデルがノイズに対して頑健になります。例えばガウシアンノイズなどがあります。
6. ぼかし(Blurring): ガウシアンぼかし、平均ぼかしなどを画像に適用し、モデルが解像度の低い画像や細部がぼやけた画像にも対応できるようにします。
7. 画像のエラスティック変形(Elastic Transformations): 画像を局所的に引き伸ばしたり圧縮したりすることで、自然界で発生するさまざまな変形に対応します。
8. ランダムイラジ(Jittering): 色彩や輝度などの小さなランダムな変更を加えて、画像の見た目を微妙に変化させます。

なのでこれらを行うpythonスクリプトを作成する

pip install Pillow numpy

で必要なライブラリのインストール

import os
import numpy as np
from PIL import Image, ImageEnhance, ImageOps
import random

def rotate_image(image, degrees):
    return image.rotate(degrees, expand=True)

def color_change(image):
    enhancer = ImageEnhance.Color(image)
    factor = random.uniform(0.5, 1.5)  # 色の強さを変更
    return enhancer.enhance(factor)

def flip_image(image):
    if random.choice([True, False]):
        return image.transpose(Image.FLIP_LEFT_RIGHT)
    else:
        return image

def scale_image(image):
    scale_factor = random.uniform(0.75, 1.25)
    width, height = image.size
    new_width = int(width * scale_factor)
    new_height = int(height * scale_factor)
    return image.resize((new_width, new_height), Image.ANTIALIAS)

def add_noise(image):
    # PIL Imageをnumpy arrayに変換
    array = np.asarray(image)
    noise = np.random.randint(0, 50, array.shape, dtype='uint8')
    # ノイズを加えた後、再びPIL Imageに変換
    image = Image.fromarray(np.clip(array + noise, 0, 255).astype('uint8'), 'RGB')
    return image

def process_images(directory):
    for filename in os.listdir(directory):
        filepath = os.path.join(directory, filename)
        if filepath.lower().endswith(('.png', '.jpg', '.jpeg')):
            with Image.open(filepath) as img:
                for angle in range(0, 360, 45):
                    new_img = rotate_image(img, angle)
                    new_img = color_change(new_img)
                    new_img = flip_image(new_img)
                    new_img = scale_image(new_img)
                    new_img = add_noise(new_img)
                    new_img.save(os.path.join(directory, f'{filename[:-4]}_rot{angle}_mod.png'))

# 画像が保存されているディレクトリを指定してください
directory_path = 'path_to_your_images'
process_images(directory_path)


これらを行うコード

これを

vim augment_images.py

で作成して保存

ちなみに

#ドライブをマウント
from google.colab import drive
drive.mount('/content/drive')

の後に

cd /content/drive/MyDrive/InventoryControl/daily_necessities/baskulin
ls

でバスクリン画像の一覧が表示された

ということはおそらく各種ファイルを転送し
その後にスクリプトで増やせばいけるはず

コードを修正しimageフォルダ内を対象としたが
これだと回転以外の要素も全て行っている
そうではなく
それぞれの処理をしたファイルを生成して欲しいので
コードを変更する

rm -f image/*

で一度ファイルを削除し

cp data_bak/Baskulin1.jpg image

でバックアップから復元

pip install opencv-python-headless scipy

そしてコードを

import os
import numpy as np
from PIL import Image, ImageEnhance, ImageOps, ImageFilter
import random
import cv2  # OpenCVを使用

def rotate_image(image, degrees, directory, filename):
    new_img = image.rotate(degrees, expand=True)
    new_img.save(os.path.join(directory, f'{filename[:-4]}_rot{degrees}.png'))

def flip_image(image, directory, filename):
    # 水平反転
    new_img = image.transpose(Image.FLIP_LEFT_RIGHT)
    new_img.save(os.path.join(directory, f'{filename[:-4]}_fliph.png'))
    # 垂直反転
    new_img = image.transpose(Image.FLIP_TOP_BOTTOM)
    new_img.save(os.path.join(directory, f'{filename[:-4]}_flipv.png'))

def scale_image(image, directory, filename):
    scale_factor = random.uniform(0.75, 1.25)
    new_width = int(image.width * scale_factor)
    new_height = int(image.height * scale_transform)
    new_img = image.resize((new_width, new_height), Image.ANTIALIAS)
    new_img.save(os.path.join(directory, f'{filename[:-4]}_scaled.png'))

def crop_image(image, directory, filename):
    start_x = random.randint(0, int(image.width * 0.1))
    start_y = random.randint(0, int(image.height * 0.1))
    end_x = start_x + int(image.width * 0.8)
    end_y = start_y + int(image.height * 0.8)
    new_img = image.crop((start_x, start_y, end_x, end_y))
    new_img.save(os.path.join(directory, f'{filename[:-4]}_cropped.png'))

def color_change(image, directory, filename):
    factor = random.uniform(0.5, 1.5)
    enhancer = ImageEnhance.Color(image)
    new_img = enhancer.enhance(factor)
    new_img.save(os.path.join(directory, f'{filename[:-4]}_colorchg.png'))

def add_noise(image, directory, filename):
    array = np.array(image)
    noise = np.random.normal(0, 25, image.size)
    new_img = Image.fromarray(np.clip(array + noise[:, :, None], 0, 255).astype('uint8'), 'RGB')
    new_img.save(os.path.join(directory, f'{filename[:-4]}_noise.png'))

def blur_image(image, directory, filename):
    new_img = image.filter(ImageFilter.GaussianBlur(radius=5))
    new_img.save(os.path.join(directory, f'{filename[:-4]}_blurred.png'))

def elastic_transform(image, directory, filename):
    alpha = image.width * 2
    sigma = image.width * 0.08
    random_state = np.random.RandomState(None)
    shape = image.size[::-1]
    dx = gaussian_filter((random_state.rand(*shape) * 2 - 1), sigma, mode="constant", cval=0) * alpha
    dy = gaussian_filter((random_state.rand(*shape) * 2 - 1), sigma, mode="constant", cval=0) * alpha
    x, y = np.meshgrid(np.arange(shape[0]), np.arange(shape[1]), indexing="ij")
    indices = np.reshape(x + dx, (-1, 1)), np.reshape(y + dy, (-1, 1))
    distored_image = map_coordinates(np.array(image), indices, order=1, mode='reflect')
    new_img = Image.fromarray(distored_image.astype('uint8'), 'RGB')
    new_img.save(os.tmp.join(directory, f'{filename[:-4]}_elastic.png'))

def jitter_image(image, directory, filename):
    new_img = ImageEnhance.Brightness(image).enhance(random.uniform(0.5, 1.5))
    new_img = ImageEnhance.Contrast(new_img).enhance(random.uniform(0.5, 1.5))
    new_img.save(os.path.join(directory, f'{filename[:-4]}_jittered.png'))

def process_images(directory):
    for filename in os.listdir(directory):
        filepath = os.path.join(directory, filename)
        if filepath.lower().endswith(('.png', '.jpg', '.jpeg')):
            with Image.open(filepath) as img:
                for angle in [0, 45, 90, 135, 180, 225, 270, 315]:
                    rotate_image(img, angle, directory, filename)
                flip_image(img, directory, filename)
                scale_image(img, directory, filename)
                crop_image(img, directory, filename)
                color_change(img, directory, filename)
                add_noise(img, directory, filename)
                blur_image(img, directory, filename)
                elastic_transform(img, directory, filename)
                jitter_image(img, directory, filename)

directory_path = 'images'
process_images(directory_path)

へ変更し

python augment_images.py

で実行

しかし

Traceback (most recent call last):
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 85, in <module>
    process_images(directory_path)
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 76, in process_images
    scale_image(img, directory, filename)
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 22, in scale_image
    new_height = int(image.height * scale_transform)
NameError: name 'scale_transform' is not defined

となる

となるため

def scale_image(image, directory, filename):
    scale_factor = random.uniform(0.75, 1.25)  # スケーリングファクターをランダムに選択
    new_width = int(image.width * scale_factor)  # 正しい変数名で幅を計算
    new_height = int(image.height * scale_factor)  # 正しい変数名で高さを計算
    new_img = image.resize((new_width, new_height), Image.ANTIALIAS)  # 画像をリサイズ
    new_img.save(os.path.join(directory, f'{filename[:-4]}_scaled.png'))  # 保存

にコードを変更

今度は

/Users/snowpool/aw10s/inventory/augment_images.py:23: DeprecationWarning: ANTIALIAS is deprecated and will be removed in Pillow 10 (2023-07-01). Use LANCZOS or Resampling.LANCZOS instead.
  new_img = image.resize((new_width, new_height), Image.ANTIALIAS)  # 画像をリサイズ
Traceback (most recent call last):
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 86, in <module>
    process_images(directory_path)
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 82, in process_images
    elastic_transform(img, directory, filename)
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 56, in elastic_transform
    dx = gaussian_filter((random_state.rand(*shape) * 2 - 1), sigma, mode="constant", cval=0) * alpha
NameError: name 'gaussian_filter' is not defined

となる

再度コードを変更

1. ANTIALIAS を LANCZOS に修正する
Pillowライブラリで ANTIALIAS が非推奨になったため、これを LANCZOS に置き換えることで解決します。以下が修正後の scale_image 関数です:


def scale_image(image, directory, filename):
    scale_factor = random.uniform(0.75, 1.25)
    new_width = int(image.width * scale_factor)
    new_height = int(image.height * scale_factor)
    new_img = image.resize((new_width, new_height), Image.LANCZOS)  # LANCZOSを使用
    new_img.save(os.path.join(directory, f'{filename[:-4]}_scaled.png'))


gaussian_filter の未定義問題を解決する
gaussian_filter 関数が未定義というエラーを修正するために、scipy.ndimage から gaussian_filter をインポートする必要があります。また、map_coordinates 関数も同様にインポートする必要があります。以下が修正後の elastic_transform 関数と、必要なインポート文です

がGPTの答えだったので

from scipy.ndimage import gaussian_filter, map_coordinates

def elastic_transform(image, directory, filename):
    alpha = image.width * 2
    sigma = image.width * 0.08
    random_state = np.random.RandomState(None)
    shape = image.size[::-1]
    dx = gaussian_filter((random_state.rand(*shape) * 2 - 1), sigma, mode="constant", cval=0) * alpha
    dy = gaussian_filter((random_state.rand(*shape) * 2 - 1), sigma, mode="constant", cval=0) * alpha
    x, y = np.meshgrid(np.arange(shape[0]), np.arange(shape[1]), indexing="ij")
    indices = (np.reshape(x + dx, (-p, 1)), np.reshape(y + dy, (-1, 1)))
    distorted_image = map_coordinates(np.array(image), indices, order=1, mode='reflect')
    new_img = Image.fromarray(distorted_image.astype('uint8'), 'RGB')
    new_img.save(os.path.join(directory, f'{filename[:-4]}_elastic.png'))

これを実行したら

Traceback (most recent call last):
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 89, in <module>
    process_images(directory_path)
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 85, in process_images
    elastic_transform(img, directory, filename)
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 62, in elastic_transform
    indices = (np.reshape(x + dx, (-p, 1)), np.reshape(y + dy, (-1, 1)))
NameError: name 'p' is not defined. Did you mean: 'np'?

となるのでこれを修正

このログでGPTで調べる

lastic_transform 関数内で未定義の変数 p を使用していることがわかります。これはおそらく -1 を意図していたものと思われます。さらに、indices の設定に関するエラーも修正する必要があります。これを修正して、適切なインデックスの形状に合わせましょう。
以下は修正後の elastic_transform 関数
from scipy.ndimage import gaussian_filter, map_coordinates

def elastic_transform(image, directory, filename):
    alpha = image.width * 2
    sigma = image.width * 0.08
    random_state = np.random.RandomState(None)
    shape = image.size[::-1]
    dx = gaussian_filter((random_state.rand(*shape) * 2 - 1), sigma, mode="constant", cval=0) * alpha
    dy = gaussian_filter((random_yes.rand(*shape) * 2 - 1), sigma, mode="constant", cval=0) * alpha
    x, y = np.meshgrid(np.arange(shape[0]), np.arange(shape[1]), indexing="ij")
    indices = np.reshape(np.array([x + dx, y + dy]), (2, -1))
    distorted_image = map_coordinates(np.array(image), indices, order=1, mode='reflect')
    new_img = Image.fromarray(distorted_image.astype('uint8'), 'RGB')
    new_img.save(os.path.join(directory, f'{filename[:-4]}_elastic.png'))

今度は

Traceback (most recent call last):
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 90, in <module>
    process_images(directory_path)
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 84, in process_images
    add_noise(img, directory, filename)
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 44, in add_noise
    new_img = Image.fromarray(np.clip(array + noise[:, :, None], 0, 255).astype('uint8'), 'RGB')
ValueError: operands could not be broadcast together with shapes (4080,3072,3) (3072,4080,1) 

というエラーになるため
コードを

def add_noise(image, directory, filename):
    array = np.array(image)
    # 正しい形状のノイズを生成
    noise = np.random.normal(0, 25, array.shape)
    # ノイズを加えた画像を作成
    noisy_array = np.clip(array + noise, 0, 255).astype('uint8')
    new_img = Image.fromarray(noisy_array, 'RGB')
    new_img.save(os.path.join(directory, f'{filename[:-4]}_noise.png'))

へ変更

このエラーは、add_noise 関数内で、ノイズを加えようとした際に配列の形状が一致しないため発生しています。具体的には、画像データ array と生成したノイズ noise の形状が異なっています

再度実行すると

Traceback (most recent call last):
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 94, in <module>
    process_images(directory_path)
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 90, in process_images
    elastic_transform(img, directory, filename)
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 64, in elastic_transform
    dy = gaussian_filter((random_yes.rand(*shape) * 2 - 1), sigma, mode="constant", cval=0) * alpha
NameError: name 'random_yes' is not defined

となる

これは単純にタイプミスで
random_yes を random_state に修正

今度は

Traceback (most recent call last):
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 94, in <module>
    process_images(directory_path)
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 90, in process_images
    elastic_transform(img, directory, filename)
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 67, in elastic_transform
    distorted_image = map_coordinates(np.array(image), indices, order=1, mode='reflect')
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/scipy/ndimage/_interpolation.py", line 440, in map_coordinates
    raise RuntimeError('invalid shape for coordinate array')
RuntimeError: invalid shape for coordinate array

となる

from scipy.ndimage import gaussian_filter, map_coordinates

def elastic_transform(image, directory, filename):
    alpha = image.width * 2
    sigma = image.width * 0.08
    random_state = np.random.RandomState(None)
    shape = image.size[::-1]  # width, height

    # dx, dy を生成
    dx = gaussian_filter((random_state.rand(*shape) * 2 - 1), sigma, mode="constant", cval=0) * alpha
    dy = gaussian_filter((random_state.rand(*shape) * 2 - 1), sigma, mode="constant", cval=0) * alpha

    x, y = np.meshgrid(np.arange(shape[0]), np.arange(shape[1]), indexing="ij")
    
    # 正しい形状でインデックスを作成
    indices = np.vstack((x.ravel() + dx.ravel(), y.ravel() + dy.ravel()))  # 2xN の形状

    # 座標変換を適用
    distorted_image = map_coordinates(np.array(image), indices, order=1, mode='reflect')

    # 新しい画像を生成
    new_img = Image.fromarray(distorted_image.reshape(image.size).astype('uint8'), 'RGB')
    new_img.save(os.path.join(directory, f'{filename[:-4]}_elastic.png'))

というように修正

indices の配列を2行(x座標、y座標)の形状に整形しています。np.vstack を使用して2つの1次元配列を縦に積み重ね、期待される形状を作成しています。
distorted_image の生成時に reshape を適用して画像の元の形状を復元しています。

なお画像認識で文字の反転は不要なので削除する

# flip_image(img, directory, filename) # この行を削除
として、flip_image 関数自体を削除するのではなく、その呼び出しをコメントアウトまたは削除しています。将来的に反転が必要になった場合に簡単に再導入できるようにするため

今度は

Traceback (most recent call last):
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 104, in <module>
    process_images(directory_path)
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 100, in process_images
    elastic_transform(img, directory, filename)
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 75, in elastic_transform
    distorted_image = map_coordinates(np.array(image), indices, order=1, mode='reflect')
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/scipy/ndimage/_interpolation.py", line 440, in map_coordinates
    raise RuntimeError('invalid shape for coordinate array')
RuntimeError: invalid shape for coordinate array

となる

なので変更

重要な修正点
* np.meshgrid を使用して x, y の座標を生成する際、indexing='ij' の指定を取り除き、順序を逆にして np.arange(shape[1]), np.arange(shape[0]) としています。これにより、x と y の座標を正しく取得します。
* indices の形状を (2, M) に正しく設定しています。vstack で縦に積み重ね、ピクセルの y 座標と x 座標を合わせています。

とのこと

from scipy.ndimage import gaussian_filter, map_coordinates

def elastic_transform(image, directory, filename):
    alpha = image.width * 2
    sigma = image.width * 0.08
    random_state = np.random.RandomState(None)
    shape = image.size[::-1]  # (width, height)

    # dx, dy を生成
    dx = gaussian_filter((random_state.rand(*shape) * 2 - 1), sigma, mode="constant", cval=0) * alpha
    dy = gaussian_filter((random_state.rand(*shape) * 2 - 1), sigma, mode="constant", cval=0) * alpha

    x, y = np.meshgrid(np.arange(shape[1]), np.arange(shape[0]))  # (height, width) 形式で生成されたグリッド
    indices = np.vstack((y.ravel() + dy.ravel(), x.ravel() + dx.ravel()))  # y座標、x座標の順に並べる

    # 座標変換を適用
    distorted_image = map_coordinates(np.array(image), indices, order=1, mode='reflect')
    new_img = Image.fromarray(distorted_image.astype('uint8'), 'RGB')
    new_img.save(os.path.join(directory, f'{filename[:-4]}_elastic.png'))

へ変更し保存

Traceback (most recent call last):
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 98, in <module>
    process_images(directory_path)
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 94, in process_images
    elastic_transform(img, directory, filename)
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 71, in elastic_transform
    distorted_image = map_coordinates(np.array(image), indices, order=1, mode='reflect')
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/scipy/ndimage/_interpolation.py", line 440, in map_coordinates
    raise RuntimeError('invalid shape for coordinate array')
RuntimeError: invalid shape for coordinate array

となる

from scipy.ndimage import gaussian_filter, map_coordinates
import numpy as np
from PIL import Image

def elastic_transform(image, directory, filename):
    alpha = image.width * 2  # 変形の強さを設定
    sigma = image.width * 0.08  # ガウスフィルタの標準偏差を設定
    random_state = np.random.RandomState(None)
    shape = image.size  # PIL Imageのsizeは(width, height)

    # ランダム変位を生成
    dx = gaussian_filter((random_state.rand(*shape[::-1]) * 2 - 1), sigma, mode="constant", cval=0) * alpha
    dy = gaussian_filter((random_state.rand(*shape[::-1]) * 2 - 1), sigma, mode="constant", cval=0) * alpha

    # グリッドを生成
    x, y = np.meshgrid(np.arange(shape[0]), np.arange(shape[1]), indexing='ij')
    indices = np.vstack((y.flatten() + dy.flatten(), x.flatten() + dx.flatten()))  # 2xNの形状

    # 座標変換を適用
    distorted_image = map_coordinates(np.array(image), indices, order=1, mode='reflect')

    # 新しい画像を作成
    new_img = Image.fromarray(distorted_image.reshape(shape[::-1]).astype('uint8'), 'RGB')
    new_img.save(os.path.join(directory, f'{filename[:-4]}_elastic.png'))

へコード変更

shape = image.sizeで取得したサイズ(width, height)は、numpyの操作に合わせてshape[::-1]((height, width))を使っています。
indices配列を生成する際、np.vstackを使ってy座標とx座標を適切に並べて(2, M)形状にしています。
map_coordinatesの引数に渡すindicesが(2, M)形状であることを確認してください。この形状が要求されるため、それに従っています。

今度は

Traceback (most recent call last):
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 103, in <module>
    process_images(directory_path)
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 99, in process_images
    elastic_transform(img, directory, filename)
  File "/Users/snowpool/aw10s/inventory/augment_images.py", line 74, in elastic_transform
    distorted_image = map_coordinates(np.array(image), indices, order=1, mode='reflect')
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/scipy/ndimage/_interpolation.py", line 440, in map_coordinates
    raise RuntimeError('invalid shape for coordinate array')
RuntimeError: invalid shape for coordinate array

今度は

from scipy.ndimage import gaussian_filter, map_coordinates
import numpy as np
from PIL import Image

def elastic_transform(image, directory, filename):
    alpha = image.width * 2  # 変形の強さを設定
    sigma = image.width * 0.08  # ガウスフィルタの標準偏差を設定
    random_state = np.random.RandomState(None)
    shape = image.size[::-1]  # PIL Imageのsizeは(width, height)、numpyでのshapeは(height, width)

    # ランダム変位を生成
    dx = gaussian_filter((random_state.rand(*shape) * 2 - 1), sigma, mode="constant", cval=0) * alpha
    dy = gaussian_filter((random_state.rand(*shape) * 2 - 1), sigma, mode="constant", cval=0) * alpha

    # グリッドを生成
    x, y = np.meshgrid(np.arange(shape[1]), np.arange(shape[0]))  # (height, width) 形式で生成されたグリッド
    indices = np.vstack((x.flatten() + dx.flatten(), y.flatten() + dy.flatten()))  # x座標、y座標の順に並べる

    # 座標変換を適用
    distorted_array = map_coordinates(np.array(image), indices, order=1, mode='reflect')
    distorted_image = Image.fromarray(distorted_array.reshape(shape).astype('uint8'), 'RGB')
    distorted_image.save(os.path.join(directory, f'{filename[:-4]}_elastic.png'))

indicesの生成を再確認し、正しい形状(2, M)が生成されていることを保証します。
map_coordinatesへの入力としてindicesが(2, M)形状であることを再確認します。これにはx.flatten()とy.flatten()を正しく配置しています。

何度やっても画像のエラスティック変形でエラーになるので
機能を削除

import os
import numpy as np
from PIL import Image, ImageEnhance, ImageOps, ImageFilter
import random

def rotate_image(image, degrees, directory, filename):
    new_img = image.rotate(degrees, expand=True)
    new_img.save(os.path.join(directory, f'{filename[:-4]}_rot{degrees}.png'))

def scale_image(image, directory, filename):
    scale_factor = random.uniform(0.75, 1.25)
    new_width = int(image.width * scale_factor)
    new_height = int(image.height * scale_factor)
    new_img = image.resize((new_width, new_height), Image.LANCZOS)
    new_img.save(os.path.join(directory, f'{filename[:-4]}_scaled.png'))

def crop_image(image, directory, filename):
    start_x = random.randint(0, int(image.width * 0.1))
    start_y = random.randint(0, int(image.height * 0.1))
    end_x = start_x + int(image.width * 0.8)
    end_y = start_y + int(image.height * 0.8)
    new_img = image.crop((start_x, start_y, end_x, end_y))
    new_img.save(os.path.join(directory, f'{filename[:-4]}_cropped.png'))

def color_change(image, directory, filename):
    factor = random.uniform(0.5, 1.5)
    enhancer = ImageEnhance.Color(image)
    new_img = enhancer.enhance(factor)
    new_img.save(os.path.join(directory, f'{filename[:-4]}_colorchg.png'))

def add_noise(image, directory, filename):
    img_array = np.array(image)
    noise = np.random.normal(0, 25, img_array.shape)
    noisy_array = np.clip(img_array + noise, 0, 255).astype('uint8')
    new_img = Image.fromarray(noisy_array, 'RGB')
    new_img.save(os.path.join(directory, f'{filename[:-4]}_noise.png'))

def blur_image(image, directory, filename):
    new_img = image.filter(ImageFilter.GaussianBlur(radius=5))
    new_img.save(os.path.join(directory, f'{filename[:-4]}_blurred.png'))

def process_images(directory):
    for filename in os.listdir(directory):
        filepath = os.path.join(directory, filename)
        if filepath.lower().endswith(('.png', '.jpg', '.jpeg')):
            with Image.open(filepath) as img:
                for angle in [0, 45, 90, 135, 180, 225, 270, 315]:
                    rotate_image(img, angle, directory, filename)
                scale_image(img, directory, filename)
                crop_image(img, directory, filename)
                color_change(img, directory, filename)
                add_noise(img, directory, filename)
                blur_image(img, directory, filename)
                # elastic_transform 呼び出しを削除しました

# ディレクトリパスを指定
directory_path = 'images'
process_images(directory_path)

これでようやく成功
元画像に対し12の画像が作成される

とりあえず成功したので

cp data_bak/Baskulin*.jpg image 

でバックアップから画像を戻し

python augment_images.py

で画像を増やす

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です