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

Как преобразовать MatOfPoint в MatOfPoint2f в opencv java api

Я пытаюсь реализовать код примера следующего question используя opencv java api. Для реализации findContours(gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE); в java я использовал этот синтаксис Imgproc.findContours(gray, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);.

Итак, теперь контуры должны быть List<MatOfPoint> contours = new ArrayList<MatOfPoint>();, а не vector<vector<cv::Point> > contours;.

Тогда мне нужно реализовать этот approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true);. В java api аргумент Imgproc.approxPolyDP принимает аргумент как approxPolyDP(MatOfPoint2f curve, MatOfPoint2f approxCurve, double epsilon, boolean closed). Как я могу преобразовать MatOfPoint в MatOfPoint2f?

Или есть способ использовать векторы так же, как и интерфейс С++ для реализации этого. Любое предложение или образец кода приветствуются.

4b9b3361

Ответ 1

MatOfPoint2f отличается от MatOfPoint только типом элементов (32-битный float и 32-битный int соответственно). Жизнеспособным вариантом (хотя и с ограничением производительности) является создание экземпляра MatOfPoint2f и установка его элементов (в цикле) равными элементам исходного MatOfPoint.

Есть

 public void fromArray(Point... lp);
 public Point[] toArray();

в обоих классах.

Итак, вы можете сделать только

 /// Source variable
 MatOfPoint SrcMtx;

 /// New variable
 MatOfPoint2f  NewMtx = new MatOfPoint2f( SrcMtx.toArray() );

Ответ 2

Я понимаю, что этот вопрос уже хорошо ответил, но добавить альтернативу для всех, кто найдет его в будущем -

Imgproc.findContours(gray, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);

for(int i=0;i<contours.size();i++){
    //Convert contours(i) from MatOfPoint to MatOfPoint2f
    contours.get(i).convertTo(mMOP2f1, CvType.CV_32FC2);
    //Processing on mMOP2f1 which is in type MatOfPoint2f
    Imgproc.approxPolyDP(mMOP2f1, mMOP2f2, approxDistance, true); 
    //Convert back to MatOfPoint and put the new values back into the contours list
    mMOP2f2.convertTo(contours.get(i), CvType.CV_32S);
}

Ответ 3

Хотя на этот вопрос уже был дан ответ, я считаю, что принятый ответ не самый лучший. Преобразование матрицы в массив, а затем назад происходит с довольно высокой эффективностью, как по времени, так и по памяти.

Вместо этого в OpenCV уже есть функция, которая выполняет именно это: convertTo.

MatOfPoint src;
// initialize src
MatOfPoint2f dst = new MatOfPoint2f();
src.convertTo(dst, CvType.CV_32F);

Я нашел, что это значительно быстрее и удобнее для памяти.

Чтобы преобразовать MatOfPoint2f в MatOfPoint, вместо этого используйте CvType.CV_32S.