본문 바로가기

PY(Python Image Processing)

AR 기능 구현 - python opencv pygame opengl

728x90
import cv2
import numpy as np
import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *

# 3D 큐브 정점
vertices = [
    [-1, -1, -1], [1, -1, -1], [1, 1, -1], [-1, 1, -1],
    [-1, -1, 1], [1, -1, 1], [1, 1, 1], [-1, 1, 1]
]

edges = [
    (0, 1), (1, 2), (2, 3), (3, 0),
    (4, 5), (5, 6), (6, 7), (7, 4),
    (0, 4), (1, 5), (2, 6), (3, 7)
]

# OpenGL 텍스처 ID 저장
texture_id = None

def init_texture(width, height):
    """OpenGL 텍스처 초기화"""
    global texture_id
    texture_id = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, texture_id)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, None)

def update_texture(frame):
    """웹캠 프레임을 OpenGL 텍스처로 업데이트"""
    glBindTexture(GL_TEXTURE_2D, texture_id)
    frame = cv2.flip(frame, 0)  # OpenGL 좌표계에 맞추기 위해 뒤집기
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)  # BGR → RGB 변환
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, frame.shape[1], frame.shape[0], GL_RGB, GL_UNSIGNED_BYTE, frame)

def draw_background():
    """OpenGL을 사용하여 배경에 웹캠 영상을 렌더링"""
    glEnable(GL_TEXTURE_2D)
    glBindTexture(GL_TEXTURE_2D, texture_id)

    glBegin(GL_QUADS)
    glTexCoord2f(0, 0); glVertex3f(-2, -2, -5)
    glTexCoord2f(1, 0); glVertex3f(2, -2, -5)
    glTexCoord2f(1, 1); glVertex3f(2, 2, -5)
    glTexCoord2f(0, 1); glVertex3f(-2, 2, -5)
    glEnd()

    glDisable(GL_TEXTURE_2D)

def draw_cube(angle, scale_factor):
    """OpenGL을 사용하여 3D 큐브를 렌더링"""
    glPushMatrix()
    glTranslatef(0.0, 0.0, -3.5)  # 큐브 위치 조정
    glScalef(scale_factor, scale_factor, scale_factor)  # 크기 조절 (기본값 0.5배)
    glRotatef(angle, 1, 1, 0)  # 큐브 회전

    glBegin(GL_QUADS)
    colors = [(1, 0, 0), (0, 1, 0), (0, 0, 1), (1, 1, 0), (1, 0, 1), (0, 1, 1)]
    faces = [(0, 1, 2, 3), (4, 5, 6, 7), (0, 1, 5, 4), (2, 3, 7, 6), (0, 3, 7, 4), (1, 2, 6, 5)]
   
    for i, face in enumerate(faces):
        glColor3fv(colors[i])  # 색상 추가
        for vertex in face:
            glVertex3fv(vertices[vertex])
   
    glEnd()
    glPopMatrix()

def main():
    cap = cv2.VideoCapture(0)  # 웹캠 시작
    if not cap.isOpened():
        print("웹캠을 열 수 없습니다!")
        return
   
    ret, frame = cap.read()
    if not ret:
        print("웹캠 프레임을 가져올 수 없습니다.")
        return

    height, width, _ = frame.shape  # 웹캠 해상도 가져오기

    pygame.init()
    display = (width, height)
    pygame.display.set_mode(display, DOUBLEBUF | OPENGL)

    glEnable(GL_DEPTH_TEST)  # 깊이 테스트 활성화
    glEnable(GL_BLEND)  # 투명도 활성화
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluPerspective(45, (width / height), 0.1, 50.0)  # 원근 투영 적용
    glMatrixMode(GL_MODELVIEW)

    init_texture(width, height)  # 텍스처 초기화

    angle = 0  # 회전 각도
    scale_factor = 0.5  # 크기 배율

    while True:
        ret, frame = cap.read()
        if not ret:
            break
       
        update_texture(frame)  # OpenGL 텍스처 업데이트

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)  # 화면 지우기
        glLoadIdentity()

        draw_background()  # 웹캠 영상을 배경으로 출력
        draw_cube(angle, scale_factor)  # 3D 큐브 렌더링 (크기 적용)
        angle += 1  # 회전

        pygame.display.flip()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                cap.release()
                pygame.quit()
                return
            if event.type == KEYDOWN and event.key == K_ESCAPE:
                cap.release()
                pygame.quit()
                return

if __name__ == "__main__":
    main()

 

📌 설치해야 할 라이브러리

pygame OpenGL 렌더링 창 및 이벤트 처리 pip install pygame
opencv-python 웹캠 영상 처리 및 이미지 변환 pip install opencv-python
numpy 행렬 연산 및 좌표 변환 pip install numpy
PyOpenGL OpenGL을 사용한 3D 렌더링 pip install PyOpenGL
PyOpenGL_accelerate PyOpenGL 성능 최적화 (선택 사항) pip install PyOpenGL_accelerate

 

728x90