diff --git a/examples/matching_to_many_images.rb b/examples/matching_to_many_images.rb new file mode 100644 index 0000000..0fef936 --- /dev/null +++ b/examples/matching_to_many_images.rb @@ -0,0 +1,16 @@ +require 'opencv' +require 'benchmark' +include OpenCV + +data = File.join(File.dirname(__FILE__), 'matching_to_many_images') + +query = IplImage.load File.join(data, 'query.png'), CV_LOAD_IMAGE_GRAYSCALE +image_files = ['1.png', '2.png', '3.png'].map{|f| File.join(data, 'train', f)} +images = image_files.map{|f| IplImage.load f, CV_LOAD_IMAGE_GRAYSCALE} + + +matchs = query.match_descriptors("SURF", "SURF", "FlannBased", images) + +match, count = matchs.max_by {|image, count| count} + +puts "max match: #{image_files[images.index(match)]}" diff --git a/examples/matching_to_many_images/query.png b/examples/matching_to_many_images/query.png new file mode 100755 index 0000000..9aa1199 Binary files /dev/null and b/examples/matching_to_many_images/query.png differ diff --git a/examples/matching_to_many_images/train/1.png b/examples/matching_to_many_images/train/1.png new file mode 100755 index 0000000..c52e19e Binary files /dev/null and b/examples/matching_to_many_images/train/1.png differ diff --git a/examples/matching_to_many_images/train/2.png b/examples/matching_to_many_images/train/2.png new file mode 100755 index 0000000..7b1189c Binary files /dev/null and b/examples/matching_to_many_images/train/2.png differ diff --git a/examples/matching_to_many_images/train/3.png b/examples/matching_to_many_images/train/3.png new file mode 100755 index 0000000..dc2389a Binary files /dev/null and b/examples/matching_to_many_images/train/3.png differ diff --git a/examples/matching_to_many_images/train/trainImages.txt b/examples/matching_to_many_images/train/trainImages.txt new file mode 100755 index 0000000..b376639 --- /dev/null +++ b/examples/matching_to_many_images/train/trainImages.txt @@ -0,0 +1,3 @@ +1.png +2.png +3.png diff --git a/ext/opencv/cvmat.cpp b/ext/opencv/cvmat.cpp index 876ade7..387b193 100644 --- a/ext/opencv/cvmat.cpp +++ b/ext/opencv/cvmat.cpp @@ -366,6 +366,7 @@ void define_ruby_class() rb_define_method(rb_klass, "equalize_hist", RUBY_METHOD_FUNC(rb_equalize_hist), 0); rb_define_method(rb_klass, "match_template", RUBY_METHOD_FUNC(rb_match_template), -1); rb_define_method(rb_klass, "match_shapes", RUBY_METHOD_FUNC(rb_match_shapes), -1); + rb_define_method(rb_klass, "match_descriptors", RUBY_METHOD_FUNC(rb_match_descriptors), -1); rb_define_method(rb_klass, "mean_shift", RUBY_METHOD_FUNC(rb_mean_shift), 2); rb_define_method(rb_klass, "cam_shift", RUBY_METHOD_FUNC(rb_cam_shift), 2); @@ -5096,7 +5097,8 @@ rb_moments(int argc, VALUE *argv, VALUE self) * hough_lines(method, rho, theta, threshold, param1, param2) -> cvseq(include CvLine or CvTwoPoints) * * Finds lines in binary image using a Hough transform. - * * method – + * * method – + * * The Hough transform variant, one of the following: * * - CV_HOUGH_STANDARD - classical or standard Hough transform. * * - CV_HOUGH_PROBABILISTIC - probabilistic Hough transform (more efficient in case if picture contains a few long linear segments). @@ -5104,12 +5106,14 @@ rb_moments(int argc, VALUE *argv, VALUE self) * * rho - Distance resolution in pixel-related units. * * theta - Angle resolution measured in radians. * * threshold - Threshold parameter. A line is returned by the function if the corresponding accumulator value is greater than threshold. - * * param1 – + * * param1 – + * * The first method-dependent parameter: * * For the classical Hough transform it is not used (0). * * For the probabilistic Hough transform it is the minimum line length. * * For the multi-scale Hough transform it is the divisor for the distance resolution . (The coarse distance resolution will be rho and the accurate resolution will be (rho / param1)). - * * param2 – + * * param2 – + * * The second method-dependent parameter: * * For the classical Hough transform it is not used (0). * * For the probabilistic Hough transform it is the maximum gap between line segments lying on the same line to treat them as a single line segment (i.e. to join them). @@ -5325,6 +5329,66 @@ rb_match_shapes(int argc, VALUE *argv, VALUE self) return rb_float_new(result); } + +/** + * Port from OpenCV sample: matching_to_many_images.cpp + * call-seq: + * match_descriptors(detector_type, descriptor_type, matcher_type, images) -> Hash + * + * Matching descriptors detected on one image to descriptors detected in image set. + * Returns a Hash contains match count of each image. + * + * detector_type is a string, options: "SURF" + * descriptor_type is a string, options: "SURF" + * matcher_type is a string, options: "FlannBased" + * images is an array of CvMat objects. + */ +VALUE +rb_match_descriptors(int argc, VALUE *argv, VALUE self) +{ + VALUE detectorType, descriptorType, matcherType, images; + rb_scan_args(argc, argv, "40", &detectorType, &descriptorType, &matcherType, &images); + + cv::Mat queryImage = CVMAT(self); + std::vector trainImages; + for(int i=0; i < RARRAY_LEN(images); i++) { + trainImages.push_back(CVMAT(RARRAY_PTR(images)[i])); + } + + // todo: validation + cv::Ptr featureDetector = cv::FeatureDetector::create(RSTRING_PTR(detectorType)); + cv::Ptr descriptorExtractor = cv::DescriptorExtractor::create(RSTRING_PTR(descriptorType)); + cv::Ptr descriptorMatcher = cv::DescriptorMatcher::create(RSTRING_PTR(matcherType)); + + std::vector queryKeypoints; + std::vector > trainKeypoints; + featureDetector->detect(queryImage, queryKeypoints); + featureDetector->detect(trainImages, trainKeypoints); + + cv::Mat queryDescriptors; + std::vector trainDescriptors; + descriptorExtractor->compute(queryImage, queryKeypoints, queryDescriptors); + descriptorExtractor->compute(trainImages, trainKeypoints, trainDescriptors); + + std::vector matches; + descriptorMatcher->add(trainDescriptors); + descriptorMatcher->train(); + descriptorMatcher->match(queryDescriptors, matches); + + VALUE _matches = rb_hash_new(); + for (size_t i=0; i comp diff --git a/ext/opencv/cvmat.h b/ext/opencv/cvmat.h index e16e03e..dca850e 100644 --- a/ext/opencv/cvmat.h +++ b/ext/opencv/cvmat.h @@ -220,6 +220,8 @@ VALUE rb_equalize_hist(VALUE self); /* Matching*/ VALUE rb_match_template(int argc, VALUE *argv, VALUE self); VALUE rb_match_shapes(int argc, VALUE *argv, VALUE self); +VALUE rb_match_descriptors(int argc, VALUE *argv, VALUE self); + /* Object Tracking */ VALUE rb_mean_shift(VALUE self, VALUE window, VALUE criteria); VALUE rb_cam_shift(VALUE self, VALUE window, VALUE criteria);