[OpenCV] QR Code 인식하기

이번 글에서는 OpenCV를 통하여 QR 코드를 인식하는 법에 대해 알아보겠습니다.

QR코드는 아래와 같은 예시 이미지를 말하며, DENSO WAVE가 개발한 고속 판독용 매트릭스 2차원 코드입니다.

https://3001ssw.tistory.com/

좌측, 우측 상단, 좌측 하단의 정사각형 패턴으로 QR 코드 영상이라고 판단 하며, QR 코드는 최소 21×21, 최대 177×177 심볼 크기를 가지며, 최대 크기의 QR코드는 7089개의 숫자 또는 4269개의 영숫자를 담고있습니다.

패턴

QR코드는 이러한 특성으로 지정된 링크나 앱에 연결하기 위한 문자를 담고있는게 일반적입니다.

많은 정보가 있긴 하지만 그걸로 음모론 펼친 정돈 아닙니다.

어쨌든 OpenCV에서는  QR코드를 QRCodeDetector 클래스를 제공하여 인식 가능하게 합니다.

QR코드의 영역은 QRCodeDetector::detect 함수를 이용하여 위치 정보를 찾아냅니다.

/**
 @param img 입력 영상
 @param points 출력 포인트, QR코드의 이미지의 꼭지점 좌표
 */
bool QRCodeDetector::detect(InputArray img, OutputArray points) const;

그리고, 담겨져있는 문자열은 QRCodeDetector::decode 함수를 사용하여 얻을 수 있습니다.

/**
 @param img 입력 이미지
 @param points 꼭지점 좌표
 @param straight_qrcode 정사각형 QR코드 영상
 */
std::string QRCodeDetector::decode(InputArray img, InputArray points, OutputArray straight_qrcode = noArray());

detect와 decode를 한번에 할 수 있는 detectAndDecode 함수도 제공합니다.

/**
@param img 입력 영상
@param points 출력 꼭지점 좌표
@param straight_qrcode 정사각형 QR 코드 영상
*/
std::string QRCodeDetector::detectAndDecode(InputArray img, OutputArray points=noArray(), OutputArray straight_qrcode = noArray());

QR코드에서 문자열을 출력하는 코드는 아래와 같습니다.

Mat src = imread("qr.png");
if (src.empty())
{
	cerr << "image load fail" << endl;
	return -1;
}

QRCodeDetector qr;
vector<Point> points;
bool detect = qr.detect(src, points); // QR 영역 인식
String qr_str = "";
if (detect)
	qr_str = qr.decode(src, points); // 문자열 추출

//String qr_str = qr.detectAndDecode(src, points); // detect와 decode 한번에

if (0 < points.size())
	polylines(src, points, true, Scalar(0, 0, 255), 2); // 영역 그리기

if (!qr_str.empty())
	cout << qr_str << endl;

imshow("src", src);

waitKey();
destroyAllWindows();

출력 결과는 아래와 같습니다.