OpenCV/OpenCV 강좌

OpenCV Python + pyQt5 구현 - 두 개의 이미지 더하는 블렌딩

webnautes 2024. 8. 28. 23:26
반응형

두 장의 이미지의 투명도를 조정하여 두 개의 이미지가 겹쳐보이게 하는 블렌딩(Blending)을 구현한 OpenCV Python 예제 코드를 테스트하기 쉽도록  pyQt5로 작성된 UI를 사용합니다. 



2024. 8. 28 최초작성  




OpenCV Python만을 사용하여 구현한 코드는 아래 포스트에서 구현되어 있습니다.

 

OpenCV Python 강좌 - 두 개의 이미지 더하기, 블렌딩

https://webnautes.tistory.com/1245




pyQt5를 사용하여 이미지의 투명도를 조정하게 만든 예제를 실행시키면 슬라이더를 사용하여 두 장의 이미지의 투명도를 조정할 수 있습니다.



실행하면 두 장의 이미지가 겹쳐서 보이게 됩니다. 2장의 이미지의 투명도가 각각 50%이기 때문입니다.

 

 




어느 한쪽으로 이동하면 한장의 이미지만 투명도가 0%되고 다른 이미지는 투명도가 100%되어 한장의 이미지만 보이게 됩니다.

 

 



전체 코드입니다.

 

import sys
import cv2
import numpy as np
from PyQt5.QtWidgets import QApplication, QWidget, QSlider, QHBoxLayout, QVBoxLayout, QLabel
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QImage, QPixmap

class ImageBlendingApp(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('이미지 블렌딩')
        self.setGeometry(100, 100, 800, 600)


        file1 = '거북이.jpg'
        file2 = '토끼.jpg'

        self.image1_name = file1.split('.')[0]
        self.image2_name = file2.split('.')[0]

        # 이미지 로드 (예시 이미지, 실제 사용 시 경로를 수정해야 합니다)
        self.img1 = cv2.imread(file1)
        self.img2 = cv2.imread(file2)
       
        # 이미지 크기 맞추기
        self.img1 = cv2.resize(self.img1, (400, 400))
        self.img2 = cv2.resize(self.img2, (400, 400))


        self.image_label1 = QLabel()

        self.img1_samll = cv2.resize(self.img1, (100, 100))
        # BGR to RGB 변환
        rgb_image1 = cv2.cvtColor(self.img1_samll, cv2.COLOR_BGR2RGB)

        # numpy 배열을 QImage로 변환
        h, w, ch = rgb_image1.shape
        bytes_per_line = ch * w
        qt_image1 = QImage(rgb_image1.data, w, h, bytes_per_line, QImage.Format_RGB888)

        # QImage를 QPixmap으로 변환
        pixmap1 = QPixmap.fromImage(qt_image1)

        # QLabel에 QPixmap 설정
        self.image_label1.setPixmap(pixmap1)
        self.image_label1.setScaledContents(True# 이미지를 라벨 크기에 맞게 조정



        self.image_label2 = QLabel()

        self.img2_samll = cv2.resize(self.img2, (100, 100))
        # BGR to RGB 변환
        rgb_image2 = cv2.cvtColor(self.img2_samll, cv2.COLOR_BGR2RGB)

        # numpy 배열을 QImage로 변환
        h, w, ch = rgb_image2.shape
        bytes_per_line = ch * w
        qt_image2 = QImage(rgb_image2.data, w, h, bytes_per_line, QImage.Format_RGB888)

        # QImage를 QPixmap으로 변환
        pixmap2 = QPixmap.fromImage(qt_image2)

        # QLabel에 QPixmap 설정
        self.image_label2.setPixmap(pixmap2)
        self.image_label2.setScaledContents(True# 이미지를 라벨 크기에 맞게 조정


        # 메인 레이아웃
        main_layout = QVBoxLayout()

        # 이미지 표시 레이블
        self.image_label = QLabel()
        self.image_label.setAlignment(Qt.AlignCenter)
        main_layout.addWidget(self.image_label)

        # 슬라이더 생성
        self.slider = QSlider(Qt.Horizontal)
        self.slider.setMinimum(0)
        self.slider.setMaximum(100)
        self.slider.setValue(50)
        self.slider.setTickPosition(QSlider.TicksBelow)
        self.slider.setTickInterval(10)

        # 슬라이더 레이아웃
        slider_layout = QHBoxLayout()

        slider_left_layout = QVBoxLayout()
        self.label_left = QLabel(f'{self.image1_name}\n100%') # 파일 이름으로 바꾸기
        slider_left_layout.addWidget(self.label_left)
        slider_left_layout.addWidget(self.image_label1)

        slider_right_layout = QVBoxLayout()
        self.label_right = QLabel(f'{self.image2_name}\n100%'# 파일 이름으로 바꾸기
        slider_right_layout.addWidget(self.label_right)
        slider_right_layout.addWidget(self.image_label2)

        self.label_left.setAlignment(Qt.AlignCenter)
        self.label_right.setAlignment(Qt.AlignCenter)
        slider_layout.addLayout(slider_left_layout)        # 왼쪽 라벨
        slider_layout.addWidget(self.slider)            # 슬라이더
        slider_layout.addLayout(slider_right_layout)       # 오른쪽 라벨

        main_layout.addLayout(slider_layout)

        self.setLayout(main_layout)

        # 슬라이더 값 변경 시 호출될 함수 연결
        self.slider.valueChanged.connect(self.updateImage)

        # 초기 이미지 표시
        self.updateImage()

    def updateImage(self):
        value = self.slider.value() / 100
        # 이미지 블렌딩
        blended = cv2.addWeighted(self.img1, 1 - value, self.img2, value, 0)
       
        # OpenCV BGR 이미지를 RGB로 변환
        rgb_image = cv2.cvtColor(blended, cv2.COLOR_BGR2RGB)
       
        # NumPy 배열을 QImage로 변환
        h, w, ch = rgb_image.shape
        bytes_per_line = ch * w
        qt_image = QImage(rgb_image.data, w, h, bytes_per_line, QImage.Format_RGB888)
       
        # QImage를 QPixmap으로 변환하고 라벨에 표시
        pixmap = QPixmap.fromImage(qt_image)
        self.image_label.setPixmap(pixmap)
       
        # 라벨 업데이트
        self.label_left.setText(f'{self.image1_name}\n{(1-value)*100:.0f}%')   # 파일 이름으로 바꾸기
        self.label_right.setText(f'{self.image2_name}\n{value*100:.0f}%')     # 파일 이름으로 바꾸기

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = ImageBlendingApp()
    ex.show()
    sys.exit(app.exec_())


반응형