Skip to content

Commit c538c3d

Browse files
committed
Add morphology functions
1 parent 998f8bf commit c538c3d

File tree

3 files changed

+173
-23
lines changed

3 files changed

+173
-23
lines changed

src/imgproc.cpp

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,122 @@ mp_obj_t cv2_imgproc_cvtColor(size_t n_args, const mp_obj_t *pos_args, mp_map_t
4040
// Return the result
4141
return mat_to_mp_obj(dst);
4242
}
43+
44+
mp_obj_t cv2_imgproc_dilate(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
45+
// Define the arguments
46+
enum { ARG_src, ARG_kernel, ARG_dst };
47+
static const mp_arg_t allowed_args[] = {
48+
{ MP_QSTR_src, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } },
49+
{ MP_QSTR_kernel, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } },
50+
{ MP_QSTR_dst, MP_ARG_OBJ, { .u_obj = mp_const_none } },
51+
};
52+
53+
// Parse the arguments
54+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
55+
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
56+
57+
// Convert arguments to required types
58+
Mat src = mp_obj_to_mat(args[ARG_src].u_obj);
59+
Mat kernel = mp_obj_to_mat(args[ARG_kernel].u_obj);
60+
Mat dst = mp_obj_to_mat(args[ARG_dst].u_obj);
61+
62+
// Call the corresponding OpenCV function
63+
try {
64+
dilate(src, dst, kernel);
65+
} catch(Exception& e) {
66+
mp_raise_msg(&mp_type_Exception, MP_ERROR_TEXT(e.what()));
67+
}
68+
69+
// Return the result
70+
return mat_to_mp_obj(dst);
71+
}
72+
73+
mp_obj_t cv2_imgproc_erode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
74+
// Define the arguments
75+
enum { ARG_src, ARG_kernel, ARG_dst };
76+
static const mp_arg_t allowed_args[] = {
77+
{ MP_QSTR_src, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } },
78+
{ MP_QSTR_kernel, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } },
79+
{ MP_QSTR_dst, MP_ARG_OBJ, { .u_obj = mp_const_none } },
80+
};
81+
82+
// Parse the arguments
83+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
84+
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
85+
86+
// Convert arguments to required types
87+
Mat src = mp_obj_to_mat(args[ARG_src].u_obj);
88+
Mat kernel = mp_obj_to_mat(args[ARG_kernel].u_obj);
89+
Mat dst = mp_obj_to_mat(args[ARG_dst].u_obj);
90+
91+
// Call the corresponding OpenCV function
92+
try {
93+
erode(src, dst, kernel);
94+
} catch(Exception& e) {
95+
mp_raise_msg(&mp_type_Exception, MP_ERROR_TEXT(e.what()));
96+
}
97+
98+
// Return the result
99+
return mat_to_mp_obj(dst);
100+
}
101+
102+
mp_obj_t cv2_imgproc_getStructuringElement(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
103+
// Define the arguments
104+
enum { ARG_shape, ARG_ksize };
105+
static const mp_arg_t allowed_args[] = {
106+
{ MP_QSTR_shape, MP_ARG_REQUIRED | MP_ARG_INT, { .u_int = 0 } },
107+
{ MP_QSTR_ksize, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } },
108+
};
109+
110+
// Parse the arguments
111+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
112+
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
113+
114+
// Convert arguments to required types
115+
int shape = args[ARG_shape].u_int;
116+
Size ksize = mp_obj_to_size(args[ARG_ksize].u_obj);
117+
118+
// Instantiate result
119+
Mat kernel;
120+
121+
// Call the corresponding OpenCV function
122+
try {
123+
kernel = getStructuringElement(shape, ksize);
124+
} catch(Exception& e) {
125+
mp_raise_msg(&mp_type_Exception, MP_ERROR_TEXT(e.what()));
126+
}
127+
128+
// Return the result
129+
return mat_to_mp_obj(kernel);
130+
}
131+
132+
mp_obj_t cv2_imgproc_morphologyEx(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
133+
// Define the arguments
134+
enum { ARG_src, ARG_op, ARG_kernel, ARG_dst };
135+
static const mp_arg_t allowed_args[] = {
136+
{ MP_QSTR_src, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } },
137+
{ MP_QSTR_op, MP_ARG_REQUIRED | MP_ARG_INT, { .u_int = 0 } },
138+
{ MP_QSTR_kernel, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } },
139+
{ MP_QSTR_dst, MP_ARG_OBJ, { .u_obj = mp_const_none } },
140+
};
141+
142+
// Parse the arguments
143+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
144+
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
145+
146+
// Convert arguments to required types
147+
Mat src = mp_obj_to_mat(args[ARG_src].u_obj);
148+
int op = args[ARG_op].u_int;
149+
Mat kernel = mp_obj_to_mat(args[ARG_kernel].u_obj);
150+
Mat dst = mp_obj_to_mat(args[ARG_dst].u_obj);
151+
152+
// Call the corresponding OpenCV function
153+
try {
154+
morphologyEx(src, dst, op, kernel);
155+
} catch(Exception& e) {
156+
mp_raise_msg(&mp_type_Exception, MP_ERROR_TEXT(e.what()));
157+
}
158+
159+
// Return the result
160+
return mat_to_mp_obj(dst);
161+
}

src/imgproc.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,7 @@
22
#include "py/runtime.h"
33

44
extern mp_obj_t cv2_imgproc_cvtColor(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
5+
extern mp_obj_t cv2_imgproc_dilate(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
6+
extern mp_obj_t cv2_imgproc_erode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
7+
extern mp_obj_t cv2_imgproc_getStructuringElement(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
8+
extern mp_obj_t cv2_imgproc_morphologyEx(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);

src/opencv_upy.c

Lines changed: 50 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,25 @@
11
#include "core.h"
22
#include "imgproc.h"
33

4-
// Define a Python reference to the function we'll make available.
5-
// See example.cpp for the definition.
4+
////////////////////////////////////////////////////////////////////////////////
5+
// Python references to OpenCV functions
6+
////////////////////////////////////////////////////////////////////////////////
7+
8+
// OpenCV core module
69
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_core_inRange_obj, 3, cv2_core_inRange);
710
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_core_max_obj, 2, cv2_core_max);
811
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_core_min_obj, 2, cv2_core_min);
12+
13+
// OpenCV imgproc module
914
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_cvtColor_obj, 2, cv2_imgproc_cvtColor);
15+
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_dilate_obj, 2, cv2_imgproc_dilate);
16+
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_erode_obj, 2, cv2_imgproc_erode);
17+
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_getStructuringElement_obj, 2, cv2_imgproc_getStructuringElement);
18+
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_morphologyEx_obj, 3, cv2_imgproc_morphologyEx);
1019

11-
// Define all attributes of the module.
12-
// Table entries are key/value pairs of the attribute name (a string)
13-
// and the MicroPython object reference.
14-
// All identifiers and strings are written as MP_QSTR_xxx and will be
15-
// optimized to word-sized integers by the build system (interned strings).
20+
////////////////////////////////////////////////////////////////////////////////
21+
// Module attributes
22+
////////////////////////////////////////////////////////////////////////////////
1623
static const mp_rom_map_elem_t cv2_module_globals_table[] = {
1724
////////////////////////////////////////////////////////////////////////////
1825
// Module name
@@ -24,22 +31,38 @@ static const mp_rom_map_elem_t cv2_module_globals_table[] = {
2431
// Constants
2532
////////////////////////////////////////////////////////////////////////////
2633

27-
// Color conversion codes. These are defined in <opencv2/imgproc.hpp>,
28-
// however we can't include that header here because it's C++ and this is C,
29-
// so we have to redefine them here. Only a subset of the most common
30-
// conversions are included here.
31-
{ MP_ROM_QSTR(MP_QSTR_COLOR_COLOR_BGR2BGRA), MP_ROM_INT(0) },
32-
{ MP_ROM_QSTR(MP_QSTR_COLOR_COLOR_RGB2RGBA), MP_ROM_INT(0) },
33-
{ MP_ROM_QSTR(MP_QSTR_COLOR_COLOR_BGRA2BGR), MP_ROM_INT(1) },
34-
{ MP_ROM_QSTR(MP_QSTR_COLOR_COLOR_RGBA2RGB), MP_ROM_INT(1) },
35-
{ MP_ROM_QSTR(MP_QSTR_COLOR_COLOR_BGR2RGBA), MP_ROM_INT(2) },
36-
{ MP_ROM_QSTR(MP_QSTR_COLOR_COLOR_RGB2BGRA), MP_ROM_INT(2) },
37-
{ MP_ROM_QSTR(MP_QSTR_COLOR_COLOR_RGBA2BGR), MP_ROM_INT(3) },
38-
{ MP_ROM_QSTR(MP_QSTR_COLOR_COLOR_BGRA2RGB), MP_ROM_INT(3) },
39-
{ MP_ROM_QSTR(MP_QSTR_COLOR_COLOR_BGR2RGB), MP_ROM_INT(4) },
40-
{ MP_ROM_QSTR(MP_QSTR_COLOR_COLOR_RGB2BGR), MP_ROM_INT(4) },
41-
{ MP_ROM_QSTR(MP_QSTR_COLOR_COLOR_BGRA2RGBA), MP_ROM_INT(5) },
42-
{ MP_ROM_QSTR(MP_QSTR_COLOR_COLOR_RGBA2BGRA), MP_ROM_INT(5) },
34+
// These constants are defined by in OpenCV's header files, however we can't
35+
// include them here because it's C++ and this is C, so we have to redefine
36+
// them here. Only a subset of the most common conversions are included.
37+
38+
// Morphology operation types, from opencv2/imgproc.hpp
39+
{ MP_ROM_QSTR(MP_QSTR_MORPH_ERODE), MP_ROM_INT(0) },
40+
{ MP_ROM_QSTR(MP_QSTR_MORPH_DILATE), MP_ROM_INT(1) },
41+
{ MP_ROM_QSTR(MP_QSTR_MORPH_OPEN), MP_ROM_INT(2) },
42+
{ MP_ROM_QSTR(MP_QSTR_MORPH_CLOSE), MP_ROM_INT(3) },
43+
{ MP_ROM_QSTR(MP_QSTR_MORPH_GRADIENT), MP_ROM_INT(4) },
44+
{ MP_ROM_QSTR(MP_QSTR_MORPH_TOPHAT), MP_ROM_INT(5) },
45+
{ MP_ROM_QSTR(MP_QSTR_MORPH_BLACKHAT), MP_ROM_INT(6) },
46+
{ MP_ROM_QSTR(MP_QSTR_MORPH_HITMISS), MP_ROM_INT(7) },
47+
48+
// Morphology shapes, from opencv2/imgproc.hpp
49+
{ MP_ROM_QSTR(MP_QSTR_MORPH_RECT), MP_ROM_INT(0) },
50+
{ MP_ROM_QSTR(MP_QSTR_MORPH_CROSS), MP_ROM_INT(1) },
51+
{ MP_ROM_QSTR(MP_QSTR_MORPH_ELLIPSE), MP_ROM_INT(2) },
52+
53+
// Color conversion codes, from opencv2/imgproc.hpp
54+
{ MP_ROM_QSTR(MP_QSTR_COLOR_BGR2BGRA), MP_ROM_INT(0) },
55+
{ MP_ROM_QSTR(MP_QSTR_COLOR_RGB2RGBA), MP_ROM_INT(0) },
56+
{ MP_ROM_QSTR(MP_QSTR_COLOR_BGRA2BGR), MP_ROM_INT(1) },
57+
{ MP_ROM_QSTR(MP_QSTR_COLOR_RGBA2RGB), MP_ROM_INT(1) },
58+
{ MP_ROM_QSTR(MP_QSTR_COLOR_BGR2RGBA), MP_ROM_INT(2) },
59+
{ MP_ROM_QSTR(MP_QSTR_COLOR_RGB2BGRA), MP_ROM_INT(2) },
60+
{ MP_ROM_QSTR(MP_QSTR_COLOR_RGBA2BGR), MP_ROM_INT(3) },
61+
{ MP_ROM_QSTR(MP_QSTR_COLOR_BGRA2RGB), MP_ROM_INT(3) },
62+
{ MP_ROM_QSTR(MP_QSTR_COLOR_BGR2RGB), MP_ROM_INT(4) },
63+
{ MP_ROM_QSTR(MP_QSTR_COLOR_RGB2BGR), MP_ROM_INT(4) },
64+
{ MP_ROM_QSTR(MP_QSTR_COLOR_BGRA2RGBA), MP_ROM_INT(5) },
65+
{ MP_ROM_QSTR(MP_QSTR_COLOR_RGBA2BGRA), MP_ROM_INT(5) },
4366
{ MP_ROM_QSTR(MP_QSTR_COLOR_BGR2GRAY), MP_ROM_INT(6) },
4467
{ MP_ROM_QSTR(MP_QSTR_COLOR_RGB2GRAY), MP_ROM_INT(7) },
4568
{ MP_ROM_QSTR(MP_QSTR_COLOR_GRAY2BGR), MP_ROM_INT(8) },
@@ -92,6 +115,10 @@ static const mp_rom_map_elem_t cv2_module_globals_table[] = {
92115
////////////////////////////////////////////////////////////////////////////
93116

94117
{ MP_ROM_QSTR(MP_QSTR_cvtColor), MP_ROM_PTR(&cv2_imgproc_cvtColor_obj) },
118+
{ MP_ROM_QSTR(MP_QSTR_dilate), MP_ROM_PTR(&cv2_imgproc_dilate_obj) },
119+
{ MP_ROM_QSTR(MP_QSTR_erode), MP_ROM_PTR(&cv2_imgproc_erode_obj) },
120+
{ MP_ROM_QSTR(MP_QSTR_getStructuringElement), MP_ROM_PTR(&cv2_imgproc_getStructuringElement_obj) },
121+
{ MP_ROM_QSTR(MP_QSTR_morphologyEx), MP_ROM_PTR(&cv2_imgproc_morphologyEx_obj) },
95122
};
96123
static MP_DEFINE_CONST_DICT(cv2_module_globals, cv2_module_globals_table);
97124

0 commit comments

Comments
 (0)