@@ -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+ 
426467mp_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+ 
674769mp_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+ 
12171367mp_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 };
0 commit comments