From 6991e2b6e4c453326aa6fc9eb5e4d4cde0ae1395 Mon Sep 17 00:00:00 2001 From: ser1zw Date: Sat, 7 Dec 2013 22:34:08 +0900 Subject: [PATCH] fix uncaught exception in CvMat#match_descriptors on OSX Mavericks --- .../matching_to_many_images.rb | 4 +- ext/opencv/cvmat.cpp | 95 ++++++++++--------- test/test_cvmat_matching.rb | 2 +- 3 files changed, 52 insertions(+), 49 deletions(-) diff --git a/examples/matching_to_many_images/matching_to_many_images.rb b/examples/matching_to_many_images/matching_to_many_images.rb index 0d70b1f..72d0a1c 100644 --- a/examples/matching_to_many_images/matching_to_many_images.rb +++ b/examples/matching_to_many_images/matching_to_many_images.rb @@ -4,9 +4,9 @@ include OpenCV data = File.dirname(__FILE__) -query = IplImage.load File.join(data, 'query.png'), CV_LOAD_IMAGE_GRAYSCALE +query = CvMat.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} +images = image_files.map{|f| CvMat.load f, CV_LOAD_IMAGE_GRAYSCALE} matchs = query.match_descriptors(images) diff --git a/ext/opencv/cvmat.cpp b/ext/opencv/cvmat.cpp index 2f6dccc..6ac93da 100644 --- a/ext/opencv/cvmat.cpp +++ b/ext/opencv/cvmat.cpp @@ -5386,7 +5386,6 @@ rb_match_descriptors(int argc, VALUE *argv, VALUE self) { VALUE images, detector_type, descriptor_type, matcher_type; rb_scan_args(argc, argv, "13", &images, &detector_type, &descriptor_type, &matcher_type); - if (RARRAY_LEN(images) == 0) { return rb_hash_new(); } @@ -5400,54 +5399,58 @@ rb_match_descriptors(int argc, VALUE *argv, VALUE self) matcher_type = rb_str_new2("FlannBased"); } - cv::Mat queryImage = CVMAT(self); - std::vector trainImages; - for(int i=0; i < RARRAY_LEN(images); i++) { - trainImages.push_back(CVMAT_WITH_CHECK(RARRAY_PTR(images)[i])); - } - - cv::Ptr featureDetector = cv::FeatureDetector::create(RSTRING_PTR(detector_type)); - if (featureDetector.empty()) { - rb_raise(rb_eArgError, "Could not create feature detector by given detector type: %s", RSTRING_PTR(detector_type)); - } - cv::Ptr descriptorExtractor = cv::DescriptorExtractor::create(RSTRING_PTR(descriptor_type)); - if (descriptorExtractor.empty()) { - rb_raise(rb_eArgError, "Could not create descriptor extractor by given descriptor type: %s", RSTRING_PTR(descriptor_type)); - } - cv::Ptr descriptorMatcher; - try { - descriptorMatcher = cv::DescriptorMatcher::create(RSTRING_PTR(matcher_type)); - } - catch(cv::Exception& e) { - rb_raise(rb_eArgError, "Could not create descriptor matcher by given matcher type: %s", RSTRING_PTR(matcher_type)); - } - - 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 trainImages; + for(int i = 0, n = RARRAY_LEN(images); i < n; i++) { + trainImages.push_back(CVMAT_WITH_CHECK(RARRAY_PTR(images)[i])); + } + + cv::Ptr featureDetector = cv::FeatureDetector::create(StringValueCStr(detector_type)); + if (featureDetector.empty()) { + rb_raise(rb_eArgError, "Could not create feature detector by given detector type: %s", StringValueCStr(detector_type)); + } + cv::Ptr descriptorExtractor = cv::DescriptorExtractor::create(StringValueCStr(descriptor_type)); + if (descriptorExtractor.empty()) { + rb_raise(rb_eArgError, "Could not create descriptor extractor by given descriptor type: %s", StringValueCStr(descriptor_type)); + } + cv::Ptr descriptorMatcher; + try { + descriptorMatcher = cv::DescriptorMatcher::create(StringValueCStr(matcher_type)); + } + catch(cv::Exception& e) { + rb_raise(rb_eArgError, "Could not create descriptor matcher by given matcher type: %s", StringValueCStr(matcher_type)); + } + + 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); + + for (size_t i = 0, n = matches.size(); i < n; i++) { + VALUE match = INT2FIX(matches[i].imgIdx); + VALUE count = rb_hash_lookup(_matches, match); + if (NIL_P(count)) { + count = INT2FIX(1); + } else { + count = INT2FIX(FIX2INT(count) + 1); + } + rb_hash_aset(_matches, match, count); } - rb_hash_aset(_matches, match, count); } + catch (cv::Exception& e) { + raise_cverror(e); + } + return _matches; } diff --git a/test/test_cvmat_matching.rb b/test/test_cvmat_matching.rb index cd50016..27d8006 100755 --- a/test/test_cvmat_matching.rb +++ b/test/test_cvmat_matching.rb @@ -18,7 +18,7 @@ class TestCvMat_matching < OpenCVTestCase end def read_test_image(*path) - IplImage.load File.join(data_dir, *path), CV_LOAD_IMAGE_GRAYSCALE + CvMat.load File.join(data_dir, *path), CV_LOAD_IMAGE_GRAYSCALE end def test_match_descriptors