为什么OpenCV的MSER的Python实现和Java实现创build不同的输出?
我一直在尝试使用OpenCV的MSERalgorithm的Python实现(opencv 2.4.11)和Java实现(opencv 2.4.10)。 有趣的是,我注意到MSER的检测返回Python和Java的不同types的输出。 在Python中,detect会返回一列点列表,其中每个点列表代表一个检测到的斑点。 在Java中,返回一个Mat
,每一行都是一个单一的点,其直径代表检测到的一个斑点。 我想重现Java中的Python行为,其中blob由一组点定义,而不是一个点。 任何人都知道发生了什么事?
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}
Python输出:
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);
Java输出:
REGIONS ARE: Mat [ 10*1*CV_32FC(7), isCont=true, isSubmat=false, nativeObj=0x6702c688, dataAddr=0x59add760 ] where each row of the Mat looks like KeyPoint [pt={365.3387451171875, 363.75640869140625}, size=10.680443, angle=-1.0, response=0.0, octave=0, class_id=-1]
编辑:
在answers.opencv.org论坛提供了更多的信息( http://answers.opencv.org/question/63733/why-does-python-implementation-and-java-implementation-of-mser-create-不同的输出/ ):
不幸的是,它看起来像java版本是仅限于features2d.FeatureDetector接口,它只允许您访问KeyPoints(而不是实际的区域)
贝拉克(15年6月10日)
@berak:所以如果我从文档中正确理解,java版本和python / C ++版本都有features2d.FeatureDetector接口,但是python / C ++版本有额外的MSER类来查找区域,而不仅仅是关键点? 在这种情况下,人们做什么? 是否可以将C ++ MSER类添加到OpenCVpipe理器,在此处编辑类似于javaFeatureDetector的东西,并为它创build一个java包装器? 感谢您的任何build议。
sloreti(15年6月11日)
所以是的,你可以得到在c + +或python矩形,但不是从Java。 这是devise中的一个缺陷。 javaFeatureDetector仍然在使用中,但是为了得到矩形,我想你必须编写自己的jni接口。 (并与您的apk一起分发您自己的.so)
berak(15年6月12日)
您正在使用MSER实施的两个不同的接口。
Python cv2.MSER
为您提供了一个包装的cv::MSER
,它将其operator()
作为detect
公开给Python:
//! 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使用调用FeatureDetector::detect
的javaFeatureDetector
包装器,它由MSER::detectImpl
支持,并使用标准的FeatureDetector接口:KeyPoints列表。
如果你想访问Java中的operator()
(在OpenCV 2.4中),你将不得不把它包装在JNI中。