¿Cómo realizar el recorte automático para el documento Reconocer la imagen con la cámara?

Quiero hacer una aplicación como un escáner de leva para recortar un documento.

Pero necesito la misma funcionalidad como mis dos imágenes ..

Primeras imágenes mostradas imagen capturada por la cámara ..

Introduzca aquí la descripción de la imagen

La segunda imagen reconoce una imagen capturada como esta.

Introduzca aquí la descripción de la imagen

Investigo más y más, pero no conseguir nada puesto así, pregunto aquí si, alguien hizo esto me dicen ..

Gracias

Aquí hay una demostración exactamente la misma aplicación que desea lograr

https://github.com/jhansireddy/AndroidScannerDemo

Supongo que su problema es detectar el objeto a analizar.

Los mecanismos de detección de objetos como la coincidencia de patrones o la detección de funciones no le aportarán los resultados que está buscando, ya que no sabe qué es exactamente el objeto que está escaneando.

Básicamente, usted busca un objeto rectangular en la imagen.

Un enfoque básico para esto podría ser lo siguiente:

  • Ejecute un detector de borde canny en la imagen. Podría ayudar a difuminar la imagen un poco antes de hacer esto. Los bordes del objeto deben ser claramente visibles.

  • Ahora quieres hacer una transformación Hough para encontrar líneas en la imagen.

  • Busca líneas con un ángulo de 90 ° entre sí. El problema sería encontrar los correctos. Tal vez sea suficiente usar las líneas más cercanas al marco de la imagen que sean razonablemente paralelas a ellas.

  • Encuentre los puntos de intersección para definir los bordes de su objeto.

Por lo menos esto debe darle una indirecta donde investigar más lejos.

Como pasos adicionales en tal aplicación, tendrás que calcular la proyección de los puntos y realizar una transformación afín del objeto.

Espero que esto ayude.

Después de escribir todo esto encontré este post. Debe ayudar mucho.

Como mi respuesta es OpenCV, tienes que usar la librería OpenCV. Para ello, debe instalar el kit de desarrollo nativo de Android (NDK) . Hay algunos buenos tutoriales sobre cómo usar OpenCV en Android en la página de OpenCV para Android .

Una cosa a tener en cuenta es que casi cada función del contenedor Java llama a un método nativo. Eso cuesta mucho tiempo. Por lo tanto, desea hacer todo lo posible en su código nativo antes de devolver los resultados a la parte Java.

Sé que soy demasiado tarde para responder, pero podría ser útil para alguien.

Pruebe el siguiente código.

@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); path = new Path(); path.moveTo(x1, y1); // this should set the start point right //path.lineTo(x1, y1); <-- this line should be drawn at the end of course,sorry path.lineTo(x2, y2); path.lineTo(x3, y3); path.lineTo(x4, y4); path.lineTo(x1, y1); canvas.drawPath(path, currentPaint); } 

He creado un repo git con el código de soporte nativo, que es cortar la imagen de la manera correcta, por favor, encontrarlo en: enlace .

Siéntase libre de editar código si se le ocurre una solución mejor.

Pase su imagen mat en este método:

  void findSquares(Mat image, List<MatOfPoint> squares) { int N = 10; squares.clear(); Mat smallerImg = new Mat(new Size(image.width() / 2, image.height() / 2), image.type()); Mat gray = new Mat(image.size(), image.type()); Mat gray0 = new Mat(image.size(), CvType.CV_8U); // down-scale and upscale the image to filter out the noise Imgproc.pyrDown(image, smallerImg, smallerImg.size()); Imgproc.pyrUp(smallerImg, image, image.size()); // find squares in every color plane of the image Outer: for (int c = 0; c < 3; c++) { extractChannel(image, gray, c); // try several threshold levels Inner: for (int l = 1; l < N; l++) { Imgproc.threshold(gray, gray0, (l + 1) * 255 / N, 255, Imgproc.THRESH_BINARY); List<MatOfPoint> contours = new ArrayList<MatOfPoint>(); // find contours and store them all as a list Imgproc.findContours(gray0, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE); MatOfPoint approx = new MatOfPoint(); // test each contour for (int i = 0; i < contours.size(); i++) { approx = approxPolyDP(contours.get(i), Imgproc.arcLength(new MatOfPoint2f(contours.get(i).toArray()), true) * 0.02, true); // square contours should have 4 vertices after approximation // relatively large area (to filter out noisy contours) // and be convex. // Note: absolute value of an area is used because // area may be positive or negative - in accordance with the // contour orientation double area = Imgproc.contourArea(approx); if (area > 5000) { if (approx.toArray().length == 4 && Math.abs(Imgproc.contourArea(approx)) > 1000 && Imgproc.isContourConvex(approx)) { double maxCosine = 0; Rect bitmap_rect = null; for (int j = 2; j < 5; j++) { // find the maximum cosine of the angle between joint edges double cosine = Math.abs(angle(approx.toArray()[j % 4], approx.toArray()[j - 2], approx.toArray()[j - 1])); maxCosine = Math.max(maxCosine, cosine); bitmap_rect = new Rect(approx.toArray()[j % 4], approx.toArray()[j - 2]); } // if cosines of all angles are small // (all angles are ~90 degree) then write quandrange // vertices to resultant sequence if (maxCosine < 0.3) squares.add(approx); } } } } } } 

En este método se obtiene cuatro puntos de documento, a continuación, puede cortar esta imagen utilizando el siguiente método:

  public Bitmap warpDisplayImage(Mat inputMat) { List<Point> newClockVisePoints = new ArrayList<>(); int resultWidth = inputMat.width(); int resultHeight = inputMat.height(); Mat startM = Converters.vector_Point2f_to_Mat(orderRectCorners(Previes method four poit list(like : List<Point> points))); Point ocvPOut4 = new Point(0, 0); Point ocvPOut1 = new Point(0, resultHeight); Point ocvPOut2 = new Point(resultWidth, resultHeight); Point ocvPOut3 = new Point(resultWidth, 0); ocvPOut3 = new Point(0, 0); ocvPOut4 = new Point(0, resultHeight); ocvPOut1 = new Point(resultWidth, resultHeight); ocvPOut2 = new Point(resultWidth, 0); } Mat outputMat = new Mat(resultWidth, resultHeight, CvType.CV_8UC4); List<Point> dest = new ArrayList<Point>(); dest.add(ocvPOut3); dest.add(ocvPOut2); dest.add(ocvPOut1); 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), Imgproc.INTER_CUBIC); Bitmap descBitmap = Bitmap.createBitmap(outputMat.cols(), outputMat.rows(), Bitmap.Config.ARGB_8888); Utils.matToBitmap(outputMat, descBitmap); return descBitmap; } 
  • Guardar los vectores de características de ORB usando OpenCV4Android (java API)
  • Qt Android proyecto con OpenCV - tbb errores de compilación
  • Android-opencv conversión mat a escala de grises con el uso de matToBitmap / bitmapToMat
  • Devolver objeto Mat desde código nativo a java en OpenCV
  • Android Studio no puede encontrar los módulos opencv, pero compila ok
  • Cómo detectar (contar) el cabello de la imagen con OpenCV?
  • No se puede construir caffe en android
  • SURF Feature Extraction con Android OpenCV SDK - Obtener algunos errores
  • Buscando OpenCV android tutorial
  • ¿Cómo usar OpenCV para procesar la imagen para que el texto se vuelva nítido y claro?
  • Resolver avisos NDK obsoletos en Android Studio
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.