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

2022-09-01 07:02:53

我一直在尝试使用OpenCV的MSER算法的Python实现(opencv 2.4.11)和Java实现(opencv 2.4.10)。有趣的是,我注意到MSER的检测在Python与Java中返回不同类型的输出。在 Python 中,检测返回点列表的列表,其中每个点列表表示检测到的 blob。在 Java 中,返回 a,其中每行都是一个点,其关联的直径表示检测到的 blob。我想在Java中重现Python行为,其中blob由一组点定义,而不是一个点。有人知道发生了什么吗?Mat

蟒:

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)]

爪哇岛:

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 论坛上的mod提供了更多信息(http://answers.opencv.org/question/63733/why-does-python-implementation-and-java-implementation-of-mser-create-different-output/):

不幸的是,看起来,Java版本仅限于expecty2d。功能检测器接口,仅允许您访问关键点(而不是实际区域)

贝拉克 (六月 10 '15)

@berak:因此,如果我从文档中正确理解,java版本和python/C++版本都具有experty2d。FeatureDetector接口,但python/C++版本具有额外的MSER类来查找区域,而不仅仅是关键点?在这种情况下,人们会怎么做?是否可以将C++ MSER 类添加到 OpenCV 管理器中,在此处编辑类似 javaFeatureDetector 的内容,然后为其创建 java 包装器?感谢您的任何建议。

斯洛雷蒂(2015年6月11日)

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

贝拉克(2015年6月12日)


答案 1

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

Python给你一个包装的,它向Python公开它作为:cv2.MSERcv::MSERoperator()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使用包装器,该包装器调用由标准 FeatureDetector 接口支持并使用标准 FeatureDetector 接口:KeyPoint 列表。javaFeatureDetectorFeatureDetector::detectMSER::detectImpl

如果你想访问Java中的(在OpenCV 2.4中),你必须用JNI来包装它。operator()


答案 2