Android OpenCV Encuentra la plaza o rectángulo más grande

Esto pudo haber sido contestado pero desesperadamente necesito una respuesta para esto. Quiero encontrar el cuadrado o rectángulo más grande en una imagen usando OpenCV en Android. Todas las soluciones que he encontrado son C + + y he intentado convertirlo, pero no funciona y no sé dónde me equivoco.

private Mat findLargestRectangle(Mat original_image) { Mat imgSource = original_image; Imgproc.cvtColor(imgSource, imgSource, Imgproc.COLOR_BGR2GRAY); Imgproc.Canny(imgSource, imgSource, 100, 100); //I don't know what to do in here return imgSource; } 

Lo que estoy tratando de lograr aquí es crear una nueva imagen que se basa en el cuadrado más grande que se encuentra en la imagen original (valor de retorno Mat imagen).

Esto es lo que quiero que suceda:

1 http://img14.imageshack.us/img14/7855/s7zr.jpg

También está bien que acabo de obtener los cuatro puntos de la plaza más grande y creo que puedo tomar desde allí. Pero sería mejor si pudiera devolver la imagen recortada.

Después de canny

1- es necesario reducir los ruidos con el desenfoque gaussiano y encontrar todos los contornos

2- encontrar y listar todas las áreas de los contornos .

3- el contorno más grande no será más que la pintura.

4- ahora usa la transformación perpective para transformar tu forma en un rectángulo.

Verifique los ejemplos de sudoku solver para ver el problema de procesamiento similar. (Mayor contorno + perspectiva)

Me tomó un tiempo para convertir el código C ++ a Java, pero aquí está 🙂

Advertencia ! Código crudo, totalmente no optimizado y todo.

Rechazo cualquier responsabilidad en caso de lesiones o accidentes letales

  List<MatOfPoint> squares = new ArrayList<MatOfPoint>(); public Mat onCameraFrame(CvCameraViewFrame inputFrame) { if (Math.random()>0.80) { findSquares(inputFrame.rgba().clone(),squares); } Mat image = inputFrame.rgba(); Imgproc.drawContours(image, squares, -1, new Scalar(0,0,255)); return image; } int thresh = 50, N = 11; // helper function: // finds a cosine of angle between vectors // from pt0->pt1 and from pt0->pt2 double angle( Point pt1, Point pt2, Point pt0 ) { double dx1 = pt1.x - pt0.x; double dy1 = pt1.y - pt0.y; double dx2 = pt2.x - pt0.x; double dy2 = pt2.y - pt0.y; return (dx1*dx2 + dy1*dy2)/Math.sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10); } // returns sequence of squares detected on the image. // the sequence is stored in the specified memory storage void findSquares( Mat image, List<MatOfPoint> squares ) { 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 for( int c = 0; c < 3; c++ ) { extractChannel(image, gray, c); // try several threshold levels for( int l = 1; l < N; l++ ) { //Cany removed... Didn't work so well 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++ ) { // approximate contour with accuracy proportional // to the contour perimeter 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 if( approx.toArray().length == 4 && Math.abs(Imgproc.contourArea(approx)) > 1000 && Imgproc.isContourConvex(approx) ) { double maxCosine = 0; 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); } // 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); } } } } } void extractChannel(Mat source, Mat out, int channelNum) { List<Mat> sourceChannels=new ArrayList<Mat>(); List<Mat> outChannel=new ArrayList<Mat>(); Core.split(source, sourceChannels); outChannel.add(new Mat(sourceChannels.get(0).size(),sourceChannels.get(0).type())); Core.mixChannels(sourceChannels, outChannel, new MatOfInt(channelNum,0)); Core.merge(outChannel, out); } MatOfPoint approxPolyDP(MatOfPoint curve, double epsilon, boolean closed) { MatOfPoint2f tempMat=new MatOfPoint2f(); Imgproc.approxPolyDP(new MatOfPoint2f(curve.toArray()), tempMat, epsilon, closed); return new MatOfPoint(tempMat.toArray()); } 

Hay algunas preguntas relacionadas aquí en SO. Compruébelo:

  • OpenCV C ++ / Obj-C: detección de una hoja de papel / detección cuadrada

  • ¿Cómo reconozco los cuadrados en esta imagen?

También hay un ejemplo enviado con OpenCV:

Una vez que tenga el rectángulo, puede alinear la imagen calculando la homografía con las esquinas del rectángulo y aplicando una transformación de perspectiva.

  • Android Paper Detection con OpenCV
  • Android UnsatisfiedLinkError con OpenCV 2.4.2
  • Reducción de la reflexión de luz OpenCV
  • Cómo acceder a las filas y columnas de Vector <Mat> Imágenes en Open cv para Android?
  • Uso de OpenCV en Java Camera2 API
  • Detección de diferentes formas dinámicamente como (Círculo, cuadrado y Rectángulo) de la cámara?
  • (OpenCV) no puede encontrar Core.line en Android Studio
  • Cómo forzar una cámara de Android a mostrar en modo vertical, o para que yo haga la rotación en su lugar
  • Tamaños de imagen compatibles con webcam
  • configuración de vídeo opencv a pantalla completa android
  • Cómo abrir la cámara en modo retrato utilizando OpenCV en la aplicación Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.