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