Skip to content

Commit 2b0bbb5

Browse files
author
AleksandrPanov
committed
add scaleFactor/setScaleFactor/getScaleFactor
add test add dnn data search
1 parent 087a100 commit 2b0bbb5

File tree

5 files changed

+83
-8
lines changed

5 files changed

+83
-8
lines changed

modules/wechat_qrcode/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
set(the_description "WeChat QR code Detector")
2-
ocv_define_module(wechat_qrcode opencv_core opencv_imgproc opencv_dnn WRAP java objc python js)
2+
ocv_define_module(wechat_qrcode opencv_core opencv_imgproc opencv_objdetect opencv_dnn WRAP java objc python js)
33

44
# iconv support isn't automatic on some systems
55
if(CMAKE_VERSION VERSION_GREATER "3.11")

modules/wechat_qrcode/include/opencv2/wechat_qrcode.hpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,23 @@ class CV_EXPORTS_W WeChatQRCode {
4848
* empty if not found.
4949
* @return list of decoded string.
5050
*/
51-
CV_WRAP std::vector<std::string> detectAndDecode(InputArray img,
52-
OutputArrayOfArrays points = noArray());
51+
CV_WRAP std::vector<std::string> detectAndDecode(InputArray img, OutputArrayOfArrays points = noArray());
52+
53+
/**
54+
* @brief set scale factor
55+
* QR code detector use neural network to detect QR.
56+
* Before running the neural network, the input image is pre-processed by scaling.
57+
* By default, the input image is scaled to an image with an area of 160000 pixels.
58+
* The scale factor allows to use custom scale the input image:
59+
* width = scaleFactor*width
60+
* height = scaleFactor*width
61+
*
62+
* scaleFactor valuse must be > 0 and <= 1, otherwise the scaleFactor value is set to -1
63+
* and use default scaled to an image with an area of 160000 pixels.
64+
*/
65+
CV_WRAP void setScaleFactor(float _scalingFactor);
66+
67+
CV_WRAP float getScaleFactor();
5368

5469
protected:
5570
class Impl;

modules/wechat_qrcode/src/wechat_qrcode.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class WeChatQRCode::Impl {
4343
std::shared_ptr<SSDDetector> detector_;
4444
std::shared_ptr<SuperScale> super_resolution_model_;
4545
bool use_nn_detector_, use_nn_sr_;
46+
float scaleFactor = -1.f;
4647
};
4748

4849
WeChatQRCode::WeChatQRCode(const String& detector_prototxt_path,
@@ -109,6 +110,17 @@ vector<string> WeChatQRCode::detectAndDecode(InputArray img, OutputArrayOfArrays
109110
points.assign(tmp_points);
110111
}
111112
return ret;
113+
}
114+
115+
void WeChatQRCode::setScaleFactor(float _scaleFactor) {
116+
if (_scaleFactor > 0 && _scaleFactor <= 1.f)
117+
p->scaleFactor = _scaleFactor;
118+
else
119+
p->scaleFactor = -1.f;
120+
};
121+
122+
float WeChatQRCode::getScaleFactor() {
123+
return p->scaleFactor;
112124
};
113125

114126
vector<string> WeChatQRCode::Impl::decode(const Mat& img, vector<Mat>& candidate_points,
@@ -173,11 +185,11 @@ int WeChatQRCode::Impl::applyDetector(const Mat& img, vector<Mat>& points) {
173185
int img_w = img.cols;
174186
int img_h = img.rows;
175187

188+
const float targetArea = 400.f * 400.f;
176189
// hard code input size
177-
int minInputSize = 400;
178-
float resizeRatio = sqrt(img_w * img_h * 1.0 / (minInputSize * minInputSize));
179-
int detect_width = img_w / resizeRatio;
180-
int detect_height = img_h / resizeRatio;
190+
const float tmpScaleFactor = scaleFactor == -1.f ? sqrt(targetArea / (img_w * img_h)) : scaleFactor;
191+
int detect_width = img_w * tmpScaleFactor;
192+
int detect_height = img_h * tmpScaleFactor;
181193

182194
points = detector_->forward(img, detect_width, detect_height);
183195

modules/wechat_qrcode/test/test_main.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,19 @@
1111
#include <hpx/hpx_main.hpp>
1212
#endif
1313

14-
CV_TEST_MAIN("cv")
14+
static
15+
void initTests()
16+
{
17+
#ifdef HAVE_OPENCV_DNN
18+
const char* extraTestDataPath =
19+
#ifdef WINRT
20+
NULL;
21+
#else
22+
getenv("OPENCV_DNN_TEST_DATA_PATH");
23+
#endif
24+
if (extraTestDataPath)
25+
cvtest::addDataSearchPath(extraTestDataPath);
26+
#endif // HAVE_OPENCV_DNN
27+
}
28+
29+
CV_TEST_MAIN("cv", initTests())

modules/wechat_qrcode/test/test_qrcode.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
// Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
77

88
#include "test_precomp.hpp"
9+
#include "opencv2/objdetect.hpp"
910

1011
namespace opencv_test {
1112
namespace {
@@ -289,5 +290,37 @@ INSTANTIATE_TEST_CASE_P(/**/, Objdetect_QRCode_Monitor, testing::ValuesIn(qrcode
289290
INSTANTIATE_TEST_CASE_P(/**/, Objdetect_QRCode_Curved, testing::ValuesIn(qrcode_images_curved));
290291
// INSTANTIATE_TEST_CASE_P(/**/, Objdetect_QRCode_Multi, testing::ValuesIn(qrcode_images_multiple));
291292

293+
TEST(Objdetect_QRCode_Big, regression) {
294+
string path_detect_prototxt, path_detect_caffemodel, path_sr_prototxt, path_sr_caffemodel;
295+
string model_version = "_2021-01";
296+
path_detect_prototxt = findDataFile("dnn/wechat"+model_version+"/detect.prototxt", false);
297+
path_detect_caffemodel = findDataFile("dnn/wechat"+model_version+"/detect.caffemodel", false);
298+
path_sr_prototxt = findDataFile("dnn/wechat"+model_version+"/sr.prototxt", false);
299+
path_sr_caffemodel = findDataFile("dnn/wechat"+model_version+"/sr.caffemodel", false);
300+
301+
auto detector = wechat_qrcode::WeChatQRCode(path_detect_prototxt, path_detect_caffemodel, path_sr_prototxt,
302+
path_sr_caffemodel);
303+
304+
const cv::String expect_msg = "OpenCV";
305+
QRCodeEncoder::Params params;
306+
params.version = 4; // 33x33
307+
Ptr<QRCodeEncoder> qrcode_enc = cv::QRCodeEncoder::create(params);
308+
Mat qrImage;
309+
qrcode_enc->encode(expect_msg, qrImage);
310+
Mat largeImage(4032, 3024, CV_8UC1);
311+
const int pixInBlob = 4;
312+
Size qrSize = Size((21+(params.version-1)*4)*pixInBlob,(21+(params.version-1)*4)*pixInBlob);
313+
Mat roiImage = largeImage(Rect((largeImage.cols - qrSize.width)/2, (largeImage.rows - qrSize.height)/2,
314+
qrSize.width, qrSize.height));
315+
cv::resize(qrImage, roiImage, qrSize, 1., 1., INTER_NEAREST);
316+
317+
vector<Mat> points;
318+
detector.setScaleFactor(0.25f);
319+
auto decoded_info = detector.detectAndDecode(largeImage, points);
320+
ASSERT_EQ(1ull, decoded_info.size());
321+
ASSERT_EQ(expect_msg, decoded_info[0]);
322+
}
323+
324+
292325
} // namespace
293326
} // namespace opencv_test

0 commit comments

Comments
 (0)