Skip to content

Commit 47bf66f

Browse files
authored
Merge pull request #3289 from AleksandrPanov:wechat_fix_output_qr_corners
fix output qr corners
2 parents ebd6445 + cee17e4 commit 47bf66f

File tree

4 files changed

+75
-5
lines changed

4 files changed

+75
-5
lines changed

modules/wechat_qrcode/src/decodermgr.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ using zxing::Result;
1818
using zxing::UnicomBlock;
1919
namespace cv {
2020
namespace wechat_qrcode {
21-
int DecoderMgr::decodeImage(cv::Mat src, bool use_nn_detector, string& result) {
21+
int DecoderMgr::decodeImage(cv::Mat src, bool use_nn_detector, string& result, vector<Point2f>& points) {
2222
int width = src.cols;
2323
int height = src.rows;
2424
if (width <= 20 || height <= 20)
@@ -46,6 +46,14 @@ int DecoderMgr::decodeImage(cv::Mat src, bool use_nn_detector, string& result) {
4646
int ret = TryDecode(source, zx_result);
4747
if (!ret) {
4848
result = zx_result->getText()->getText();
49+
auto result_points = zx_result->getResultPoints();
50+
for(int i = 0; i < result_points->size() / 4; i++) {
51+
const int ind = i * 4;
52+
for (int j = 1; j < 4; j++)
53+
points.emplace_back(result_points[ind+j]->getX(), result_points[ind+j]->getY());
54+
55+
points.emplace_back(result_points[ind]->getX(), result_points[ind]->getY());
56+
}
4957
return ret;
5058
}
5159
// try different binarizers

modules/wechat_qrcode/src/decodermgr.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class DecoderMgr {
2626
DecoderMgr() { reader_ = new zxing::qrcode::QRCodeReader(); };
2727
~DecoderMgr(){};
2828

29-
int decodeImage(cv::Mat src, bool use_nn_detector, string& result);
29+
int decodeImage(cv::Mat src, bool use_nn_detector, string& result, vector<Point2f>& points);
3030

3131
private:
3232
zxing::Ref<zxing::UnicomBlock> qbarUicomBlock_;

modules/wechat_qrcode/src/wechat_qrcode.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@ vector<string> WeChatQRCode::Impl::decode(const Mat& img, vector<Mat>& candidate
131131
vector<string> decode_results;
132132
for (auto& point : candidate_points) {
133133
Mat cropped_img;
134+
Align aligner;
134135
if (use_nn_detector_) {
135-
Align aligner;
136136
cropped_img = cropObj(img, point, aligner);
137137
} else {
138138
cropped_img = img;
@@ -144,9 +144,19 @@ vector<string> WeChatQRCode::Impl::decode(const Mat& img, vector<Mat>& candidate
144144
super_resolution_model_->processImageScale(cropped_img, cur_scale, use_nn_sr_);
145145
string result;
146146
DecoderMgr decodemgr;
147-
auto ret = decodemgr.decodeImage(scaled_img, use_nn_detector_, result);
148-
147+
vector<Point2f> points_qr;
148+
auto ret = decodemgr.decodeImage(scaled_img, use_nn_detector_, result, points_qr);
149149
if (ret == 0) {
150+
for (auto&& pt: points_qr) {
151+
pt /= cur_scale;
152+
}
153+
154+
if (use_nn_detector_)
155+
points_qr = aligner.warpBack(points_qr);
156+
for (int i = 0; i < 4; ++i) {
157+
point.at<float>(i, 0) = points_qr[i].x;
158+
point.at<float>(i, 1) = points_qr[i].y;
159+
}
150160
decode_results.push_back(result);
151161
points.push_back(point);
152162
break;

modules/wechat_qrcode/test/test_qrcode.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,58 @@ TEST_P(Objdetect_QRCode_Multi, regression) {
284284
}
285285
}
286286

287+
TEST(Objdetect_QRCode_points_position, rotate45) {
288+
string path_detect_prototxt, path_detect_caffemodel, path_sr_prototxt, path_sr_caffemodel;
289+
string model_version = "_2021-01";
290+
path_detect_prototxt = findDataFile("dnn/wechat"+model_version+"/detect.prototxt", false);
291+
path_detect_caffemodel = findDataFile("dnn/wechat"+model_version+"/detect.caffemodel", false);
292+
path_sr_prototxt = findDataFile("dnn/wechat"+model_version+"/sr.prototxt", false);
293+
path_sr_caffemodel = findDataFile("dnn/wechat"+model_version+"/sr.caffemodel", false);
294+
295+
auto detector = wechat_qrcode::WeChatQRCode(path_detect_prototxt, path_detect_caffemodel, path_sr_prototxt,
296+
path_sr_caffemodel);
297+
298+
const cv::String expect_msg = "OpenCV";
299+
QRCodeEncoder::Params params;
300+
params.version = 5; // 37x37
301+
Ptr<QRCodeEncoder> qrcode_enc = cv::QRCodeEncoder::create(params);
302+
Mat qrImage;
303+
qrcode_enc->encode(expect_msg, qrImage);
304+
Mat image(800, 800, CV_8UC1);
305+
const int pixInBlob = 4;
306+
Size qrSize = Size((21+(params.version-1)*4)*pixInBlob,(21+(params.version-1)*4)*pixInBlob);
307+
Rect2f rec((image.cols - qrSize.width)/2, (image.rows - qrSize.height)/2, qrSize.width, qrSize.height);
308+
vector<float> goldCorners = {rec.x, rec.y,
309+
rec.x+rec.width, rec.y,
310+
rec.x+rec.width, rec.y+rec.height,
311+
rec.x, rec.y+rec.height};
312+
Mat roiImage = image(rec);
313+
cv::resize(qrImage, roiImage, qrSize, 1., 1., INTER_NEAREST);
314+
315+
vector<Mat> points1;
316+
auto decoded_info1 = detector.detectAndDecode(image, points1);
317+
ASSERT_EQ(1ull, decoded_info1.size());
318+
ASSERT_EQ(expect_msg, decoded_info1[0]);
319+
EXPECT_NEAR(0, cvtest::norm(Mat(goldCorners), points1[0].reshape(1, 8), NORM_INF), 8.);
320+
321+
const double angle = 45;
322+
Point2f pc(image.cols/2.f, image.rows/2.f);
323+
Mat rot = getRotationMatrix2D(pc, angle, 1.);
324+
warpAffine(image, image, rot, image.size());
325+
vector<float> rotateGoldCorners;
326+
for (int i = 0; i < static_cast<int>(goldCorners.size()); i+= 2) {
327+
rotateGoldCorners.push_back(rot.at<double>(0, 0) * goldCorners[i] +
328+
rot.at<double>(0, 1) * goldCorners[i+1] + rot.at<double>(0, 2));
329+
rotateGoldCorners.push_back(rot.at<double>(1, 0) * goldCorners[i] +
330+
rot.at<double>(1, 1) * goldCorners[i+1] + rot.at<double>(1, 2));
331+
}
332+
vector<Mat> points2;
333+
auto decoded_info2 = detector.detectAndDecode(image, points2);
334+
ASSERT_EQ(1ull, decoded_info2.size());
335+
ASSERT_EQ(expect_msg, decoded_info2[0]);
336+
EXPECT_NEAR(0, cvtest::norm(Mat(rotateGoldCorners), points2[0].reshape(1, 8), NORM_INF), 11.);
337+
}
338+
287339
INSTANTIATE_TEST_CASE_P(/**/, Objdetect_QRCode, testing::ValuesIn(qrcode_images_name));
288340
INSTANTIATE_TEST_CASE_P(/**/, Objdetect_QRCode_Close, testing::ValuesIn(qrcode_images_close));
289341
INSTANTIATE_TEST_CASE_P(/**/, Objdetect_QRCode_Monitor, testing::ValuesIn(qrcode_images_monitor));

0 commit comments

Comments
 (0)