QR코드는 흑백 격자 무늬 모양의 2차원 바코드 일종으로 숫자, 영문자, 8비트 문자, 한자 등의 정보를 저장할 수 있다.
입력영상에서 QR코드를 인식하려면 먼저 QR코드 세 모서리에 포함된 흑백 정사각형 패턴을 찾아 QR코드 전체 영역 위치를 알아내야 한다. 그리고 검출된 QR코드를 저사각형 형태로 투시변환한 후 QR코드 내부에 포함된 흑백 격자 무늬를 해석하여 문자열을 추출해야 한다. 이는 OpenCV 4.0.0 버전부터 QR코드를 검출하고 QR코드에 포함된 문자열을 해석하는 기능을 제공한다.
OpenCV 에서 QR코드를 검출하고 해석하는 기능은 QRCodeDetector 클래스에 구현되어 있다. QRCodeDetector 클래스를 이용하여 영상에서 QR코드를 검출하거나 해석하려면 먼저 QRCodeDetector 객체를 생성해야한다.
QRCodeDetector detector;
QR코드 영역을 검출하기 위해서는 detect 함수를 사용한다.
bool QRCodeDetector::detect(InputArray img, OutputArray points) const;
img : 입력영상
points : QR코드를 감싸는 사각형의 네 꼭지점 좌표
반환값 : QR코드를 검출하면 true, 검출하지 못하면 false를 반환
검출된 QR코드 영역에서 QR코드에 저장된 문자열을 추출할때는 decode()함수를 사용한다.
std::string QRCodeDetector::decode(InputArray img, InputArray points,
OutputArray straight_qrcode = noArray());
imag : 입력영상
points : QR코드를 감싸는 사각형의 네 꼭지점 좌표
straight_qrcode : 정사각형 QR코드 영상
반환값 : QR코드에 포함된 문자열
입력영상에서 QR코드 검출과 해석을 한꺼번에 수행하려면 detectAndDecode() 멤버 함수를 사용하는 것이 편리하다.
std::string QRCodeDetector::detectAndDecode(InputArray img, OutputArray points = noArray(), OutputArray straight_qrcode = noArray());
img : 입력영상
points : QR코드를 감싸는 사각형의 네 꼭지점의 좌표
straight_qrcode : 정사각형 QR코드 영상
반환값 : QR코드에 포함된 문자열
void decode_qrcode() {
VideoCapture cap(0);
if (!cap.isOpened()) {
cerr << "Camera open failed! " << endl;
return;
}
QRCodeDetector detector;
Mat frame;
while (true) {
cap >> frame;
if (frame.empty()) {
cerr << "Frame load failed!" << endl;
break;
}
vector<Point> points;
String info = detector.detectAndDecode(frame, points);
if (!info.empty()) {
polylines(frame, points, true, Scalar(0, 0, 255), 2);
putText(frame, info, Point(10, 30), FONT_HERSHEY_DUPLEX, 1, Scalar(0, 0, 255));
}
imshow("frame", frame);
if (waitKey(1) == 27)
break;
}
}