为什么OpenCV的MSER的Python实现和Java实现会产生不同的输出?

时间:2015-05-27 17:17:56

标签: java python opencv

我一直在尝试使用OpenCV的MSER算法的Python实现(opencv 2.4.11)和Java实现(opencv 2.4.10)。有趣的是,我注意到MSER的检测在Python和Java中返回不同类型的输出。在Python中,detect返回一个点列表列表,其中每个点列表代表一个检测到的blob。在Java中,返回.state('review', { url: '/details/review', templateUrl: 'views/reviewsproduct.html', parent: 'detailedProduct', controller: 'ReviewController' }) ,其中每行是单个点,其相关直径表示检测到的blob。我想重现Java中的Python行为,其中blob由一组点定义,而不是一个点。任何人都知道发生了什么?

Python:

Mat

Python输出:

frame = cv2.imread('test.jpg')
mser = cv2.MSER(**dict((k, kw[k]) for k in MSER_KEYS))  
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)  
regions = mser.detect(gray, None)
print("REGIONS ARE: " + str(regions))

where the dict given to cv2.MSER is
{'_delta':7, '_min_area': 2000, '_max_area': 20000, '_max_variation': .25, '_min_diversity': .2, '_max_evolution': 200, '_area_threshold': 1.01, '_min_margin': .003, '_edge_blur_size': 5}

爪哇:

REGIONS ARE: [array([[197,  58],
   [197,  59],
   [197,  60],
   ..., 
   [143,  75],
   [167,  86],
   [172,  98]], dtype=int32), array([[114,   2],
   [114,   1],
   [114,   0],
   ..., 
   [144,  56],
   [ 84,  55],
   [ 83,  55]], dtype=int32)]

Java输出:

Mat mat = new Mat(bitmap.getWidth(), bitmap.getHeight(), CvType.CV_16S, new Scalar(4));
Mat gray = new Mat(bitmap.getWidth(), bitmap.getHeight(), CvType.CV_16S, new Scalar(4));
Imgproc.cvtColor(mat, gray, Imgproc.COLOR_RGB2GRAY, 4);

FeatureDetector fd = FeatureDetector.create(FeatureDetector.MSER);
MatOfKeyPoint regions = new MatOfKeyPoint();
fd.detect(gray, regions);
System.out.println("REGIONS ARE: " + regions);

修改

answers.opencv.org论坛上的一个mod提供了更多信息(http://answers.opencv.org/question/63733/why-does-python-implementation-and-java-implementation-of-mser-create-different-output/):

  

不幸的是,它看起来像java版本仅限于features2d.FeatureDetector接口,它允许您只访问KeyPoints(而不是实际的区域)

     

berak(6月10日&15; 15)

     

@berak:所以如果我从文档中正确理解,java版本和python / C ++版本都有features2d.FeatureDetector接口,但python / C ++版本有额外的MSER类来查找区域,而不仅仅是键点?   在那种情况下,人们做什么?是否可以将C ++ MSER类添加到OpenCV管理器,在这里编辑类似javaFeatureDetector的东西,并为它创建一个java包装器?谢谢你的任何建议。

     

sloreti(6月11日和15日)

     

是的,您可以使用c ++或python获取矩形,但不能使用java。这是设计中的一个缺陷。 javaFeatureDetector仍然在使用,但是为了得到矩形,我猜你必须编写自己的jni接口。 (并将你自己的.so与你的apk分发)

     

berak(6月12日和15日)

1 个答案:

答案 0 :(得分:1)

您正在使用两个不同的MSER实现接口。

Python cv2.MSER为您提供了一个包裹的cv::MSER,它将operator()公开给Python detect

//! the operator that extracts the MSERs from the image or the specific part of it
CV_WRAP_AS(detect) void operator()( const Mat& image, CV_OUT vector<vector<Point> >& msers,
                                    const Mat& mask=Mat() ) const;

这为您提供了一个很好的轮廓界面列表。

相比之下,Java使用javaFeatureDetector包装器调用由FeatureDetector::detect支持的MSER::detectImpl并使用标准的FeatureDetector接口:KeyPoints列表。

如果要访问Java中的operator()(在OpenCV 2.4中),则必须将其包装在JNI中。