CV 영상인식 기술을 적용하기 위해 바운딩박스를 그리다가
어느순간 내가 이걸 왜 하고 있지? 싶더라
노가다도 이런 노가다가 없는데 좀 더 편리하게 하기 위한 프로그램을 개발중이다.
일단 PyQt5를 이용해서 직접 바운딩박스를 그릴 수 있도록 적용해볼까 한다.
우선 세팅부터하자.
import sys
import cv2
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class MyApp(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('EasyBoxer') # 툴 제목
self.setGeometry(100, 100, 1000, 350) # 창의 위치&크기 (x,y,w,h)
# QWidget과 연결
self.cent_widget = CentWidget()
self.setCentralWidget(self.cent_widget.tabs)
self.show()
class CentWidget(QWidget):
def __init__(self):
super().__init__()
# 사진 보여줄 곳
self.img = QLabel()
self.img.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
self.img.setScaledContents(True)
self.img.setPixmap(QPixmap('./icon/flowers.jpg'))
# 테스트
self.lbl_test = QLabel()
self.lbl_test.setStyleSheet('background-color: #FFFFFF')
# 레이아웃
layout = QGridLayout()
layout.addWidget(self.img, 0, 0, 80, 80) # 사진
layout.addWidget(self.lbl_test, 0, 80, 5, 20)
main = QWidget()
main.setLayout(layout)
self.tabs = QTabWidget(self)
self.tabs.setFocusPolicy(Qt.NoFocus)
self.tabs.addTab(main, 'Main')
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MyApp()
sys.exit(app.exec_())
꽃밭 배경을 띄워보았다.
사진에 바운딩박스를 그리려면 사진에 직접 바운딩 박스를 그리는 방법이 하나,
또 다른 방법은 사진 위에 투명 이미지 하나를 올려서 바운딩 박스를 그리는 방법이 또 하나.
나는 후자의 방법을 택하기로 했다.
전자의 경우 바운딩 박스를 제거할 때 이미지가 훼손될 가능성이 보였기 때문이다.
일반적인 QLabel() 클래스에서 불가능하기 때문에 직접 QLable() 클래스를 상속해서 정의하도록 했다.
class DrawRectangle(QLabel):
def __init__(self):
super().__init__()
self.begin = QPoint()
self.destination = QPoint()
def paintEvent(self, e):
painter = QPainter(self)
painter.setPen(QPen(Qt.red, 3))
rect = QRect(self.begin, self.destination)
painter.drawRect(rect.normalized())
def mousePressEvent(self, e):
if e.button() == Qt.LeftButton:
self.begin = e.pos()
self.destination = self.begin
self.update()
def mouseMoveEvent(self, e):
if e.buttons() == Qt.LeftButton:
self.destination = e.pos()
self.update()
QPoint()는 좌표계(0, 0)을 의미하며, 정의된 라벨의 왼쪽 위 끝의 픽셀 좌표를 나타낸다.
painter.setPen을 이용하여 붉은색의 3픽셀 굵기로 박스를 그리기로 했다.
rect.normalized()는 꼭 사용하지 않아도 된다.
우측하단을 시작으로 잡고 왼쪽 상단으로 박스를 그릴 때 박스의 크기는 음수가 나올텐데 양수로 바꿔주는 역할이다.
Qt.LeftBetton은 마우스 왼쪽클릭 이벤트가 발생할 때를 의미한다.
따라서 우클릭하면 작동하지 않는다.
처음 mousePressEvent가 발생하면 시작점과 끝점이 동일한 박스를 그린다.
다음으로 mouseMoveEvent가 발생하면 끝점은 마우스 왼쪽 클릭의 좌표로 변경되며 업데이트 된다.
self.lbl_rect = DrawRectangle()
self.lbl_rect.setAttribute(Qt.WA_TranslucentBackground, True)
layout.addWidget(self.lbl_rect, 0, 0, 80, 80) # 바운딩 박스 팔레트
새롭게 정의한 DrawRentangle() 클래스를 기존 사진 위에 덧씌웠다.
Qt.WA_TranslucentBackground는 라벨을 투명하게 해준다.
박스가 잘 그려지는 것을 알 수 있다.
'PyQt5' 카테고리의 다른 글
QTableWidget 실행취소&다시실행 구현하기 (0) | 2022.05.30 |
---|---|
QSplitter 다루기 (0) | 2022.05.16 |
PyQt5를 이용하여 동영상 플레이어를 만들어보자(4) (0) | 2022.01.10 |
PyQt5를 이용하여 동영상 플레이어를 만들어보자(3) (0) | 2022.01.08 |
PyQt5를 이용하여 동영상 플레이어를 만들어보자(2) (0) | 2022.01.08 |
댓글