No se puede obtener el warpPerspective de OpenCV para trabajar en Android

He estado luchando para implementar un sistema de cuatro a cuatro en mi aplicación de Android. El objetivo es dejar que el usuario tome una imagen, añadir 4 puntos de esquina y tener ese quad extraído de la imagen como un rectángulo.

He echado un vistazo a este método y esta pregunta para usar OpenCV para esto. El código resultante es el siguiente:

public static Bitmap warp(Bitmap image, MyPoint p1, MyPoint p2, MyPoint p3, MyPoint p4) { int resultWidth = 500; int resultHeight = 500; Mat inputMat = new Mat(image.getHeight(), image.getHeight(), CvType.CV_8UC4); Utils.bitmapToMat(image, inputMat); Mat outputMat = new Mat(resultWidth, resultHeight, CvType.CV_8UC4); Point ocvPIn1 = new Point(p1.getX(), p1.getY()); Point ocvPIn2 = new Point(p2.getX(), p2.getY()); Point ocvPIn3 = new Point(p3.getX(), p3.getY()); Point ocvPIn4 = new Point(p4.getX(), p4.getY()); List<Point> source = new ArrayList<Point>(); source.add(ocvPIn1); source.add(ocvPIn2); source.add(ocvPIn3); source.add(ocvPIn4); Mat startM = Converters.vector_Point2f_to_Mat(source); Point ocvPOut1 = new Point(0, 0); Point ocvPOut2 = new Point(0, resultHeight); Point ocvPOut3 = new Point(resultWidth, resultHeight); Point ocvPOut4 = new Point(resultWidth, 0); List<Point> dest = new ArrayList<Point>(); dest.add(ocvPOut1); dest.add(ocvPOut2); dest.add(ocvPOut3); dest.add(ocvPOut4); Mat endM = Converters.vector_Point2f_to_Mat(dest); Mat perspectiveTransform = new Mat(3, 3, CvType.CV_32FC1); Core.perspectiveTransform(startM, endM, perspectiveTransform); Imgproc.warpPerspective(inputMat, outputMat, perspectiveTransform, new Size(resultWidth, resultHeight), Imgproc.INTER_CUBIC); Bitmap output = Bitmap.createBitmap(resultWidth, resultHeight, Bitmap.Config.RGB_565); Utils.matToBitmap(outputMat, output); return output; } 

Durante la prueba, me aseguro de que el orden de los puntos de esquina sea superior izquierda, inferior izquierda, inferior derecha, superior derecha.

Lo extraño es que el resultado no es siempre el mismo. La mayoría de las veces muestra un cuadrado de un solo color, a veces un cuadrado negro, a veces una línea diagonal con diferentes colores en él. Incluso la experimentación con startM = endM da lugar a un comportamiento no determinista.

¿Que me estoy perdiendo aqui?

Lo encontré, el problema estaba en estas líneas:

 Mat perspectiveTransform = new Mat(3, 3, CvType.CV_32FC1); Core.perspectiveTransform(startM, endM, perspectiveTransform); 

Cuál debe ser substituido por esto:

 Mat perspectiveTransform = Imgproc.getPerspectiveTransform(startM, endM); 

Tuve algunos problemas con su código, así que hice cambios hasta que obtuve una versión de trabajo, aquí está mi código si alguien tenía problemas con el código de la pregunta:

 Bitmap warp(Bitmap image, Point topLeft, Point topRight, Point bottomLeft, Point bottomRight) { int resultWidth = (int)(topRight.x - topLeft.x); int bottomWidth = (int)(bottomRight.x - bottomLeft.x); if(bottomWidth > resultWidth) resultWidth = bottomWidth; int resultHeight = (int)(bottomLeft.y - topLeft.y); int bottomHeight = (int)(bottomRight.y - topRight.y); if(bottomHeight > resultHeight) resultHeight = bottomHeight; Mat inputMat = new Mat(image.getHeight(), image.getHeight(), CvType.CV_8UC1); Utils.bitmapToMat(image, inputMat); Mat outputMat = new Mat(resultWidth, resultHeight, CvType.CV_8UC1); List<Point> source = new ArrayList<>(); source.add(topLeft); source.add(topRight); source.add(bottomLeft); source.add(bottomRight); Mat startM = Converters.vector_Point2f_to_Mat(source); Point ocvPOut1 = new Point(0, 0); Point ocvPOut2 = new Point(resultWidth, 0); Point ocvPOut3 = new Point(0, resultHeight); Point ocvPOut4 = new Point(resultWidth, resultHeight); List<Point> dest = new ArrayList<>(); dest.add(ocvPOut1); dest.add(ocvPOut2); dest.add(ocvPOut3); dest.add(ocvPOut4); Mat endM = Converters.vector_Point2f_to_Mat(dest); Mat perspectiveTransform = Imgproc.getPerspectiveTransform(startM, endM); Imgproc.warpPerspective(inputMat, outputMat, perspectiveTransform, new Size(resultWidth, resultHeight)); Bitmap output = Bitmap.createBitmap(resultWidth, resultHeight, Bitmap.Config.ARGB_8888); Utils.matToBitmap(outputMat, output); return output; } 
  • Mejora del rendimiento de OpenCV Android: seguimiento rápido de objetos
  • Cómo integrar OpenCV Manager en la aplicación para Android
  • Android NDK. Ninguna sección de C / C ++ en las propiedades del proyecto de Eclipse
  • Usando get () y put () para acceder a valores de píxeles en OpenCV para Java
  • Cómo devolver una imagen de opencv y mostrar en código androide java?
  • Transformación de perspectiva
  • OpenCV en Android - Encabezados; No hay tal directorio de archivos
  • Rotar la imagen desde los datos del sensor de orientación
  • Cómo ejecutar código OpenCV sin OpenCv Manager
  • SIGNAL 11 SIGSEGV código = 2 crash Android
  • OpenCV Native Samples no están construyendo
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.