Подтвердить что ты не робот

Почему реализация Python и реализация Java OpenCV MSER создают разные результаты?

Я пытаюсь использовать как реализацию Python (opencv 2.4.11), так и реализацию Java (opencv 2.4.10) алгоритма OpenCV MSER. Интересно, что я заметил, что обнаружение MSER возвращает разные типы вывода в Python vs Java. В Python обнаружение возвращает список списков точек, где каждый список точек представляет собой обнаруженное blob. В Java возвращается Mat, где каждая строка представляет собой единую точку с соответствующим диаметром, представляющим обнаруженное blob. Я хотел бы воспроизвести поведение Python в Java, где blobs определяются набором точек, а не одной точкой. Кто-нибудь знает, что происходит?

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]

EDIT:

Мод на форуме answers.opencv.org предоставил немного больше информации (http://answers.opencv.org/question/63733/why-does-python-implementation-and-java-implementation-of-mser-create-different-output/):

К сожалению, похоже, что версия java ограничена интерфейсом features2d.FeatureDetector, который позволяет вам получать доступ только к KeyPoints (а не к реальным регионам).

berak (10 июня 15)

@berak: Итак, если я правильно понимаю из документов, как версия java, так и версия python/С++ имеют интерфейс features2d.FeatureDetector, но версия python/С++ имеет дополнительный класс MSER для поиска регионов, а не только ключ точки? В этом случае, что делают люди? Можно ли добавить класс С++ MSER в менеджер OpenCV, отредактируйте здесь что-то вроде javaFeatureDetector и создайте для него оболочку java? Спасибо за любой совет.

sloreti (июн 11 '15)

так что да, вы можете получить прямоугольники в С++ или python, но не из java. что недостаток в дизайне. javaFeatureDetector все еще используется, но чтобы получить прямоугольники, вам придется писать собственный интерфейс jni, я думаю. (и распространять свои собственные .so вместе с вашим apk)

berak (12 июня 15)

4b9b3361

Ответ 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.

Если вы хотите получить доступ к operator() в Java (в OpenCV 2.4), вам придется его обернуть в JNI.