OpenCV에서 효율적으로 자르기를 시도했습니다.

기계 학습을 할 때는 우선 교사 데이터의 전처리가 중요하다고 합니다.
그리고 화상 처리로 물체 인식을 할 때는 학습하고 싶은 물체만 트리밍하여 낭비를 없애고 싶네요?
하지만 일부러 이미지 편집 소프트웨어를 사용하여 자르고 저장하는 것도 번거롭습니다.
그래서 이번에는 OpenCV를 사용하여 효율적으로 수동으로 트리밍하는 방법을 소개합니다.

이번에 할 일



디렉터리의 이미지를 한꺼번에 가져와서 다음과 같이 한 장씩 학습할 영역을 잘라낼 수 있습니다.
잘린 이미지는 저장 디렉토리에 저장됩니다.


잘라낼 영역 선택



우선은 드래그&드롭으로 화상상의 선택 영역의 원점이 되는 x축, y축, 높이, 폭의 정보를 취하려면 cv2.selectROI 를 사용하면 영역 선택하는 화면이 간단하게 서 있습니다.
잘라낼 영역을 선택한 후 Enter 키를 누르면 선택 영역의 좌표 정보를 튜플로 얻을 수 있습니다.
(C 키를 누르면 취소되고 (0. 0. 0, 0)가 반환됩니다.)
selected = cv2.selectROI(img)

선택 영역의 좌표 정보를 얻으면 이미지 데이터를 잘라낼 수 있습니다.
imCrop = img[int(selected[1]):int(selected[1]+selected[3]),
                         int(selected[0]):int(selected[0]+selected[2])]

나머지는 잘라낸 이미지 데이터를 저장하기만 하면 됩니다.
cv2.imwrite(file_dir, imCrop)

완성된 코드



파일의 패스 조작에 관한 코드도 맞춘 완성형은 이쪽입니다.
Windows와 UNIX계에서도 사용할 수 있도록 패스의 서식을 통일하고 있습니다.

trim_image.py

import cv2
import os
import sys

if __name__ == '__main__':
    args = sys.argv
    data_dir = args[1].replace('\\', '/')
    annotated_dir = data_dir + 'trimed'
    os.mkdir(annotated_dir)
    files = os.listdir(data_dir)
    img_files = [
        f for f in files if '.jpeg' in f or '.jpg' in f or '.png' in f]
    print(img_files)
    for img_file in img_files:
        # Read image
        img_dir = data_dir + img_file
        img = cv2.imread(img_dir)

        # Select ROI
        selected = cv2.selectROI(img)
        if sum(selected):
            # Crop image
            imCrop = img[int(selected[1]):int(selected[1]+selected[3]),
                         int(selected[0]):int(selected[0]+selected[2])]
            # write annotated img
            file_dir = annotated_dir + '/' + img_file
            cv2.imwrite(file_dir, imCrop)
            print('saved!')

다음 명령을 사용하여 이미지 데이터가 저장된 디렉터리의 경로를 지정하여 디렉터리의 이미지를 일괄 트리밍할 수 있습니다.
트리밍한 이미지 데이터는 디렉토리에 작성한 trimed 디렉토리에 저장됩니다.
python trim_image.py path/to/img_dir

좋은 웹페이지 즐겨찾기