Skip to content

Commit 83376cf

Browse files
committed
Add findContours(), drawContours(), and moments()
Have to force floats because of v923z/micropython-ulab#719
1 parent be7d810 commit 83376cf

File tree

4 files changed

+223
-0
lines changed

4 files changed

+223
-0
lines changed

src/convert.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,3 +310,49 @@ Scalar mp_obj_to_scalar(mp_obj_t obj)
310310

311311
return scalar;
312312
}
313+
314+
std::vector<std::vector<Point>> mp_obj_to_contours(mp_obj_t obj)
315+
{
316+
// Check for None object
317+
if(obj == mp_const_none)
318+
{
319+
// Create an empty contours object
320+
return std::vector<std::vector<Point>>();
321+
}
322+
323+
// Create a vector to hold the contours
324+
std::vector<std::vector<Point>> contours;
325+
326+
// Ideally, we could just use ndarray_from_mp_obj(), but it has a bug with
327+
// 4D arrays, so we need to do this a bit manually.
328+
// https://github.com/v923z/micropython-ulab/issues/727
329+
330+
// Assume the object is iterable. Will raise an exception if not
331+
mp_obj_iter_buf_t iter_buf;
332+
mp_obj_t iterable = mp_getiter(obj, &iter_buf);
333+
mp_obj_t item;
334+
335+
// Iterate through all items in the iterable
336+
while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION)
337+
{
338+
// Create a vector to hold the points of this contour
339+
std::vector<Point> contour;
340+
341+
// Convert the item to a Mat object (should be a 3D ndarray of points)
342+
Mat contour_mat = mp_obj_to_mat(item);
343+
344+
// Iterate through the rows of the Mat object and extract the points
345+
for (int j = 0; j < contour_mat.rows; j++)
346+
{
347+
contour.push_back(Point(
348+
contour_mat.at<float>(j, 0),
349+
contour_mat.at<float>(j, 1)
350+
));
351+
}
352+
353+
// Add the contour to the list of contours
354+
contours.push_back(contour);
355+
}
356+
357+
return contours;
358+
}

src/convert.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,6 @@ Point mp_obj_to_point(mp_obj_t obj);
3030

3131
// Conversion functions between Scalar and mp_obj_t
3232
Scalar mp_obj_to_scalar(mp_obj_t obj);
33+
34+
// Conversion functions between contours (vector of vector of Point) and mp_obj_t
35+
std::vector<std::vector<Point>> mp_obj_to_contours(mp_obj_t obj);

src/imgproc.cpp

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,47 @@ mp_obj_t cv2_imgproc_dilate(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k
423423
return mat_to_mp_obj(dst);
424424
}
425425

426+
mp_obj_t cv2_imgproc_drawContours(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
427+
// Define the arguments
428+
enum { ARG_image, ARG_contours, ARG_contourIdx, ARG_color, ARG_thickness, ARG_lineType, ARG_hierarchy, ARG_maxLevel, ARG_offset };
429+
static const mp_arg_t allowed_args[] = {
430+
{ MP_QSTR_image, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } },
431+
{ MP_QSTR_contours, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } },
432+
{ MP_QSTR_contourIdx, MP_ARG_REQUIRED | MP_ARG_INT, { .u_int = -1 } },
433+
{ MP_QSTR_color, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } },
434+
{ MP_QSTR_thickness, MP_ARG_INT, { .u_int = 1 } },
435+
{ MP_QSTR_lineType, MP_ARG_INT, { .u_int = LINE_8 } },
436+
{ MP_QSTR_hierarchy, MP_ARG_OBJ, { .u_obj = mp_const_none } },
437+
{ MP_QSTR_maxLevel, MP_ARG_INT, { .u_int = INT_MAX } },
438+
{ MP_QSTR_offset, MP_ARG_OBJ, { .u_obj = mp_const_none } },
439+
};
440+
441+
// Parse the arguments
442+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
443+
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
444+
445+
// Convert arguments to required types
446+
Mat image = mp_obj_to_mat(args[ARG_image].u_obj);
447+
std::vector<std::vector<Point>> contours = mp_obj_to_contours(args[ARG_contours].u_obj);
448+
int contourIdx = args[ARG_contourIdx].u_int;
449+
Scalar color = mp_obj_to_scalar(args[ARG_color].u_obj);
450+
int thickness = args[ARG_thickness].u_int;
451+
int lineType = args[ARG_lineType].u_int;
452+
Mat hierarchy = args[ARG_hierarchy].u_obj != mp_const_none ? mp_obj_to_mat(args[ARG_hierarchy].u_obj) : Mat();
453+
int maxLevel = args[ARG_maxLevel].u_int;
454+
Point offset = args[ARG_offset].u_obj != mp_const_none ? mp_obj_to_point(args[ARG_offset].u_obj) : Point();
455+
456+
// Call the corresponding OpenCV function
457+
try {
458+
drawContours(image, contours, contourIdx, color, thickness, lineType, hierarchy, maxLevel, offset);
459+
} catch(Exception& e) {
460+
mp_raise_msg(&mp_type_Exception, MP_ERROR_TEXT(e.what()));
461+
}
462+
463+
// Return the result
464+
return mat_to_mp_obj(image);
465+
}
466+
426467
mp_obj_t cv2_imgproc_drawMarker(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
427468
// Define the arguments
428469
enum { ARG_img, ARG_position, ARG_color, ARG_markerType, ARG_markerSize, ARG_thickness, ARG_line_type };
@@ -671,6 +712,60 @@ mp_obj_t cv2_imgproc_filter2D(size_t n_args, const mp_obj_t *pos_args, mp_map_t
671712
return mat_to_mp_obj(dst);
672713
}
673714

715+
mp_obj_t cv2_imgproc_findContours(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
716+
// Define the arguments
717+
enum { ARG_image, ARG_mode, ARG_method, ARG_contours, ARG_hierarchy, ARG_offset };
718+
static const mp_arg_t allowed_args[] = {
719+
{ MP_QSTR_image, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } },
720+
{ MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, { .u_int = 0 } },
721+
{ MP_QSTR_method, MP_ARG_REQUIRED | MP_ARG_INT, { .u_int = 0 } },
722+
{ MP_QSTR_contours, MP_ARG_OBJ, { .u_obj = mp_const_none } },
723+
{ MP_QSTR_hierarchy, MP_ARG_OBJ, { .u_obj = mp_const_none } },
724+
{ MP_QSTR_offset, MP_ARG_OBJ, { .u_obj = mp_const_none } },
725+
};
726+
727+
// Parse the arguments
728+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
729+
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
730+
731+
// Convert arguments to required types
732+
Mat image = mp_obj_to_mat(args[ARG_image].u_obj);
733+
int mode = args[ARG_mode].u_int;
734+
int method = args[ARG_method].u_int;
735+
std::vector<std::vector<Point>> contours; // TODO: Allow user input
736+
std::vector<Vec4i> hierarchy; // TODO: Allow user input
737+
Point offset = args[ARG_offset].u_obj == mp_const_none ? Point() : mp_obj_to_point(args[ARG_offset].u_obj);
738+
739+
// Call the corresponding OpenCV function
740+
try {
741+
findContours(image, contours, hierarchy, mode, method, offset);
742+
} catch(Exception& e) {
743+
mp_raise_msg(&mp_type_Exception, MP_ERROR_TEXT(e.what()));
744+
}
745+
746+
// Convert contours to a tuple of ndarray objects
747+
mp_obj_t contours_obj = mp_obj_new_tuple(contours.size(), NULL);
748+
mp_obj_tuple_t *contours_tuple = (mp_obj_tuple_t*) MP_OBJ_TO_PTR(contours_obj);
749+
750+
for(size_t i = 0; i < contours.size(); i++) {
751+
Mat mat_contour(contours[i]);
752+
Mat mat_f32;
753+
mat_contour.convertTo(mat_f32, CV_32F);
754+
contours_tuple->items[i] = mat_to_mp_obj(mat_f32);
755+
}
756+
757+
// Convert hierarchy to a Mat object
758+
Mat mat_hierarchy(hierarchy);
759+
760+
// Return the result
761+
mp_obj_t result_tuple[2];
762+
result_tuple[0] = contours_tuple;
763+
Mat mat_16s;
764+
mat_hierarchy.convertTo(mat_16s, CV_16S);
765+
result_tuple[1] = mat_to_mp_obj(mat_16s);
766+
return mp_obj_new_tuple(2, result_tuple);
767+
}
768+
674769
mp_obj_t cv2_imgproc_GaussianBlur(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
675770
// Define the arguments
676771
enum { ARG_src, ARG_ksize, ARG_sigmaX, ARG_dst, ARG_sigmaY, ARG_borderType, ARG_hint };
@@ -1214,6 +1309,61 @@ mp_obj_t cv2_imgproc_morphologyEx(size_t n_args, const mp_obj_t *pos_args, mp_ma
12141309
return mat_to_mp_obj(dst);
12151310
}
12161311

1312+
mp_obj_t cv2_imgproc_moments(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
1313+
// Define the arguments
1314+
enum { ARG_src, ARG_binary };
1315+
static const mp_arg_t allowed_args[] = {
1316+
{ MP_QSTR_src, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } },
1317+
{ MP_QSTR_binary, MP_ARG_BOOL, { .u_bool = false } },
1318+
};
1319+
1320+
// Parse the arguments
1321+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
1322+
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
1323+
1324+
// Convert arguments to required types
1325+
Mat src = mp_obj_to_mat(args[ARG_src].u_obj);
1326+
bool binary = args[ARG_binary].u_bool;
1327+
Moments moments;
1328+
1329+
// Call the corresponding OpenCV function
1330+
try {
1331+
moments = cv::moments(src, binary);
1332+
} catch(Exception& e) {
1333+
mp_raise_msg(&mp_type_Exception, MP_ERROR_TEXT(e.what()));
1334+
}
1335+
1336+
// Create a dictionary to hold the moments
1337+
mp_obj_t moments_dict = mp_obj_new_dict(0);
1338+
mp_obj_dict_store(moments_dict, MP_OBJ_NEW_QSTR(MP_QSTR_m00), mp_obj_new_float(moments.m00));
1339+
mp_obj_dict_store(moments_dict, MP_OBJ_NEW_QSTR(MP_QSTR_m10), mp_obj_new_float(moments.m10));
1340+
mp_obj_dict_store(moments_dict, MP_OBJ_NEW_QSTR(MP_QSTR_m01), mp_obj_new_float(moments.m01));
1341+
mp_obj_dict_store(moments_dict, MP_OBJ_NEW_QSTR(MP_QSTR_m20), mp_obj_new_float(moments.m20));
1342+
mp_obj_dict_store(moments_dict, MP_OBJ_NEW_QSTR(MP_QSTR_m11), mp_obj_new_float(moments.m11));
1343+
mp_obj_dict_store(moments_dict, MP_OBJ_NEW_QSTR(MP_QSTR_m02), mp_obj_new_float(moments.m02));
1344+
mp_obj_dict_store(moments_dict, MP_OBJ_NEW_QSTR(MP_QSTR_m30), mp_obj_new_float(moments.m30));
1345+
mp_obj_dict_store(moments_dict, MP_OBJ_NEW_QSTR(MP_QSTR_m21), mp_obj_new_float(moments.m21));
1346+
mp_obj_dict_store(moments_dict, MP_OBJ_NEW_QSTR(MP_QSTR_m12), mp_obj_new_float(moments.m12));
1347+
mp_obj_dict_store(moments_dict, MP_OBJ_NEW_QSTR(MP_QSTR_m03), mp_obj_new_float(moments.m03));
1348+
mp_obj_dict_store(moments_dict, MP_OBJ_NEW_QSTR(MP_QSTR_mu20), mp_obj_new_float(moments.mu20));
1349+
mp_obj_dict_store(moments_dict, MP_OBJ_NEW_QSTR(MP_QSTR_mu11), mp_obj_new_float(moments.mu11));
1350+
mp_obj_dict_store(moments_dict, MP_OBJ_NEW_QSTR(MP_QSTR_mu02), mp_obj_new_float(moments.mu02));
1351+
mp_obj_dict_store(moments_dict, MP_OBJ_NEW_QSTR(MP_QSTR_mu30), mp_obj_new_float(moments.mu30));
1352+
mp_obj_dict_store(moments_dict, MP_OBJ_NEW_QSTR(MP_QSTR_mu21), mp_obj_new_float(moments.mu21));
1353+
mp_obj_dict_store(moments_dict, MP_OBJ_NEW_QSTR(MP_QSTR_mu12), mp_obj_new_float(moments.mu12));
1354+
mp_obj_dict_store(moments_dict, MP_OBJ_NEW_QSTR(MP_QSTR_mu03), mp_obj_new_float(moments.mu03));
1355+
mp_obj_dict_store(moments_dict, MP_OBJ_NEW_QSTR(MP_QSTR_nu20), mp_obj_new_float(moments.nu20));
1356+
mp_obj_dict_store(moments_dict, MP_OBJ_NEW_QSTR(MP_QSTR_nu11), mp_obj_new_float(moments.nu11));
1357+
mp_obj_dict_store(moments_dict, MP_OBJ_NEW_QSTR(MP_QSTR_nu02), mp_obj_new_float(moments.nu02));
1358+
mp_obj_dict_store(moments_dict, MP_OBJ_NEW_QSTR(MP_QSTR_nu30), mp_obj_new_float(moments.nu30));
1359+
mp_obj_dict_store(moments_dict, MP_OBJ_NEW_QSTR(MP_QSTR_nu21), mp_obj_new_float(moments.nu21));
1360+
mp_obj_dict_store(moments_dict, MP_OBJ_NEW_QSTR(MP_QSTR_nu12), mp_obj_new_float(moments.nu12));
1361+
mp_obj_dict_store(moments_dict, MP_OBJ_NEW_QSTR(MP_QSTR_nu03), mp_obj_new_float(moments.nu03));
1362+
1363+
// Return the moments dictionary
1364+
return moments_dict;
1365+
}
1366+
12171367
mp_obj_t cv2_imgproc_putText(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
12181368
// Define the arguments
12191369
enum { ARG_img, ARG_text, ARG_org, ARG_fontFace, ARG_fontScale, ARG_color, ARG_thickness, ARG_lineType, ARG_bottomLeftOrigin };

src/imgproc.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@ extern mp_obj_t cv2_imgproc_connectedComponents(size_t n_args, const mp_obj_t *p
1313
extern mp_obj_t cv2_imgproc_circle(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
1414
extern mp_obj_t cv2_imgproc_cvtColor(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
1515
extern mp_obj_t cv2_imgproc_dilate(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
16+
extern mp_obj_t cv2_imgproc_drawContours(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
1617
extern mp_obj_t cv2_imgproc_drawMarker(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
1718
extern mp_obj_t cv2_imgproc_ellipse(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
1819
extern mp_obj_t cv2_imgproc_erode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
1920
extern mp_obj_t cv2_imgproc_fillConvexPoly(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
2021
extern mp_obj_t cv2_imgproc_fillPoly(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
2122
extern mp_obj_t cv2_imgproc_filter2D(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
23+
extern mp_obj_t cv2_imgproc_findContours(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
2224
extern mp_obj_t cv2_imgproc_GaussianBlur(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
2325
extern mp_obj_t cv2_imgproc_getStructuringElement(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
2426
extern mp_obj_t cv2_imgproc_HoughCircles(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
@@ -31,6 +33,7 @@ extern mp_obj_t cv2_imgproc_line(size_t n_args, const mp_obj_t *pos_args, mp_map
3133
extern mp_obj_t cv2_imgproc_matchTemplate(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
3234
extern mp_obj_t cv2_imgproc_medianBlur(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
3335
extern mp_obj_t cv2_imgproc_morphologyEx(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
36+
extern mp_obj_t cv2_imgproc_moments(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
3437
extern mp_obj_t cv2_imgproc_putText(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
3538
extern mp_obj_t cv2_imgproc_rectangle(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
3639
extern mp_obj_t cv2_imgproc_Scharr(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
@@ -50,12 +53,14 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_connectedComponents_obj, 1, cv2_im
5053
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_circle_obj, 4, cv2_imgproc_circle);
5154
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_cvtColor_obj, 2, cv2_imgproc_cvtColor);
5255
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_dilate_obj, 2, cv2_imgproc_dilate);
56+
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_drawContours_obj, 3, cv2_imgproc_drawContours);
5357
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_drawMarker_obj, 3, cv2_imgproc_drawMarker);
5458
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_ellipse_obj, 7, cv2_imgproc_ellipse);
5559
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_erode_obj, 2, cv2_imgproc_erode);
5660
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_fillConvexPoly_obj, 3, cv2_imgproc_fillConvexPoly);
5761
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_fillPoly_obj, 3, cv2_imgproc_fillPoly);
5862
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_filter2D_obj, 3, cv2_imgproc_filter2D);
63+
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_findContours_obj, 3, cv2_imgproc_findContours);
5964
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_GaussianBlur_obj, 3, cv2_imgproc_GaussianBlur);
6065
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_getStructuringElement_obj, 2, cv2_imgproc_getStructuringElement);
6166
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_HoughCircles_obj, 4, cv2_imgproc_HoughCircles);
@@ -68,6 +73,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_line_obj, 4, cv2_imgproc_line);
6873
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_matchTemplate_obj, 3, cv2_imgproc_matchTemplate);
6974
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_medianBlur_obj, 2, cv2_imgproc_medianBlur);
7075
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_morphologyEx_obj, 3, cv2_imgproc_morphologyEx);
76+
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_moments_obj, 1, cv2_imgproc_moments);
7177
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_putText_obj, 6, cv2_imgproc_putText);
7278
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_rectangle_obj, 4, cv2_imgproc_rectangle);
7379
static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_Scharr_obj, 4, cv2_imgproc_Scharr);
@@ -89,12 +95,14 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_threshold_obj, 4, cv2_imgproc_thre
8995
{ MP_ROM_QSTR(MP_QSTR_circle), MP_ROM_PTR(&cv2_imgproc_circle_obj) }, \
9096
{ MP_ROM_QSTR(MP_QSTR_cvtColor), MP_ROM_PTR(&cv2_imgproc_cvtColor_obj) }, \
9197
{ MP_ROM_QSTR(MP_QSTR_dilate), MP_ROM_PTR(&cv2_imgproc_dilate_obj) }, \
98+
{ MP_ROM_QSTR(MP_QSTR_drawContours), MP_ROM_PTR(&cv2_imgproc_drawContours_obj) }, \
9299
{ MP_ROM_QSTR(MP_QSTR_drawMarker), MP_ROM_PTR(&cv2_imgproc_drawMarker_obj) }, \
93100
{ MP_ROM_QSTR(MP_QSTR_ellipse), MP_ROM_PTR(&cv2_imgproc_ellipse_obj) }, \
94101
{ MP_ROM_QSTR(MP_QSTR_erode), MP_ROM_PTR(&cv2_imgproc_erode_obj) }, \
95102
{ MP_ROM_QSTR(MP_QSTR_fillConvexPoly), MP_ROM_PTR(&cv2_imgproc_fillConvexPoly_obj) }, \
96103
{ MP_ROM_QSTR(MP_QSTR_fillPoly), MP_ROM_PTR(&cv2_imgproc_fillPoly_obj) }, \
97104
{ MP_ROM_QSTR(MP_QSTR_filter2D), MP_ROM_PTR(&cv2_imgproc_filter2D_obj) }, \
105+
{ MP_ROM_QSTR(MP_QSTR_findContours), MP_ROM_PTR(&cv2_imgproc_findContours_obj) }, \
98106
{ MP_ROM_QSTR(MP_QSTR_GaussianBlur), MP_ROM_PTR(&cv2_imgproc_GaussianBlur_obj) }, \
99107
{ MP_ROM_QSTR(MP_QSTR_getStructuringElement), MP_ROM_PTR(&cv2_imgproc_getStructuringElement_obj) }, \
100108
{ MP_ROM_QSTR(MP_QSTR_HoughCircles), MP_ROM_PTR(&cv2_imgproc_HoughCircles_obj) }, \
@@ -107,6 +115,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_threshold_obj, 4, cv2_imgproc_thre
107115
{ MP_ROM_QSTR(MP_QSTR_matchTemplate), MP_ROM_PTR(&cv2_imgproc_matchTemplate_obj) }, \
108116
{ MP_ROM_QSTR(MP_QSTR_medianBlur), MP_ROM_PTR(&cv2_imgproc_medianBlur_obj) }, \
109117
{ MP_ROM_QSTR(MP_QSTR_morphologyEx), MP_ROM_PTR(&cv2_imgproc_morphologyEx_obj) }, \
118+
{ MP_ROM_QSTR(MP_QSTR_moments), MP_ROM_PTR(&cv2_imgproc_moments_obj) }, \
110119
{ MP_ROM_QSTR(MP_QSTR_putText), MP_ROM_PTR(&cv2_imgproc_putText_obj) }, \
111120
{ MP_ROM_QSTR(MP_QSTR_rectangle), MP_ROM_PTR(&cv2_imgproc_rectangle_obj) }, \
112121
{ MP_ROM_QSTR(MP_QSTR_Scharr), MP_ROM_PTR(&cv2_imgproc_Scharr_obj) }, \
@@ -143,6 +152,21 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(cv2_imgproc_threshold_obj, 4, cv2_imgproc_thre
143152
{ MP_ROM_QSTR(MP_QSTR_ADAPTIVE_THRESH_MEAN_C), MP_ROM_INT(0) }, \
144153
{ MP_ROM_QSTR(MP_QSTR_ADAPTIVE_THRESH_GAUSSIAN_C), MP_ROM_INT(1) }, \
145154
\
155+
/* Retrieval modes, from opencv2/imgproc.hpp */ \
156+
{ MP_ROM_QSTR(MP_QSTR_RETR_EXTERNAL), MP_ROM_INT(0) }, \
157+
{ MP_ROM_QSTR(MP_QSTR_RETR_LIST), MP_ROM_INT(1) }, \
158+
{ MP_ROM_QSTR(MP_QSTR_RETR_CCOMP), MP_ROM_INT(2) }, \
159+
{ MP_ROM_QSTR(MP_QSTR_RETR_TREE), MP_ROM_INT(3) }, \
160+
{ MP_ROM_QSTR(MP_QSTR_RETR_FLOODFILL), MP_ROM_INT(4) }, \
161+
\
162+
/* Contour approximation methods, from opencv2/imgproc.hpp */ \
163+
{ MP_ROM_QSTR(MP_QSTR_CHAIN_CODE), MP_ROM_INT(0) }, \
164+
{ MP_ROM_QSTR(MP_QSTR_CHAIN_APPROX_NONE), MP_ROM_INT(1) }, \
165+
{ MP_ROM_QSTR(MP_QSTR_CHAIN_APPROX_SIMPLE), MP_ROM_INT(2) }, \
166+
{ MP_ROM_QSTR(MP_QSTR_CHAIN_APPROX_TC89_L1), MP_ROM_INT(3) }, \
167+
{ MP_ROM_QSTR(MP_QSTR_CHAIN_APPROX_TC89_KCOS), MP_ROM_INT(4) }, \
168+
{ MP_ROM_QSTR(MP_QSTR_LINK_RUNS), MP_ROM_INT(5) }, \
169+
\
146170
/* Hough modes, from opencv2/imgproc.hpp */ \
147171
{ MP_ROM_QSTR(MP_QSTR_HOUGH_STANDARD), MP_ROM_INT(0) }, \
148172
{ MP_ROM_QSTR(MP_QSTR_HOUGH_PROBABILISTIC), MP_ROM_INT(1) }, \

0 commit comments

Comments
 (0)