Skip to content

OpenCV 응용

QR 코드 인식하기

  • QRCodeDetector 클래스의 사용법을 익힌다.
  • QR 코드의 위치(좌표)를 찾아 화면에 표시한다.
  • QR 코드 안에 담긴 데이터(문자열, URL)를 디코딩하여 터미널과 화면에 출력한다.

cv2.QRCodeDetector

OpenCV는 QR 코드를 처리하기 위해 전용 클래스를 제공합니다.

  • 기능 1: Detect (검출) - 영상에서 QR 코드가 있는 네 모서리 좌표를 찾습니다.
  • 기능 2: Decode (해독) - 검출된 QR 코드의 패턴을 분석해 문자열로 바꿉니다.

💡 함수 하나로 해결하기

detectAndDecode(img) 함수를 사용하면 검출과 해독을 동시에 수행할 수 있어 매우 편리합니다.

실습 코드 (Python)

python
import cv2
import numpy as np

# 1. 카메라 설정
cap = cv2.VideoCapture(0)

# 2. QR 코드 디텍터 객체 생성 (초기화)
detector = cv2.QRCodeDetector()

print("QR 코드를 카메라에 보여주세요! (종료: q)")

while True:
    ret, frame = cap.read()
    if not ret:
        break

    # 3. QR 코드 검출 및 해독 (핵심 함수)
    # data: 해독된 문자열 (예: "http://naver.com")
    # points: QR 코드의 4개 모서리 좌표 (배열)
    # straight_qrcode: 정면에서 본 형태로 변환된 QR 코드 이미지 (여기선 안 씀)
    data, points, _ = detector.detectAndDecode(frame)

    # 4. QR 코드가 검출되었다면? (points가 None이 아님)
    if points is not None:
        # 데이터가 존재한다면 (해독 성공)
        if data:
            # (1) 좌표 데이터를 정수형으로 변환 (그리기 위해)
            # points의 형태가 (1, 4, 2) 등으로 나오므로 int로 바꾸고 차원 정리
            pts = points.astype(int)
            
            # (2) QR 코드 주변에 테두리 그리기
            # polylines를 쓰는 이유: QR 코드가 회전되어 있어도 정확히 감싸기 위해
            # isClosed=True: 4개 점을 닫힌 도형으로 연결
            cv2.polylines(frame, [pts], isClosed=True, color=(0, 255, 0), thickness=3)

            # (3) 해독된 내용 화면에 출력하기
            # 텍스트 위치: QR 코드의 첫 번째 모서리 위쪽
            cv2.putText(frame, data, (pts[0][0][0], pts[0][0][1] - 10),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2)
            
            # 터미널에도 출력 (중복 출력 방지를 위해 이전 값과 비교하는 로직 추가 가능)
            print(f"Detected: {data}")

    # 5. 화면 출력
    cv2.imshow('QR Code Reader', frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()
QR 코드 인식 결과

주요 함수 설명

  1. detector.detectAndDecode(frame) : 가장 중요한 한 줄입니다. 3가지 값을 반환합니다.

리턴값

  • data: QR 코드 안의 내용입니다. (예: "Hello World"). 인식이 실패하거나 QR 코드가 없으면 빈 문자열 ""이 나옵니다.
  • points: QR 코드의 4개 꼭짓점 좌표입니다. [[x1, y1], [x2, y2], ...] 형태의 배열입니다.
  • straight_qrcode: 찌그러진 QR 코드를 정면에서 본 정사각형 이미지로 펴서 돌려줍니다. (주로 분석용으로 쓰이며 일반적인 인식에선 잘 안 씁니다.)
  1. cv2.polylines(...)

왜 rectangle을 안 쓰나요?

rectangle은 수평/수직으로 된 사각형만 그릴 수 있습니다. QR 코드는 카메라 앞에서 기울어지거나 회전될 수 있습니다. polylines는 4개의 점을 이어주므로, QR 코드가 마름모 꼴로 보여도 정확하게 테두리를 그릴 수 있습니다.

  1. points.astype(int) : 좌표 변환

detectAndDecode가 반환하는 좌표값은 소수점(float) 형태일 수 있습니다. OpenCV의 그리기 함수(polylines, line 등)는 픽셀 좌표로 정수(int)만 받기 때문에 타입 변환이 필수입니다.

실습 과제

  1. 기초: 특정 QR 코드에만 반응하기 "SECRET"이라는 글자가 들어있는 QR 코드를 인식했을 때만 "접속 승인(Access Granted)"이라고 띄우고, 나머지는 "접속 불가"라고 빨간색으로 띄워보세요.

  2. 응용 1: 웹 브라우저 자동 실행

  • Python의 webbrowser 모듈을 임포트합니다.
  • 인식된 데이터가 http로 시작하는 URL이라면 자동으로 인터넷 창을 띄우는 키오스크 기능을 만들어보세요.
import webbrowser
# ... 코드 생략 ...
if data.startswith("http"):
    webbrowser.open(data)
    cv2.waitKey(0) # 브라우저가 계속 뜨는걸 막기 위해 잠시 멈춤
  1. 심화: 바코드도 될까요?
  • OpenCV의 QRCodeDetector는 QR 코드 전용입니다. 일반 1차원 바코드(편의점 바코드)는 인식하지 못합니다.
  • 바코드까지 인식하고 싶다면 pyzbar라는 외부 라이브러리를 설치해야 함을 설명하고, 관심 있는 학생에게 키워드를 던져주세요.