딥러닝 데이터를 늘리기 위한 이미지 제너레이터 만들기

7) 이미지 제너레이터 만들기 - 이미지 늘릴때 진행상황 프로그레스바로 나타내기

잡동사니123 2023. 2. 28. 14:00

기본 준비

  • 진행상황은 별도의 창을 띄워서 알릴 예정이다. 따라서 별도의 창을 띄우기 위한 준비를 한다.
  • 먼저 ui를 받아온다.(클래스 밖에 작성해야함)
generating_class = uic.loadUiType("ui/generating.ui")[0]

 

  • 기본 틀 클래스를 만든다.
class Generating(QDialog, generating_class):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

 

창 띄우기

  • 프로그레스바는 generate/save 버튼을 눌렀을떄 나오는 폴더 선택 창 다음으로 나오도록 할것이다. 기존에 만들어둔 generateAndSave 함수 안에 다음 코드를 삽입한다. 폴더 선택을 안했을 경우에는 굳이 프로그레스 창을 띄울 필요가 없으므로 기존에 만들어둔 if문 안에 넣었다.
  • 코드를 실행하면 창이 나타난다. 하지만 아무 움직임도 없고 버튼 클릭 반응도 없다.
def generateAndSave(self):
    # 저장할 폴더 위치 가져오기
    save_folder = QFileDialog.getExistingDirectory(self, '저장할 폴더 선택')

    if bool(save_folder):
        # 프로그레스 창 띄우기
        generating = Generating()
        generating.exec_()
    
    # 코드 생략

 

프로그레스바 실시간으로 색이 채워지도록 하기

  • WindowClass의 generateAndSave 함수를 다음과 같이 수정한다.
def generateAndSave(self):
    # 저장할 폴더 위치 가져오기
    save_folder = QFileDialog.getExistingDirectory(self, '저장할 폴더 선택')

    if bool(save_folder):
        # 제너레이터에 넣을 속성값 프로그램에서 가져오기
        count = self.count_spinBox.value()
        horizontalFlip = self.horizontalFlip_comboBox.currentText() == 'True'
        widthShiftRange = self.widthShiftRange_SpinBox.value()
        heightShiftRange = self.heightShiftRange_spinBox.value()
        rotationRange = self.rotationRange_spinBox.value()
        shearRange = self.shearRange_spinBox.value()
        zoomRange = self.zoomRange_spinBox.value()
        verticalFlip = self.verticalFlip_comboBox.currentText() == 'True'
        fillMode = self.fillMode_comboBox.currentText()

        # 사용자 속성에 맞춘 이미지 제너레이터 준비
        datagen = ImageDataGenerator(horizontal_flip=horizontalFlip, width_shift_range=widthShiftRange,
                                     height_shift_range=heightShiftRange, rotation_range=rotationRange,
                                     shear_range=shearRange, zoom_range=zoomRange,
                                     vertical_flip=verticalFlip, fill_mode=fillMode)

        # 프로그레스 창 띄우기
        generating = Generating(len(self.files_root) * count, count, save_folder, datagen, self.files_root)
        generating.exec_()

 

  • Generating 클래스를 다음과 같이 수정한다.
class Generating(QDialog, generating_class):
    def __init__(self, total_count, count, save_folder, datagen, files_root):
        super().__init__()
        self.setupUi(self)

        # 클래스 내에서 사용할 변수
        self.total_count = total_count  # 전체 이미지 개수
        self.now_count = 0  # 현재 처리된 이미지 개수
        self.count = count
        self.save_folder = save_folder
        self.datagen = datagen
        self.files_root = files_root

        # 이벤트 추가
        self.ok_button.clicked.connect(self.close)  # 버튼을 누르면 해당 창 종료
        QTimer.singleShot(7, self.generateAndSave)  # 대기 거는 코드, 없으면 설정한 ui가 뜨지 않음

    def updateProgress(self):
        self.now_count = self.now_count + 1  # 진행된 갯수 +1 시키기
        nowValue = int(self.now_count / self.total_count * 100)  # 현재 진행 퍼센트 계산
        self.progressbar.setValue(nowValue)  # 값 반영시키기
        time.sleep(0.001)  # 대기 거는 코드, 없으면 프로그레스바 수치가 올라가는것이 표시되지 않는다.

    def generateAndSave(self):
        # 실제로 이미지를 제너레이터를 이용하여 생성하는 코드
        for i in self.files_root:
            img = load_img(i)
            x = img_to_array(img)
            x = x.reshape((1,) + x.shape)
            idx = 0
            for batch in self.datagen.flow(x, batch_size=1):
                name = os.path.splitext(os.path.basename(i))[0]  # 경로에서 이름만 추출해서 name 변수에 저장
                path = self.save_folder + '/' + name + str(idx) + '.jpg'  # 원하는 경로+이미지원본이름+사진 번호+확장자 로 path 지정
                array_to_img(batch[0]).save(path, 'jpeg')  # 실질적으로 이미지 저장하는 코드
                idx += 1
                QTimer.singleShot(1, self.updateProgress)  # 대기 걸면서 프로그레스바 업데이트 함수 실행
                if idx == self.count:
                    break
                    
        self.ok_button.setEnabled(True)  # 확인 버튼 활성화

 

 

생성이 다 완료된 후의 모습(프로그레스 바 창 끄기 전)