Как преобразовать 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?
Или есть способ использовать векторы так же, как и интерфейс С++ для реализации этого. Любое предложение или образец кода приветствуются.
Ответы
Ответ 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.