본문 바로가기
학부 생활 + 랩실/OpenCv

Open Cv 스터디 - 3 (객체 검출 - qr 코드 검출)

by 프롭 2026. 3. 16.

 

객체 검출 - qr 코드 검출

 

QR 코드란?

  • QR 코드는 흑백 격자 무늬로 구성된 2차원 바코드(2D barcode)의 일종으로, 숫자, 영문자, 8비트 문자, 한자 등 다양한 정보를 저장할 수 있습니다.
  • 최근에는 명함, 광고, 포스터 등에 웹사이트 URL이나 문자열을 저장한 QR 코드를 인쇄하여 스마트폰 앱으로 스캔 시 해당 정보로 직접 접근할 수 있도록 활용됩니다.

 

QR 코드 인식 과정

  • 입력 영상에서 QR 코드를 인식하기 위해 다음의 단계가 수행됩니다.
  1. 위치 검출
    • QR 코드의 세 모서리에 포함된 흑백 정사각형 패턴(위치 검출 패턴)을 찾아 전체 QR 코드 영역의 위치를 파악합니다.
  2. 투시 변환 (Perspective Transformation)
    • 검출된 사각형 영역을 기준으로 QR 코드를 정사각형 형태로 보정합니다.
  3. 격자 해석 및 문자열 추출
    • 보정된 QR 코드 내부의 흑백 격자 패턴을 해석하여 인코딩된 문자열을 복원합니다.
  • OpenCV에서는 이러한 과정을 단일 클래스로 처리할 수 있도록 QRCodeDetector 기능을 제공합니다.

 

QRCodeDetector 클래스

  • QRCodeDetector 클래스는 QR 코드 검출(detect), 해석(decode), 그리고 검출 및 해석 통합(detectAndDecode) 기능을 제공합니다.
  • 객체는 다음과 같이 선언하여 생성합니다.
QRCodeDetector detector;
 

 

1. QR 코드 검출 – detect()

함수 원형

bool QRCodeDetector::detect(InputArray img, OutputArray points) const;
 
매개변수
설명
img
입력 영상 (CV_8U 또는 CV_8UC3)
points
(출력) QR 코드를 감싸는 사각형의 네 꼭지점 좌표, points는 일반적으로 vector<Point> 타입으로 받으며, 이후 decode() 단계에서 QR 코드 영역 정보를 입력으로 사용합니다
반환값
QR 코드 검출 성공 시 true, 실패 시 false

 

2. QR 코드 해석 – decode()

함수 원형

std::string QRCodeDetector::decode(
    InputArray img,
    InputArray points,
    OutputArray straight_qrcode = noArray()
);
매개변수
설명
img
입력 영상
points
(입력) QR 코드 네 꼭지점 좌표 (detect() 결과)
straight_qrcode
(출력) 정사각형 형태로 투시 변환된 QR 코드 영상 (CV_8UC1)
반환값
QR 코드에 포함된 문자열, 해석에 실패하면 빈 문자열("")을 반환합니다.

 

3. 검출 및 해석 통합 – detectAndDecode()

함수 원형

std::string QRCodeDetector::detectAndDecode(
    InputArray img,
    OutputArray points = noArray(),
    OutputArray straight_qrcode = noArray()
);
 
매개변수
설명
img
입력 영상 (CV_8U)
points
(출력) QR 코드 네 꼭지점 좌표
straight_qrcode
(출력) 정사각형 QR 코드 영상
반환값
QR 코드에 포함된 문자열

※ QR 코드 검출과 해석을 동시에 수행하며, 문자열만 필요하다면 points와 straight_qrcode 인자는 생략할 수 있습니다.

 

qr 코드 검출 실습

#include <opencv2/opencv.hpp>
#include <iostream>
#include <string>

using namespace cv;
using namespace std;

void decode_qrcode_from_image()
{
    // 이미지 파일 로드
    Mat src = imread("qrcode.png", IMREAD_COLOR);

    // 이미지 로드 성공 여부 확인
    if (src.empty()) {
        cerr << "Image load failed! (Check if 'qrcode_test.png' exists)" << endl;
        // 테스트를 위해 적절한 QR 코드 이미지를 준비해주세요.
        return;
    }

    // QR 코드 검출 및 디코딩을 위한 객체 생성
    QRCodeDetector detector;

    // QR 코드 검출 및 디코딩 수행
    vector<Point> points; // 검출된 QR 코드의 네 모서리 좌표
    Mat decoded_image;    // 디코딩된 영역의 이진화된 이미지

    // detectAndDecode 함수 호출
    String info = detector.detectAndDecode(src, points, decoded_image);

    // QR 코드가 검출되었고 디코딩에 성공했을 경우 처리
    Mat dst = src.clone(); // 원본 이미지에 결과를 그리기 위해 복사

    if (!info.empty()) {
        cout << "✅ QR Code Detected and Decoded!" << endl;
        cout << "   -> Data: " << info << endl;

        // QR 코드 경계선 그리기 (빨간색, 두께 3)
        polylines(dst, points, true, Scalar(0, 0, 255), 3);

        // 디코딩된 정보를 이미지 위에 출력
        putText(dst, info, Point(10, 30), // 좌상단 (10, 30) 위치에 텍스트 출력
            FONT_HERSHEY_DUPLEX, 0.8, Scalar(0, 0, 255), 2); // 빨간색 텍스트
    }
    else {
        cout << "❌ QR Code Not Detected or Decoding Failed." << endl;
    }

    imshow("src (Original Image)", src);
    imshow("dst (QR Code Result)", dst);

    waitKey(0);

    destroyAllWindows();
}

int main()
{
    decode_qrcode_from_image(); // 이미지 파일 QR 코드 디코딩 함수 호출
    return 0;
}

 

 

'학부 생활 + 랩실 > OpenCv' 카테고리의 다른 글

Open Cv 스터디 - 2 (케니 알고리즘, 허프 변환)  (0) 2026.03.16
Open Cv 스터디 - 1  (1) 2026.03.16