¿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 ..
- Android Studio 1.5 Opencv 3.0.0 calibración de la cámara de muestra se estrelló
- Visualización de imagen de mapa de bits en Android (OpenCV)
- Android + OpenCV: Cómo configurar la resolución de la cámara cuando se utiliza CameraBridgeViewBase
- OpenCV instalador independiente opencv
- Detección de objetos android opencv
Primeras imágenes mostradas imagen capturada por la cámara ..
La segunda imagen reconoce una imagen capturada como esta.
Investigo más y más, pero no conseguir nada puesto así, pregunto aquí si, alguien hizo esto me dicen ..
Gracias
- Imagen de limpieza para ayudar a tesseract en Android
- OpenCV Android - edición de color usando CameraBridgeViewBase
- Convertir Mat a Bitmap Opencv para Android
- Error de OpenCV Library con AndroidStudio
- Gire la imagen en opencv dependiendo del ángulo de inclinación ...!
- Cómo obtener efecto de color mágico como escáner de cámara utilizando OpenCV
- Imagen umbral con opencv (Java)
- Representación del modelo 3D de realidad aumentada
Aquí hay una demostración exactamente la misma aplicación que desea lograr
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; }
- Gestión de la memoria de Android Endless list
- Límite de 64 k superado en las API más antiguas que Lollipop, pero no más reciente