Merge pull request #3289 from AleksandrPanov:wechat_fix_output_qr_corners

fix output qr corners
pull/3346/head
Alexander Smorkalov 3 years ago committed by GitHub
commit 47bf66f6f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      modules/wechat_qrcode/src/decodermgr.cpp
  2. 2
      modules/wechat_qrcode/src/decodermgr.hpp
  3. 16
      modules/wechat_qrcode/src/wechat_qrcode.cpp
  4. 52
      modules/wechat_qrcode/test/test_qrcode.cpp

@ -18,7 +18,7 @@ using zxing::Result;
using zxing::UnicomBlock;
namespace cv {
namespace wechat_qrcode {
int DecoderMgr::decodeImage(cv::Mat src, bool use_nn_detector, string& result) {
int DecoderMgr::decodeImage(cv::Mat src, bool use_nn_detector, string& result, vector<Point2f>& points) {
int width = src.cols;
int height = src.rows;
if (width <= 20 || height <= 20)
@ -46,6 +46,14 @@ int DecoderMgr::decodeImage(cv::Mat src, bool use_nn_detector, string& result) {
int ret = TryDecode(source, zx_result);
if (!ret) {
result = zx_result->getText()->getText();
auto result_points = zx_result->getResultPoints();
for(int i = 0; i < result_points->size() / 4; i++) {
const int ind = i * 4;
for (int j = 1; j < 4; j++)
points.emplace_back(result_points[ind+j]->getX(), result_points[ind+j]->getY());
points.emplace_back(result_points[ind]->getX(), result_points[ind]->getY());
}
return ret;
}
// try different binarizers

@ -26,7 +26,7 @@ public:
DecoderMgr() { reader_ = new zxing::qrcode::QRCodeReader(); };
~DecoderMgr(){};
int decodeImage(cv::Mat src, bool use_nn_detector, string& result);
int decodeImage(cv::Mat src, bool use_nn_detector, string& result, vector<Point2f>& points);
private:
zxing::Ref<zxing::UnicomBlock> qbarUicomBlock_;

@ -131,8 +131,8 @@ vector<string> WeChatQRCode::Impl::decode(const Mat& img, vector<Mat>& candidate
vector<string> decode_results;
for (auto& point : candidate_points) {
Mat cropped_img;
Align aligner;
if (use_nn_detector_) {
Align aligner;
cropped_img = cropObj(img, point, aligner);
} else {
cropped_img = img;
@ -144,9 +144,19 @@ vector<string> WeChatQRCode::Impl::decode(const Mat& img, vector<Mat>& candidate
super_resolution_model_->processImageScale(cropped_img, cur_scale, use_nn_sr_);
string result;
DecoderMgr decodemgr;
auto ret = decodemgr.decodeImage(scaled_img, use_nn_detector_, result);
vector<Point2f> points_qr;
auto ret = decodemgr.decodeImage(scaled_img, use_nn_detector_, result, points_qr);
if (ret == 0) {
for (auto&& pt: points_qr) {
pt /= cur_scale;
}
if (use_nn_detector_)
points_qr = aligner.warpBack(points_qr);
for (int i = 0; i < 4; ++i) {
point.at<float>(i, 0) = points_qr[i].x;
point.at<float>(i, 1) = points_qr[i].y;
}
decode_results.push_back(result);
points.push_back(point);
break;

@ -284,6 +284,58 @@ TEST_P(Objdetect_QRCode_Multi, regression) {
}
}
TEST(Objdetect_QRCode_points_position, rotate45) {
string path_detect_prototxt, path_detect_caffemodel, path_sr_prototxt, path_sr_caffemodel;
string model_version = "_2021-01";
path_detect_prototxt = findDataFile("dnn/wechat"+model_version+"/detect.prototxt", false);
path_detect_caffemodel = findDataFile("dnn/wechat"+model_version+"/detect.caffemodel", false);
path_sr_prototxt = findDataFile("dnn/wechat"+model_version+"/sr.prototxt", false);
path_sr_caffemodel = findDataFile("dnn/wechat"+model_version+"/sr.caffemodel", false);
auto detector = wechat_qrcode::WeChatQRCode(path_detect_prototxt, path_detect_caffemodel, path_sr_prototxt,
path_sr_caffemodel);
const cv::String expect_msg = "OpenCV";
QRCodeEncoder::Params params;
params.version = 5; // 37x37
Ptr<QRCodeEncoder> qrcode_enc = cv::QRCodeEncoder::create(params);
Mat qrImage;
qrcode_enc->encode(expect_msg, qrImage);
Mat image(800, 800, CV_8UC1);
const int pixInBlob = 4;
Size qrSize = Size((21+(params.version-1)*4)*pixInBlob,(21+(params.version-1)*4)*pixInBlob);
Rect2f rec((image.cols - qrSize.width)/2, (image.rows - qrSize.height)/2, qrSize.width, qrSize.height);
vector<float> goldCorners = {rec.x, rec.y,
rec.x+rec.width, rec.y,
rec.x+rec.width, rec.y+rec.height,
rec.x, rec.y+rec.height};
Mat roiImage = image(rec);
cv::resize(qrImage, roiImage, qrSize, 1., 1., INTER_NEAREST);
vector<Mat> points1;
auto decoded_info1 = detector.detectAndDecode(image, points1);
ASSERT_EQ(1ull, decoded_info1.size());
ASSERT_EQ(expect_msg, decoded_info1[0]);
EXPECT_NEAR(0, cvtest::norm(Mat(goldCorners), points1[0].reshape(1, 8), NORM_INF), 8.);
const double angle = 45;
Point2f pc(image.cols/2.f, image.rows/2.f);
Mat rot = getRotationMatrix2D(pc, angle, 1.);
warpAffine(image, image, rot, image.size());
vector<float> rotateGoldCorners;
for (int i = 0; i < static_cast<int>(goldCorners.size()); i+= 2) {
rotateGoldCorners.push_back(rot.at<double>(0, 0) * goldCorners[i] +
rot.at<double>(0, 1) * goldCorners[i+1] + rot.at<double>(0, 2));
rotateGoldCorners.push_back(rot.at<double>(1, 0) * goldCorners[i] +
rot.at<double>(1, 1) * goldCorners[i+1] + rot.at<double>(1, 2));
}
vector<Mat> points2;
auto decoded_info2 = detector.detectAndDecode(image, points2);
ASSERT_EQ(1ull, decoded_info2.size());
ASSERT_EQ(expect_msg, decoded_info2[0]);
EXPECT_NEAR(0, cvtest::norm(Mat(rotateGoldCorners), points2[0].reshape(1, 8), NORM_INF), 11.);
}
INSTANTIATE_TEST_CASE_P(/**/, Objdetect_QRCode, testing::ValuesIn(qrcode_images_name));
INSTANTIATE_TEST_CASE_P(/**/, Objdetect_QRCode_Close, testing::ValuesIn(qrcode_images_close));
INSTANTIATE_TEST_CASE_P(/**/, Objdetect_QRCode_Monitor, testing::ValuesIn(qrcode_images_monitor));

Loading…
Cancel
Save