Skip to content

Commit 7668d0a

Browse files
committed
add contrib:wechat_qrcode
1 parent f644870 commit 7668d0a

File tree

10 files changed

+357
-1
lines changed

10 files changed

+357
-1
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ set(OpenCV_LIBS
1616
opencv_aruco opencv_core opencv_calib3d opencv_dnn opencv_highgui
1717
opencv_features2d opencv_gapi opencv_photo opencv_imgproc
1818
opencv_objdetect opencv_video opencv_videoio opencv_stitching
19-
opencv_img_hash
19+
opencv_img_hash opencv_wechat_qrcode
2020
)
2121

2222
if(ANDROID)

ffigen.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ headers:
2424
- src/dnn/dnn.h
2525
- src/extra/aruco.h
2626
- src/extra/img_hash.h
27+
- src/extra/wechat_qrcode.h
2728
- src/features2d/features2d.h
2829
- src/highgui/highgui.h
2930
- src/imgcodecs/imgcodecs.h
@@ -44,6 +45,7 @@ headers:
4445
- src/dnn/dnn.h
4546
- src/extra/aruco.h
4647
- src/extra/img_hash.h
48+
- src/extra/wechat_qrcode.h
4749
- src/features2d/features2d.h
4850
- src/highgui/highgui.h
4951
- src/imgcodecs/imgcodecs.h

lib/src/contrib/wechat_qrcode.dart

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
library cv;
2+
3+
import 'dart:ffi' as ffi;
4+
5+
import 'package:ffi/ffi.dart';
6+
7+
import '../core/base.dart';
8+
import '../core/mat.dart';
9+
import '../core/vec.dart';
10+
import '../opencv.g.dart' as cvg;
11+
12+
class WeChatQRCode extends CvStruct<cvg.WeChatQRCode> {
13+
WeChatQRCode._(super.ptr) : super.fromPointer() {
14+
finalizer.attach(this, ptr.cast());
15+
}
16+
17+
factory WeChatQRCode.empty() {
18+
final p = calloc<cvg.WeChatQRCode>();
19+
cvRun(() => CFFI.WeChatQRCode_New(p));
20+
return WeChatQRCode._(p);
21+
}
22+
23+
/// Initialize the WeChatQRCode.
24+
/// It includes two models, which are packaged with caffe format.
25+
/// Therefore, there are prototxt and caffe models (In total, four paramenters).
26+
///
27+
/// https://docs.opencv.org/4.x/d5/d04/classcv_1_1wechat__qrcode_1_1WeChatQRCode.html#a9c0dc4c37646a1a051340d6b0916f388
28+
factory WeChatQRCode([
29+
String detectorPrototxtPath = "",
30+
String detectorCaffeModelPath = "",
31+
String superResolutionPrototxtPath = "",
32+
String superResolutionCaffeModelPath = "",
33+
]) {
34+
return cvRunArena<WeChatQRCode>((arena) {
35+
final p = calloc<cvg.WeChatQRCode>();
36+
final dp = detectorPrototxtPath.toNativeUtf8(allocator: arena).cast<ffi.Char>();
37+
final dm = detectorCaffeModelPath.toNativeUtf8(allocator: arena).cast<ffi.Char>();
38+
final srp = superResolutionPrototxtPath.toNativeUtf8(allocator: arena).cast<ffi.Char>();
39+
final srm = superResolutionCaffeModelPath.toNativeUtf8(allocator: arena).cast<ffi.Char>();
40+
cvRun(() => CFFI.WeChatQRCode_NewWithParams(dp, dm, srp, srm, p));
41+
return WeChatQRCode._(p);
42+
});
43+
}
44+
45+
/// Both detects and decodes QR code. To simplify the usage, there is a only API: detectAndDecode.
46+
/// https://docs.opencv.org/4.x/d5/d04/classcv_1_1wechat__qrcode_1_1WeChatQRCode.html#a27c167d2d58e5ee4418fd3a9ed5876cc
47+
(List<String>, VecMat points) detectAndDecode(InputArray img, [VecMat? points]) {
48+
final p = calloc<cvg.VecMat>();
49+
final rval = calloc<cvg.VecVecChar>();
50+
cvRun(() => CFFI.WeChatQRCode_DetectAndDecode(ptr, img.ref, p, rval));
51+
final vec = VecVecChar.fromPointer(rval);
52+
final points = VecMat.fromPointer(p);
53+
return (vec.asStringList(), points);
54+
}
55+
56+
/// https://docs.opencv.org/4.x/d5/d04/classcv_1_1wechat__qrcode_1_1WeChatQRCode.html#abf807138abc2626c159abd3e9a80e791
57+
double get scaleFactor {
58+
return cvRunArena<double>((arena) {
59+
final p = calloc<ffi.Float>();
60+
cvRun(() => CFFI.WeChatQRCode_GetScaleFactor(ptr, p));
61+
return p.value;
62+
});
63+
}
64+
65+
/// set scale factor QR code detector use neural network to detect QR.
66+
/// Before running the neural network, the input image is pre-processed by scaling.
67+
/// By default, the input image is scaled to an image with an area of 160000 pixels.
68+
/// The scale factor allows to use custom scale the input image:
69+
/// width = scaleFactor*width height = scaleFactor*width
70+
///
71+
/// scaleFactor valuse must be > 0 and <= 1,
72+
/// otherwise the scaleFactor value is set to -1 and
73+
/// use default scaled to an image with an area of 160000 pixels.
74+
///
75+
/// https://docs.opencv.org/4.x/d5/d04/classcv_1_1wechat__qrcode_1_1WeChatQRCode.html#a084f9aa8693fa0a62c43dd10d2533ab8
76+
set scaleFactor(double scaleFactor) {
77+
cvRun(() => CFFI.WeChatQRCode_SetScaleFactor(ptr, scaleFactor));
78+
}
79+
80+
static final finalizer = OcvFinalizer<cvg.WeChatQRCodePtr>(CFFI.addresses.WeChatQRCode_Close);
81+
82+
@override
83+
List<int> get props => [ptr.address];
84+
85+
@override
86+
cvg.WeChatQRCode get ref => ptr.ref;
87+
}

lib/src/opencv.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export 'constants.g.dart';
55
export 'contrib/aruco.dart';
66
export 'contrib/aruco_dict.dart';
77
export 'contrib/img_hash.dart';
8+
export 'contrib/wechat_qrcode.dart';
89

910
export 'core/array.dart';
1011
export 'core/asyncarray.dart';

lib/src/opencv.g.dart

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15867,6 +15867,126 @@ class CvNative {
1586715867
late final _Watershed =
1586815868
_WatershedPtr.asFunction<CvStatus Function(Mat, Mat)>();
1586915869

15870+
void WeChatQRCode_Close(
15871+
ffi.Pointer<WeChatQRCode> self,
15872+
) {
15873+
return _WeChatQRCode_Close(
15874+
self,
15875+
);
15876+
}
15877+
15878+
late final _WeChatQRCode_ClosePtr =
15879+
_lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<WeChatQRCode>)>>(
15880+
'WeChatQRCode_Close');
15881+
late final _WeChatQRCode_Close = _WeChatQRCode_ClosePtr.asFunction<
15882+
void Function(ffi.Pointer<WeChatQRCode>)>();
15883+
15884+
CvStatus WeChatQRCode_DetectAndDecode(
15885+
ffi.Pointer<WeChatQRCode> self,
15886+
Mat img,
15887+
ffi.Pointer<VecMat> points,
15888+
ffi.Pointer<VecVecChar> rval,
15889+
) {
15890+
return _WeChatQRCode_DetectAndDecode(
15891+
self,
15892+
img,
15893+
points,
15894+
rval,
15895+
);
15896+
}
15897+
15898+
late final _WeChatQRCode_DetectAndDecodePtr = _lookup<
15899+
ffi.NativeFunction<
15900+
CvStatus Function(ffi.Pointer<WeChatQRCode>, Mat, ffi.Pointer<VecMat>,
15901+
ffi.Pointer<VecVecChar>)>>('WeChatQRCode_DetectAndDecode');
15902+
late final _WeChatQRCode_DetectAndDecode =
15903+
_WeChatQRCode_DetectAndDecodePtr.asFunction<
15904+
CvStatus Function(ffi.Pointer<WeChatQRCode>, Mat, ffi.Pointer<VecMat>,
15905+
ffi.Pointer<VecVecChar>)>();
15906+
15907+
CvStatus WeChatQRCode_GetScaleFactor(
15908+
ffi.Pointer<WeChatQRCode> self,
15909+
ffi.Pointer<ffi.Float> rval,
15910+
) {
15911+
return _WeChatQRCode_GetScaleFactor(
15912+
self,
15913+
rval,
15914+
);
15915+
}
15916+
15917+
late final _WeChatQRCode_GetScaleFactorPtr = _lookup<
15918+
ffi.NativeFunction<
15919+
CvStatus Function(ffi.Pointer<WeChatQRCode>,
15920+
ffi.Pointer<ffi.Float>)>>('WeChatQRCode_GetScaleFactor');
15921+
late final _WeChatQRCode_GetScaleFactor =
15922+
_WeChatQRCode_GetScaleFactorPtr.asFunction<
15923+
CvStatus Function(
15924+
ffi.Pointer<WeChatQRCode>, ffi.Pointer<ffi.Float>)>();
15925+
15926+
CvStatus WeChatQRCode_New(
15927+
ffi.Pointer<WeChatQRCode> qrcode,
15928+
) {
15929+
return _WeChatQRCode_New(
15930+
qrcode,
15931+
);
15932+
}
15933+
15934+
late final _WeChatQRCode_NewPtr =
15935+
_lookup<ffi.NativeFunction<CvStatus Function(ffi.Pointer<WeChatQRCode>)>>(
15936+
'WeChatQRCode_New');
15937+
late final _WeChatQRCode_New = _WeChatQRCode_NewPtr.asFunction<
15938+
CvStatus Function(ffi.Pointer<WeChatQRCode>)>();
15939+
15940+
CvStatus WeChatQRCode_NewWithParams(
15941+
ffi.Pointer<ffi.Char> detector_prototxt_path,
15942+
ffi.Pointer<ffi.Char> detector_caffe_model_path,
15943+
ffi.Pointer<ffi.Char> super_resolution_prototxt_path,
15944+
ffi.Pointer<ffi.Char> super_resolution_caffe_model_path,
15945+
ffi.Pointer<WeChatQRCode> qrcode,
15946+
) {
15947+
return _WeChatQRCode_NewWithParams(
15948+
detector_prototxt_path,
15949+
detector_caffe_model_path,
15950+
super_resolution_prototxt_path,
15951+
super_resolution_caffe_model_path,
15952+
qrcode,
15953+
);
15954+
}
15955+
15956+
late final _WeChatQRCode_NewWithParamsPtr = _lookup<
15957+
ffi.NativeFunction<
15958+
CvStatus Function(
15959+
ffi.Pointer<ffi.Char>,
15960+
ffi.Pointer<ffi.Char>,
15961+
ffi.Pointer<ffi.Char>,
15962+
ffi.Pointer<ffi.Char>,
15963+
ffi.Pointer<WeChatQRCode>)>>('WeChatQRCode_NewWithParams');
15964+
late final _WeChatQRCode_NewWithParams =
15965+
_WeChatQRCode_NewWithParamsPtr.asFunction<
15966+
CvStatus Function(
15967+
ffi.Pointer<ffi.Char>,
15968+
ffi.Pointer<ffi.Char>,
15969+
ffi.Pointer<ffi.Char>,
15970+
ffi.Pointer<ffi.Char>,
15971+
ffi.Pointer<WeChatQRCode>)>();
15972+
15973+
CvStatus WeChatQRCode_SetScaleFactor(
15974+
ffi.Pointer<WeChatQRCode> self,
15975+
double scale_factor,
15976+
) {
15977+
return _WeChatQRCode_SetScaleFactor(
15978+
self,
15979+
scale_factor,
15980+
);
15981+
}
15982+
15983+
late final _WeChatQRCode_SetScaleFactorPtr = _lookup<
15984+
ffi.NativeFunction<
15985+
CvStatus Function(ffi.Pointer<WeChatQRCode>,
15986+
ffi.Float)>>('WeChatQRCode_SetScaleFactor');
15987+
late final _WeChatQRCode_SetScaleFactor = _WeChatQRCode_SetScaleFactorPtr
15988+
.asFunction<CvStatus Function(ffi.Pointer<WeChatQRCode>, double)>();
15989+
1587015990
void Window_Close(
1587115991
ffi.Pointer<ffi.Char> winname,
1587215992
) {
@@ -16513,6 +16633,8 @@ class _SymbolAddresses {
1651316633
get VideoCapture_Close => _library._VideoCapture_ClosePtr;
1651416634
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<VideoWriter>)>>
1651516635
get VideoWriter_Close => _library._VideoWriter_ClosePtr;
16636+
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<WeChatQRCode>)>>
16637+
get WeChatQRCode_Close => _library._WeChatQRCode_ClosePtr;
1651616638
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Char>)>>
1651716639
get Window_Close => _library._Window_ClosePtr;
1651816640
}
@@ -17205,6 +17327,13 @@ final class NO_USE_VideoWriterPtr extends ffi.Struct {
1720517327
external ffi.Pointer<VideoWriterPtr> p;
1720617328
}
1720717329

17330+
/// \
17331+
/// Dart ffigen will not generate typedefs if not referred \
17332+
/// so here we confirm they are included \
17333+
final class NO_USE_WeChatQRCodePtr extends ffi.Struct {
17334+
external ffi.Pointer<WeChatQRCodePtr> p;
17335+
}
17336+
1720817337
final class Net extends ffi.Struct {
1720917338
external ffi.Pointer<ffi.Void> ptr;
1721017339
}
@@ -17836,6 +17965,12 @@ final class VideoWriter extends ffi.Struct {
1783617965
}
1783717966

1783817967
typedef VideoWriterPtr = ffi.Pointer<VideoWriter>;
17968+
17969+
final class WeChatQRCode extends ffi.Struct {
17970+
external ffi.Pointer<ffi.Void> ptr;
17971+
}
17972+
17973+
typedef WeChatQRCodePtr = ffi.Pointer<WeChatQRCode>;
1783917974
typedef double_t = ffi.Double;
1784017975
typedef Dartdouble_t = double;
1784117976
typedef float_t = ffi.Float;

src/extra/wechat_qrcode.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#include "wechat_qrcode.h"
2+
#include <vector>
3+
4+
CvStatus WeChatQRCode_New(WeChatQRCode *qrcode)
5+
{
6+
BEGIN_WRAP
7+
*qrcode = {new cv::wechat_qrcode::WeChatQRCode()};
8+
END_WRAP
9+
}
10+
CvStatus WeChatQRCode_NewWithParams(const char *detector_prototxt_path, const char *detector_caffe_model_path,
11+
const char *super_resolution_prototxt_path,
12+
const char *super_resolution_caffe_model_path, WeChatQRCode *qrcode)
13+
{
14+
BEGIN_WRAP
15+
*qrcode = {new cv::wechat_qrcode::WeChatQRCode(detector_prototxt_path, detector_caffe_model_path,
16+
super_resolution_prototxt_path,
17+
super_resolution_caffe_model_path)};
18+
END_WRAP
19+
}
20+
void WeChatQRCode_Close(WeChatQRCode *self)
21+
{
22+
delete self->ptr;
23+
self->ptr = nullptr;
24+
delete self;
25+
self = nullptr;
26+
}
27+
CvStatus WeChatQRCode_DetectAndDecode(WeChatQRCode *self, Mat img, VecMat *points, VecVecChar *rval)
28+
{
29+
BEGIN_WRAP
30+
std::vector<cv::Mat> pts;
31+
32+
auto strings = self->ptr->detectAndDecode(*img.ptr, pts);
33+
*points = {new std::vector<cv::Mat>(pts)};
34+
35+
auto cstrings = new std::vector<std::vector<char>>();
36+
cstrings->reserve(strings.size());
37+
for (int i = 0; i < strings.size(); i++) {
38+
auto s = strings.at(i);
39+
cstrings->push_back(std::vector<char>(s.begin(), s.end()));
40+
}
41+
*rval = {cstrings};
42+
43+
END_WRAP
44+
}
45+
CvStatus WeChatQRCode_GetScaleFactor(WeChatQRCode *self, float *rval)
46+
{
47+
BEGIN_WRAP
48+
*rval = self->ptr->getScaleFactor();
49+
END_WRAP
50+
}
51+
CvStatus WeChatQRCode_SetScaleFactor(WeChatQRCode *self, float scale_factor)
52+
{
53+
BEGIN_WRAP
54+
self->ptr->setScaleFactor(scale_factor);
55+
END_WRAP
56+
}

src/extra/wechat_qrcode.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
Created by Rainyl.
3+
Licensed: Apache 2.0 license. Copyright (c) 2024 Rainyl.
4+
*/
5+
#pragma once
6+
#ifndef WECHAT_QRCODE_H
7+
#define WECHAT_QRCODE_H
8+
9+
#include "core/core.h"
10+
11+
#ifdef __cplusplus
12+
#include <opencv2/opencv.hpp>
13+
#include <opencv2/wechat_qrcode.hpp>
14+
extern "C" {
15+
#endif
16+
17+
// Main Content Start
18+
#ifdef __cplusplus
19+
CVD_TYPEDEF(cv::wechat_qrcode::WeChatQRCode, WeChatQRCode)
20+
#else
21+
CVD_TYPEDEF(void, WeChatQRCode)
22+
#endif
23+
24+
CVD_TYPEDEF_PTR(WeChatQRCode)
25+
26+
CvStatus WeChatQRCode_New(WeChatQRCode *qrcode);
27+
CvStatus WeChatQRCode_NewWithParams(const char *detector_prototxt_path, const char *detector_caffe_model_path,
28+
const char *super_resolution_prototxt_path,
29+
const char *super_resolution_caffe_model_path, WeChatQRCode *qrcode);
30+
void WeChatQRCode_Close(WeChatQRCode *self);
31+
CvStatus WeChatQRCode_DetectAndDecode(WeChatQRCode *self, Mat img, VecMat *points, VecVecChar *rval);
32+
CvStatus WeChatQRCode_GetScaleFactor(WeChatQRCode *self, float *rval);
33+
CvStatus WeChatQRCode_SetScaleFactor(WeChatQRCode *self, float scale_factor);
34+
35+
// Main Content End
36+
37+
#ifdef __cplusplus
38+
}
39+
#endif
40+
41+
#endif
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)