Opencv4.0版本以后,引入了二维码定位+解码功能
以下代码实现基于opencv 4.5.0
- 代码实现
#include "opencv2/objdetect.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/videoio.hpp"
#include "opencv2/imgcodecs.hpp"
#include <string>
#include <iostream>
using namespace std;
using namespace cv;
/**
* @brief 解析图片,并标记二维码位置
* @note
* @param input: 输入图片
* @retval
*/
int runQR(Mat input)
{
QRCodeDetector qrcode;
vector<Point> corners;
vector<cv::String> decode_info;
corners.clear();
decode_info.clear();
// 开始解码
TickMeter timer;
timer.start();
// 多个扫描
bool result_detection = qrcode.detectAndDecodeMulti(input, decode_info, corners);
// cout << "result_detection:" << result_detection << endl;
// 单个扫描
// string code_detection = qrcode.detectAndDecode(input, corners);
// cout << "code_detection:" << code_detection << endl;
timer.stop();
cout << "Decoder time: " << timer.getTimeSec()*1000.00 << "ms" << endl;
if (result_detection > 0){
// cout << "decode_info.size():" << decode_info.size() <<endl;
// 将1维向量转为4维
vector<vector<Point>> corners2;
for (size_t i = 0; i < corners.size(); i+=4)
{
vector<Point> temp(corners.begin()+i,corners.begin()+i+4);
// cout << "temp:" << temp << endl;
corners2.push_back(temp);
}
// cout << "corners2:" << corners2.size() << endl;
// 显示二维码定位
for (size_t i = 0; i < corners2.size(); i++)
{
drawContours(input,corners2,i,Scalar(0,0,255),2);
// imshow("QR dst", input);
}
// 显示识别结果
for (size_t i = 0; i < decode_info.size(); i++)
{
if(!decode_info[i].empty())
cout << "Get QRcode:" << decode_info[i] <<endl;
else
cout << "err" << endl;
}
}else{
cout << "decoder err" << endl;
return -1;
}
return 0;
}
/**
* @brief 二维码检测、解析
* @note
* @param argc:
* @param *argv[]:
* @retval
*/
int QRcode_decode(int argc, char *argv[])
{
string in_file_name = "./QRcode.png";
// 加载二维码图片
Mat input = imread(in_file_name, IMREAD_COLOR);
cout << "image info: " << input.size()
<< " (" << typeToString(input.type()) << ")"
<< endl;
runQR(input);
imshow("QR src", input);
#if 0
// 打开摄像头捕获
VideoCapture cap(0);
if (!cap.isOpened()){
cout << "Cannot open a camera" << endl;
return 2;
}
for (;;)
{
Mat frame;
cap >> frame;
if (frame.empty())
{
cout << "End of video stream" << endl;
break;
}
runQR(frame);
imshow("QR src", frame);
if(waitKey(100) == 27){
cout << "'ESC' is pressed. Exiting..." << endl;
break;
}
}
#endif
cout << "=============================" << endl;
cout << "Press any key to exit ..." << endl;
waitKey(0);
cout << "Exit." << endl;
return 0;
}
- 运行
eric@eric-PC:~/Documents/work/linux-c/opencv_demo/demo$ ./main
image info: [335 x 388] (CV_8UC3)
Decoder time: 24.3895ms
Get QRcode:1234567890
=============================
Press any key to exit ...
Exit.