Skip to content

Commit

Permalink
add scaleFactor/setScaleFactor/getScaleFactor
Browse files Browse the repository at this point in the history
add test

add dnn data search
  • Loading branch information
AleksandrPanov committed Aug 29, 2022
1 parent 087a100 commit 2b0bbb5
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 8 deletions.
2 changes: 1 addition & 1 deletion modules/wechat_qrcode/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
set(the_description "WeChat QR code Detector")
ocv_define_module(wechat_qrcode opencv_core opencv_imgproc opencv_dnn WRAP java objc python js)
ocv_define_module(wechat_qrcode opencv_core opencv_imgproc opencv_objdetect opencv_dnn WRAP java objc python js)

# iconv support isn't automatic on some systems
if(CMAKE_VERSION VERSION_GREATER "3.11")
Expand Down
19 changes: 17 additions & 2 deletions modules/wechat_qrcode/include/opencv2/wechat_qrcode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,23 @@ class CV_EXPORTS_W WeChatQRCode {
* empty if not found.
* @return list of decoded string.
*/
CV_WRAP std::vector<std::string> detectAndDecode(InputArray img,
OutputArrayOfArrays points = noArray());
CV_WRAP std::vector<std::string> detectAndDecode(InputArray img, OutputArrayOfArrays points = noArray());

/**
* @brief set scale factor
* QR code detector use neural network to detect QR.
* Before running the neural network, the input image is pre-processed by scaling.
* By default, the input image is scaled to an image with an area of 160000 pixels.
* The scale factor allows to use custom scale the input image:
* width = scaleFactor*width
* height = scaleFactor*width
*
* scaleFactor valuse must be > 0 and <= 1, otherwise the scaleFactor value is set to -1
* and use default scaled to an image with an area of 160000 pixels.
*/
CV_WRAP void setScaleFactor(float _scalingFactor);

CV_WRAP float getScaleFactor();

protected:
class Impl;
Expand Down
20 changes: 16 additions & 4 deletions modules/wechat_qrcode/src/wechat_qrcode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class WeChatQRCode::Impl {
std::shared_ptr<SSDDetector> detector_;
std::shared_ptr<SuperScale> super_resolution_model_;
bool use_nn_detector_, use_nn_sr_;
float scaleFactor = -1.f;
};

WeChatQRCode::WeChatQRCode(const String& detector_prototxt_path,
Expand Down Expand Up @@ -109,6 +110,17 @@ vector<string> WeChatQRCode::detectAndDecode(InputArray img, OutputArrayOfArrays
points.assign(tmp_points);
}
return ret;
}

void WeChatQRCode::setScaleFactor(float _scaleFactor) {
if (_scaleFactor > 0 && _scaleFactor <= 1.f)
p->scaleFactor = _scaleFactor;
else
p->scaleFactor = -1.f;
};

float WeChatQRCode::getScaleFactor() {
return p->scaleFactor;
};

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

const float targetArea = 400.f * 400.f;
// hard code input size
int minInputSize = 400;
float resizeRatio = sqrt(img_w * img_h * 1.0 / (minInputSize * minInputSize));
int detect_width = img_w / resizeRatio;
int detect_height = img_h / resizeRatio;
const float tmpScaleFactor = scaleFactor == -1.f ? sqrt(targetArea / (img_w * img_h)) : scaleFactor;
int detect_width = img_w * tmpScaleFactor;
int detect_height = img_h * tmpScaleFactor;

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

Expand Down
17 changes: 16 additions & 1 deletion modules/wechat_qrcode/test/test_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,19 @@
#include <hpx/hpx_main.hpp>
#endif

CV_TEST_MAIN("cv")
static
void initTests()
{
#ifdef HAVE_OPENCV_DNN
const char* extraTestDataPath =
#ifdef WINRT
NULL;
#else
getenv("OPENCV_DNN_TEST_DATA_PATH");
#endif
if (extraTestDataPath)
cvtest::addDataSearchPath(extraTestDataPath);
#endif // HAVE_OPENCV_DNN
}

CV_TEST_MAIN("cv", initTests())
33 changes: 33 additions & 0 deletions modules/wechat_qrcode/test/test_qrcode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.

#include "test_precomp.hpp"
#include "opencv2/objdetect.hpp"

namespace opencv_test {
namespace {
Expand Down Expand Up @@ -289,5 +290,37 @@ INSTANTIATE_TEST_CASE_P(/**/, Objdetect_QRCode_Monitor, testing::ValuesIn(qrcode
INSTANTIATE_TEST_CASE_P(/**/, Objdetect_QRCode_Curved, testing::ValuesIn(qrcode_images_curved));
// INSTANTIATE_TEST_CASE_P(/**/, Objdetect_QRCode_Multi, testing::ValuesIn(qrcode_images_multiple));

TEST(Objdetect_QRCode_Big, regression) {
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 = 4; // 33x33
Ptr<QRCodeEncoder> qrcode_enc = cv::QRCodeEncoder::create(params);
Mat qrImage;
qrcode_enc->encode(expect_msg, qrImage);
Mat largeImage(4032, 3024, CV_8UC1);
const int pixInBlob = 4;
Size qrSize = Size((21+(params.version-1)*4)*pixInBlob,(21+(params.version-1)*4)*pixInBlob);
Mat roiImage = largeImage(Rect((largeImage.cols - qrSize.width)/2, (largeImage.rows - qrSize.height)/2,
qrSize.width, qrSize.height));
cv::resize(qrImage, roiImage, qrSize, 1., 1., INTER_NEAREST);

vector<Mat> points;
detector.setScaleFactor(0.25f);
auto decoded_info = detector.detectAndDecode(largeImage, points);
ASSERT_EQ(1ull, decoded_info.size());
ASSERT_EQ(expect_msg, decoded_info[0]);
}


} // namespace
} // namespace opencv_test

0 comments on commit 2b0bbb5

Please sign in to comment.