/// <summary> /// /// </summary> /// <param name="input_img">original image</param> /// <param name="type"></param> /// <returns></returns> public static List <Image <Gray, byte> > find_all_possible_plates(Image <Gray, byte> input_img, Plate_feature.type_of_plate type) { Image <Gray, byte> blur = Image_utils.gaussian_blur(input_img); Image <Gray, byte> sobelx = Image_utils.sobel_X(blur).Convert <Gray, byte>(); Image <Gray, byte> adaptive = Image_utils.adaptive_threshold(sobelx); Image <Gray, byte> morp = Image_utils.morphology_ex(adaptive, Plate_feature.type_of_plate.RECT_PLATE); VectorOfVectorOfPoint contours = Image_utils.find_all_contours(morp); List <Image <Gray, byte> > approved_plates = new List <Image <Gray, byte> >(); for (int i = 0; i < contours.Size; i++) { double area = CvInvoke.ContourArea(contours[i]); Rectangle r = CvInvoke.BoundingRectangle(contours[i]); RotatedRect rr = CvInvoke.MinAreaRect(contours[i]); Image <Gray, byte> suspected_plate = input_img.Copy(r); Tuple <Image <Gray, byte>, Rectangle> after_clean_plate_tuple; Tuple <bool, List <Image <Gray, byte> > > after_check_plate_has_characters_tuple; if (!Plate_feature.ratio_check(type, area, r.Width, r.Height)) { continue; } else { if (!Plate_feature.validate_rotation_and_ratio(type, rr)) { continue; } else { after_clean_plate_tuple = clean_plate(suspected_plate, type); after_check_plate_has_characters_tuple = check_plate_has_character(after_clean_plate_tuple.Item1, type); if (!after_check_plate_has_characters_tuple.Item1) { continue; } else { approved_plates = after_check_plate_has_characters_tuple.Item2; } } } } return(approved_plates); }