참고(이분 책 보고 opencv 공부 많이 했다 ㅎㅎ)
결론을 이야기하자면 opencv로 작업하려면 numpy로 배열을 받고 QImage → QPixmap으로 변환해야 한다.
import sys, cv2
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
def open_movie():
print("동영상 불러오기를 성공하였습니다.")
class MyWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("physics Lab")
self.setGeometry(300, 300, 400, 400)
self.setWindowIcon(QIcon("physics.png"))
# 상태바 생성
self.status_bar = QStatusBar()
self.setStatusBar(self.status_bar)
self.img_label = QLabel(parent=self)
self.img_label.move(10, 10)
self.btn = QPushButton(text = "이미지 열기", parent = self)
self.btn.move(250, 10)
self.btn.clicked.connect(self.btn_clicked)
self.btn2 = QPushButton(text = "이미지 삭제", parent = self)
self.btn2.move(250, 50)
self.btn2.clicked.connect(self.btn2_clicked)
def btn_clicked(self):
fname, _ = QFileDialog.getOpenFileName(self, "Choose File", "", "All files(*)")
# 사용자가 파일 선택을 취소한 경우
if not fname: # fname이 빈 문자열일 경우
self.status_bar.showMessage("파일 선택이 취소되었습니다.")
return # 아무 작업도 하지 않고 함수 종료
img = cv2.imread(fname)
if img is None: # 이미지가 제대로 읽히지 않은 경우
self.status_bar.showMessage("이미지를 불러오는 데 실패하였습니다.")
return # 에러 처리 후 함수 종료
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
h, w, c = img.shape
qImg = QImage(img.data, w, h, w*c, QImage.Format_RGB888)
self.pixmap = QPixmap.fromImage(qImg)
self.img_label.resize(200, 200)
self.pixmap = self.pixmap.scaled(200, 200)
self.img_label.setPixmap(self.pixmap)
self.status_bar.showMessage("이미지를 불러오는 데 성공하였습니다.")
def btn2_clicked(self):
self.img_label.clear()
self.status_bar.clearMessage()
app = QApplication(sys.argv)
win = MyWindow()
win.show()
app.exec_()
여기서 주목해야 할 것은 btn_clicked 함수이다.
fname, _ = QFileDialog.getOpenFileName(self, "Choose File", "", "All files(*)")
- QFileDialog.getOpenFileName 함수를 호출하여 파일 선택 창을 엽니다. 사용자가 선택한 파일의 경로는 fname에 저장됩니다.
- "Choose File"은 다이얼로그의 제목이며, ""는 기본 경로, "All files(*)"는 선택 가능한 파일 형식을 의미합니다.
if not fname:
self.status_bar.showMessage("파일 선택이 취소되었습니다.")
return
- fname이 빈 문자열인지 확인합니다. 빈 문자열인 경우 사용자가 파일 선택을 취소한 것이므로, 사용자에게 메시지를 출력하고 함수를 종료합니다.
img = cv2.imread(fname)
- cv2.imread 함수를 사용하여 선택한 파일 경로 fname에서 이미지를 읽어옵니다. 이때 img 변수는 이미지 데이터를 포함하는 NumPy 배열입니다.
if img is None:
self.status_bar.showMessage("이미지를 불러오는 데 실패하였습니다.")
return
- cv2.imread가 실패했을 경우(img가 None인 경우)에도 적절한 에러 메시지를 출력하고 함수를 종료합니다.
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
- OpenCV는 기본적으로 이미지를 BGR 형식으로 읽어옵니다. 따라서, 이를 RGB 형식으로 변환하기 위해 cv2.cvtColor 함수를 사용합니다.
- cv2.COLOR_BGR2RGB는 BGR 색상 공간에서 RGB 색상 공간으로의 변환을 나타냅니다.
h, w, c = img.shape
- img.shape를 통해 이미지의 높이(h), 너비(w), 채널 수(c)를 가져옵니다. 이 정보는 QImage 객체를 생성할 때 필요합니다.
qImg = QImage(img.data, w, h, w*c, QImage.Format_RGB888)
- QImage는 PyQt에서 이미지를 다루기 위한 객체입니다. 이 객체는 OpenCV의 NumPy 배열을 사용하여 생성됩니다.
- img.data는 이미지의 픽셀 데이터에 대한 포인터입니다.
- w, h는 이미지의 너비와 높이입니다.
- w*c는 각 행의 바이트 수 (너비 * 채널 수)입니다.
- QImage.Format_RGB888는 RGB 형식을 지정합니다.
self.pixmap = QPixmap.fromImage(qImg)
- QPixmap.fromImage 메서드를 사용하여 QImage를 QPixmap으로 변환합니다. QPixmap은 화면에 이미지를 표시하는 데 최적화된 객체입니다.
self.img_label.resize(200, 200)
self.pixmap = self.pixmap.scaled(200, 200)
self.img_label.setPixmap(self.pixmap)
- self.img_label.resize(200, 200)는 이미지 라벨의 크기를 200x200 픽셀로 설정합니다.
- self.pixmap.scaled(200, 200)는 QPixmap을 200x200 픽셀로 조정합니다.
- self.img_label.setPixmap(self.pixmap)는 조정된 QPixmap을 라벨에 설정하여 이미지를 화면에 표시합니다.
실행결과
이미지 열기를 클릭하면...
파일 열기창이 뜬다.
불러오기 성공! (Status bar 상태 바에도 뜬다)
이미지 삭제를 누르면 사라진다.
'파이썬 프로그래밍 > PyQt5 공부하기' 카테고리의 다른 글
7. PyQt5 쓰레드 사용하기 (0) | 2024.11.25 |
---|---|
6. PyQt5와 opencv 연동하기 : 동영상 불러오기 (0) | 2024.11.24 |
4. PyQt5 기초(Box배치, Grid배치) (0) | 2024.11.11 |
3. PyQt5 기초(툴바, 스타일) (0) | 2024.11.10 |
2. PyQt5 기초(툴팁, 상태바, 동작정의, 메뉴바) (0) | 2024.11.09 |