지정된 각도로 원본 이미지의 중심을 축으로 회전시킨 이미지를 만들고 저장합니다.

소개



딥 러닝으로 학습 이미지를 얻는 경우 다양한 각도에서 이미지를 얻음으로써 학습 정확도를 높이는 경우가 있습니다. 이 때 화상을 여러가지 각도로 다시 찍는 것이 귀찮기 때문에, 화상 처리로 학습 데이터의 물 증가를 실시하는 것으로 화상 촬영 작업의 효율화를 검토해 보았습니다.

덧붙여서, 학습 데이터의 물 증가 방법으로서, 노이즈를 늘리고, 콘트라스트를 바꾸고, 밝기를 바꾸는, 평활화, 확대 축소, 반전(좌우/상하), 회전, 시프트(수평/수직), 부분 마스크, 트리밍, 변형 , 변색, 배경의 변경 등이 있어 이용하고 있는 딥 러닝 라이브러리에 따라서는 물 증가 기능이 준비되어 있는 케이스가 있기 때문에, 환경에 따라서는 여기까지 자작할 필요는 없을지도 모릅니다.

덧붙여 적은 화상 데이터로 물 늘려 학습시키고 있는 경우, 특정의 데이터로만 인식하는 과 학습이 발생할 가능성이 있으므로, 이 툴은 PoC로 이용하는 레벨로 해 두는 등, 어디까지나 참고 정도로서 제발.

처리 개요



아핀 변환을 사용하여 주어진 이미지를 지정된 각도로 원 이미지의 중심을 축으로 회전시켜 이미지를 저장합니다. 이 때 이미지의 종횡 크기가 최대가 되도록 여백을 잡습니다.

파라미터를 지정하지 않고 data/maxgogo.jpg 에 이미지를 두고 실행하면, data 이하에 maxgogo_0.jpg ~maxgogo_xx.jpg 가 작성됩니다.
파라미터에 이미지 파일의 경로를 지정하면 이미지가 존재하는 디렉토리에 이미지명_0.jpg ~ 이미지명_xx.jpg가 작성됩니다.

이 회전 화상에 맞춘 Yolo용의 어노테이션 데이터 물 증가 툴은 여유가 있으면 후일 공개할까…

이용 예



■ 인수가없는 경우
data/maxgogo.jpg라는 파일을 저장합니다.
python img_rotation.py
실행합니다.

maxgogo.jpg


■ 인수 개미의 경우
python img_rotation.py 이미지 파일

소스 코드



img_rotation.py
# -*- coding: utf-8 -*-
import numpy as np
import cv2
import sys
import os

args = sys.argv
print("args=",args)
print(len(args))

if len(args) == 1:

    # パラメータを指定しない場合は、data/maxgogo.jpg というファイルが存在する前提です
    img_path = "data"
    img_name_body = "maxgogo"
    img_name_extension = ".jpg"

    img_name = img_name_body + img_name_extension

elif len(args) == 2: # 画像ファイルが指定される前提で細かいチェックしてません。

    base_dir_pair = os.path.split(args[1])
    img_path = base_dir_pair[0]
    root_ext_pair = os.path.splitext(base_dir_pair[1])
    img_name_body = root_ext_pair[0]
    img_name_extension = root_ext_pair[1]
    img_name = img_name_body + img_name_extension

    print(base_dir_pair)
    print("img_path=",img_path)
    print(root_ext_pair)
    print("img_name_body=",img_name_body)
    print("img_name_extension=",img_name_extension)

else :
    print("error path/filename")

# パスが無い場合を考慮した処理
if len(img_path) == 0:
    # 画像読み込み
    img = cv2.imread(img_name)
else:
    # 画像読み込み
    img = cv2.imread(img_path + os.sep + img_name)

if img is None:
        print("**************************")
        print("Failed to load image file.")
        print("**************************")
        sys.exit(1)

print(type(img))
print("size:",img.size)
h, w = img.shape[:2]
size = (w, h)

########################################################
# 回転角の指定 30 だと30度ごと。適当に変更してください。
########################################################
angle = 30

# 取得数 360度を回転角で割る
range_num = 360 // angle

# 指定した角度で回転した場合の最大の幅と高さを取得する
w_max = 0
h_max = 0

# 高さ、幅の最大値を取得
# ragne は 0 から始まり、指定した数-1 まで実行する。
for  num in range(range_num):

    angle_num = angle*num

    angle_rad = angle_num/180.0*np.pi

    # 回転後の画像サイズを計算
    w_rot = int(np.round(h*np.absolute(np.sin(angle_rad))+w*np.absolute(np.cos(angle_rad))))
    h_rot = int(np.round(h*np.absolute(np.cos(angle_rad))+w*np.absolute(np.sin(angle_rad))))

    if w_rot > w_max :
        w_max = w_rot
    if h_rot > h_max :
        h_max = h_rot

# 画像書き出し
for  num in range(range_num):

    angle_num = angle*num

    angle_rad = angle_num/180.0*np.pi

    size_rot = (w_max, h_max)

    # 元画像の中心を軸に回転する
    center = (w/2, h/2)
    scale = 1.0
    rotation_matrix = cv2.getRotationMatrix2D(center, angle_num, scale)

    # 平行移動を加える (rotation + translation)
    affine_matrix = rotation_matrix.copy()
    affine_matrix[0][2] = affine_matrix[0][2] -w/2 + w_max/2
    affine_matrix[1][2] = affine_matrix[1][2] -h/2 + h_max/2

    # アフィン変換
    img_rot = cv2.warpAffine(img, affine_matrix, size_rot, flags=cv2.INTER_CUBIC)

    # パスが無い場合を考慮した処理
    if len(img_path) == 0:
        writefile_name = img_name_body + "_" + str(num) + img_name_extension
    else:
        writefile_name = img_path + os.sep + img_name_body + "_" + str(num) + img_name_extension

    print (writefile_name)

    cv2.imshow(writefile_name, img_rot)
    cv2.imwrite(writefile_name, img_rot)

cv2.waitKey(0)


실행 결과





애니메이션 GIF화



마 군 눈이 돌고 ~


참고



htps : // m / 료코 my / ms / 0d1, 879 또는 c59, 0bfbdc5
를 참고로 변경하였습니다.

좋은 웹페이지 즐겨찾기