본문 바로가기
코딩취미/Python

[파이썬] pygame과 opencv, pyqt의 동작방식의 차이점 정리 : 코드비교

by 브링블링 2024. 1. 26.
반응형

pygame과 opencv, pyqt의 동작방식의 차이점 정리 : 코드비교

Pygame, OpenCV, 그리고 PyQt는 각각 다른 목적과 기능을 가진 라이브러리입니다. 이들의 동작 방식, 차이점 및 비슷한 점은 아래에 정리합니다. 그리고 동일한 기능을 각각의 라이브러리를 사용해서 코드를 만들고 그 코드를 비교합니다.

Pygame

  • 동작 방식: 게임 개발을 위한 라이브러리로, 렌더링 루프와 이벤트 루프를 중심으로 작동합니다. 그래픽, 사운드, 입력 장치 등을 처리하기 위한 다양한 기능 제공.
  • 특징: 간단한 2D 게임 개발 및 그래픽 프로젝트에 적합. 사용이 쉽고, 빠른 프로토타이핑이 가능.
  • 차이점: 상대적으로 단순한 그래픽 처리에 초점. 사용자 인터페이스 기능이 제한적.

OpenCV

  • 동작 방식: 이미지 및 비디오 처리에 중점을 둔 라이브러리. 실시간 컴퓨터 비전을 위한 기능 제공.
  • 특징: 복잡한 이미지 및 비디오 분석, 컴퓨터 비전 프로젝트에 적합. 고급 알고리즘과 효율적인 처리 기능.
  • 차이점: 이미지와 비디오 데이터 처리에 특화. GUI 개발이나 게임 개발에는 적합하지 않음.

PyQt

  • 동작 방식: GUI 애플리케이션 개발을 위한 라이브러리. 이벤트 기반 프로그래밍 모델과 함께 사용됩니다.
  • 특징: 복잡한 GUI 애플리케이션 개발에 적합. 다양한 위젯과 사용자 인터페이스 요소 제공.
  • 차이점: 강력한 GUI 개발 기능. 이미지 처리보다는 사용자 인터페이스와 상호작용에 초점.

비슷한 점

  • 모두 파이썬에서 널리 사용되는 라이브러리.
  • 그래픽 및 이벤트 처리 기능을 제공.
  • 상호작용이 필요한 애플리케이션 개발에 사용됨.
라이브러리 동작 방식 특징 차이점
Pygame 게임 개발 및 그래픽 루프 기반 2D 게임 개발, 간단한 그래픽 처리 GUI 기능 제한, 단순한 그래픽 처리
OpenCV 이미지 및 비디오 처리 중심 고급 이미지/비디오 분석 GUI 개발에 적합하지 않음
PyQt GUI 애플리케이션 개발 복잡한 GUI 개발, 다양한 위젯 제공 이미지 처리보다 UI에 초점

 

패키지(PyQt, Pygame, OpenCV) 별로 동일 동작 구현

목표기능 :

  1. 박스와 3개의 라인 그림.
  2. 마우스 스크롤에 따라 박스와 라인의 크기를 확대 및 축소.
  3. 박스나 라인 위에 마우스 포인터가 위치하면 선택된 객체와 좌표를 툴팁으로 표시.

PyQt/PySide

PyQt에서 이러한 기능을 구현하기 위해 QGraphicsScene, QGraphicsView, QGraphicsRectItemQGraphicsLineItem 클래스를 사용할 수 있습니다. 다음은 이 기능을 수행하는 간단한 예제 코드입니다.

import sys
from PyQt5.QtWidgets import QApplication, QGraphicsView, QGraphicsScene, QGraphicsRectItem, QGraphicsLineItem, QToolTip
from PyQt5.QtCore import Qt, QRectF
from PyQt5.QtGui import QTransform

class GraphicsView(QGraphicsView):
    def __init__(self, scene):
        super().__init__(scene)
        self.setSceneRect(0, 0, 400, 300)
        self.scaleFactor = 1.0

    def wheelEvent(self, event):
        if event.angleDelta().y() > 0:
            self.scaleFactor *= 1.1
            self.scale(1.1, 1.1)
        else:
            self.scaleFactor *= 0.9
            self.scale(0.9, 0.9)

    def mouseMoveEvent(self, event):
        items = self.items(event.pos())
        if items:
            item = items[0]
            if isinstance(item, QGraphicsRectItem):
                QToolTip.showText(event.globalPos(), f"Rectangle - Pos: {item.pos()}")
            elif isinstance(item, QGraphicsLineItem):
                QToolTip.showText(event.globalPos(), f"Line - Pos: {item.line().p1()}")
        super().mouseMoveEvent(event)

app = QApplication(sys.argv)
scene = QGraphicsScene()

# 박스 추가
rect = QGraphicsRectItem(QRectF(0, 0, 100, 100))
scene.addItem(rect)

# 라인 추가
for i in range(3):
    line = QGraphicsLineItem(110, 10 + i*30, 200, 10 + i*30)
    scene.addItem(line)

view = GraphicsView(scene)
view.show()
sys.exit(app.exec_())

 

이 코드는 PyQt를 사용하여 그래픽스 장면에 박스와 선을 그리고, 마우스 스크롤에 의한 확대/축소 및 마우스 이동에 따른 툴팁을 표시합니다. 확대/축소 기능은 wheelEvent를 재정의하여 구현하고, 툴팁 표시는 mouseMoveEvent를 사용하여 구현합니다.

import sys
from PySide6.QtWidgets import QApplication, QGraphicsView, QGraphicsScene, QGraphicsRectItem, QGraphicsLineItem, QToolTip
from PySide6.QtCore import Qt, QRectF
from PySide6.QtGui import QTransform

class GraphicsView(QGraphicsView):
    def __init__(self, scene):
        super().__init__(scene)
        self.setSceneRect(0, 0, 400, 300)
        self.scaleFactor = 1.0

    def wheelEvent(self, event):
        if event.angleDelta().y() > 0:
            self.scaleFactor *= 1.1
            self.scale(1.1, 1.1)
        else:
            self.scaleFactor *= 0.9
            self.scale(0.9, 0.9)

    def mouseMoveEvent(self, event):
        items = self.items(event.pos())
        if items:
            item = items[0]
            if isinstance(item, QGraphicsRectItem):
                QToolTip.showText(event.globalPos(), f"Rectangle - Pos: {item.pos()}")
            elif isinstance(item, QGraphicsLineItem):
                QToolTip.showText(event.globalPos(), f"Line - Pos: {item.line().p1()}")
        super().mouseMoveEvent(event)

app = QApplication(sys.argv)
scene = QGraphicsScene()

# 박스 추가
rect = QGraphicsRectItem(QRectF(0, 0, 100, 100))
scene.addItem(rect)

# 라인 추가
for i in range(3):
    line = QGraphicsLineItem(110, 10 + i*30, 200, 10 + i*30)
    scene.addItem(line)

view = GraphicsView(scene)
view.show()
sys.exit(app.exec_())
반응형

Pygame

Pygame에서 직접적인 툴팁 기능은 제공하지 않기 때문에, 마우스 포인터 위치에 따라 텍스트를 화면에 표시하는 방식으로 툴팁 기능을 구현할 수 있습니다. 이 코드는 Pygame을 사용하여 화면에 박스와 선을 그리고, 마우스 스크롤에 의한 확대/축소 및 마우스 위치에 따른 텍스트 표시를 구현합니다. Pygame은 툴팁 기능을 직접 제공하지 않으므로, 텍스트를 사용하여 마우스 위치에 정보를 표시합니다.

import pygame
import sys

# Pygame 초기화 및 설정
pygame.init()
width, height = 800, 600
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("Pygame Shape Drawing")

# 색상 및 초기 설정
black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
font = pygame.font.Font(None, 36)

# 도형 그리기 설정
rect = pygame.Rect(100, 100, 200, 200)
lines = [(300, 150, 400, 150), (300, 200, 400, 200), (300, 250, 400, 250)]
scale = 1.0

# 게임 루프
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 4:  # 마우스 스크롤 업
                scale *= 1.1
            elif event.button == 5:  # 마우스 스크롤 다운
                scale *= 0.9

    # 화면 지우기
    screen.fill(black)

    # 도형 그리기
    scaled_rect = rect.inflate(rect.width * (scale - 1), rect.height * (scale - 1))
    pygame.draw.rect(screen, red, scaled_rect, 2)
    for line in lines:
        scaled_line = [line[0] * scale, line[1] * scale, line[2] * scale, line[3] * scale]
        pygame.draw.line(screen, green, scaled_line[:2], scaled_line[2:], 2)

    # 마우스 위치 표시
    mx, my = pygame.mouse.get_pos()
    if scaled_rect.collidepoint(mx, my):
        text = font.render(f"Box - Pos: ({mx}, {my})", True, white)
        screen.blit(text, (mx, my))
    for line in lines:
        if scaled_rect.collidepoint(mx, my):  # 간단한 체크, 실제 라인 충돌은 계산 필요
            text = font.render(f"Line - Pos: ({mx}, {my})", True, white)
            screen.blit(text, (mx, my))

    pygame.display.flip()

pygame.quit()
sys.exit()

OpenCV

OpenCV는 주로 이미지 처리에 사용되는 라이브러리이지만, 간단한 그래픽스와 마우스 이벤트 처리도 가능합니다.

이 코드는 OpenCV를 사용하여 화면에 박스와 선을 그리고, 마우스 이벤트를 처리합니다. 마우스 이동 이벤트(EVENT_MOUSEMOVE)가 발생하면, 마우스 위치에 따라 박스 또는 라인 위에 텍스트를 표시합니다. OpenCV에는 툴팁 기능이 없으므로, 텍스트를 사용하여 마우스 위치에 정보를 표시합니다. 그리고 현재 코드에서는 간단히 중앙 부분에 마우스가 있는지 확인하는 방식으로 구현되어 있습니다.

import cv2
import numpy as np

# 초기 설정
scale = 1.0
img_original = np.zeros((600, 800, 3), dtype=np.uint8)
cv2.rectangle(img_original, (100, 100), (300, 300), (0, 0, 255), 2)
lines = [(350, 150, 450, 150), (350, 200, 450, 200), (350, 250, 450, 250)]
for line in lines:
    cv2.line(img_original, line[:2], line[2:], (0, 255, 0), 2)

# 마우스 콜백 함수
def mouse_callback(event, x, y, flags, param):
    global scale, img_original

    if event == cv2.EVENT_MOUSEWHEEL:
        if flags > 0:  # 스크롤 업, 확대
            scale *= 1.1
        else:  # 스크롤 다운, 축소
            scale *= 0.9

        # 확대 또는 축소된 이미지 생성
        img_resized = cv2.resize(img_original, None, fx=scale, fy=scale, interpolation=cv2.INTER_LINEAR)
        cv2.imshow("Image", img_resized)

    elif event == cv2.EVENT_MOUSEMOVE:
        img_resized = cv2.resize(img_original, None, fx=scale, fy=scale, interpolation=cv2.INTER_LINEAR)
        # 마우스 위치에 따른 텍스트 표시
        # 여기서는 간단히 화면 중앙에 박스나 라인 위에 마우스가 있는지 표시합니다.
        # 실제 위치 계산은 확대/축소 비율을 고려하여 조정해야 합니다.
        if 100*scale <= x <= 300*scale and 100*scale <= y <= 300*scale:
            cv2.putText(img_resized, "Box", (x, y), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
        cv2.imshow("Image", img_resized)

cv2.namedWindow("Image")
cv2.setMouseCallback("Image", mouse_callback)

while True:
    cv2.imshow("Image", img_original)
    key = cv2.waitKey(1)
    if key == 27:  # ESC 키
        break

cv2.destroyAllWindows()

 

반응형