Cómo encontrar las esquinas de un objeto Rect en openCV?

Estoy utilizando la biblioteca openCV en la plataforma android. He detectado con éxito el rectángulo más grande de la imagen, pero ya que mi aplicación se utilizará para el propósito de exploración, quiero tener la funcionalidad de cambio de perspectiva también.

Sé, cómo aplicar la perspectiva Transformación y warpPerspectiveTransform, pero para eso necesitaré esquinas del rectángulo para los puntos de la fuente.

Parece muy fácil encontrar las esquinas dado el hecho de que tenemos las coordenadas de la primera esquina (Superior izquierda) y el ancho / altura asociados con el objeto Rect, pero el problema es, para un rectángulo girado (boundingRect usual, pero lados no paralelos a Estos valores son muy diferentes. En este caso almacena los valores correspondientes a otro rectángulo con lados paralelos al eje y cubriendo el rectángulo girado, por lo que no puedo detectar las esquinas del rectángulo real.

También quiero hacer una comparación entre estos dos algoritmos para detectar una hoja de la imagen.

  1. Canny edge -> Contorno mayor -> rectángulo más grande -> encontrar esquinas -> cambio de perspectiva

  2. Canny edge-> Hough lines -> intersección de las líneas -> cambio de perspectiva

Lo que quiero preguntar es dado si tenemos un objeto Rect, ¿cómo obtener todas las esquinas de ese rectángulo?

Gracias por adelantado.

¡Soy muy emocionante para contestar mi pregunta! Era fácil pero sucede cuando u apenas comienza con algo con la documentación no tan apropiada relevante.

Yo estaba tratando de obtener las esquinas de un rectángulo general que no se definió en la aplicación de openCV y por lo tanto era casi imposible.

Seguí el código estándar en stackoverflow para la detección cuadrada más grande. Y las esquinas se pueden encontrar fácilmente utilizando el aproxCurve sí mismo.

// convertir la imagen en blanco y negro Imgproc.cvtColor (imgSource, imgSource, Imgproc.COLOR_BGR2GRAY);

//convert the image to black and white does (8 bit) Imgproc.Canny(imgSource, imgSource, 50, 50); //apply gaussian blur to smoothen lines of dots Imgproc.GaussianBlur(imgSource, imgSource, new org.opencv.core.Size(5, 5), 5); //find the contours List<MatOfPoint> contours = new ArrayList<MatOfPoint>(); Imgproc.findContours(imgSource, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE); double maxArea = -1; int maxAreaIdx = -1; Log.d("size",Integer.toString(contours.size())); MatOfPoint temp_contour = contours.get(0); //the largest is at the index 0 for starting point MatOfPoint2f approxCurve = new MatOfPoint2f(); MatOfPoint largest_contour = contours.get(0); //largest_contour.ge List<MatOfPoint> largest_contours = new ArrayList<MatOfPoint>(); //Imgproc.drawContours(imgSource,contours, -1, new Scalar(0, 255, 0), 1); for (int idx = 0; idx < contours.size(); idx++) { temp_contour = contours.get(idx); double contourarea = Imgproc.contourArea(temp_contour); //compare this contour to the previous largest contour found if (contourarea > maxArea) { //check if this contour is a square MatOfPoint2f new_mat = new MatOfPoint2f( temp_contour.toArray() ); int contourSize = (int)temp_contour.total(); MatOfPoint2f approxCurve_temp = new MatOfPoint2f(); Imgproc.approxPolyDP(new_mat, approxCurve_temp, contourSize*0.05, true); if (approxCurve_temp.total() == 4) { maxArea = contourarea; maxAreaIdx = idx; approxCurve=approxCurve_temp; largest_contour = temp_contour; } } } Imgproc.cvtColor(imgSource, imgSource, Imgproc.COLOR_BayerBG2RGB); sourceImage =Highgui.imread(Environment.getExternalStorageDirectory(). getAbsolutePath() +"/scan/p/1.jpg"); double[] temp_double; temp_double = approxCurve.get(0,0); Point p1 = new Point(temp_double[0], temp_double[1]); //Core.circle(imgSource,p1,55,new Scalar(0,0,255)); //Imgproc.warpAffine(sourceImage, dummy, rotImage,sourceImage.size()); temp_double = approxCurve.get(1,0); Point p2 = new Point(temp_double[0], temp_double[1]); // Core.circle(imgSource,p2,150,new Scalar(255,255,255)); temp_double = approxCurve.get(2,0); Point p3 = new Point(temp_double[0], temp_double[1]); //Core.circle(imgSource,p3,200,new Scalar(255,0,0)); temp_double = approxCurve.get(3,0); Point p4 = new Point(temp_double[0], temp_double[1]); // Core.circle(imgSource,p4,100,new Scalar(0,0,255)); List<Point> source = new ArrayList<Point>(); source.add(p1); source.add(p2); source.add(p3); source.add(p4); Mat startM = Converters.vector_Point2f_to_Mat(source); Mat result=warp(sourceImage,startM); return result; 

Y la función utilizada para la transformación en perspectiva se da a continuación:

  public Mat warp(Mat inputMat,Mat startM) { int resultWidth = 1000; int resultHeight = 1000; Mat outputMat = new Mat(resultWidth, resultHeight, CvType.CV_8UC4); 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 = Imgproc.getPerspectiveTransform(startM, endM); Imgproc.warpPerspective(inputMat, outputMat, perspectiveTransform, new Size(resultWidth, resultHeight), Imgproc.INTER_CUBIC); return outputMat; } 
 1. find the coordinate of left ,right, top,bottom point of the rect 2. min_x = min(left.x right.x,top.x,bottom.x) min_y = min(left.y right.y,top.y,bottom.y) max_x = max(left.x right.x,top.x,bottom.x) max_y = max(left.y right.y,top.y,bottom.y) 3. the corners's coordinate is the point with the min_x, min_y ,max_x, max_y 
  • Android Paper Detection con OpenCV
  • ¿Cómo deformar imágenes en Android?
  • Ajuste de saturación y ColorFilter a la imagen simultáneamente
  • Comparar dos imágenes en android
  • Primeros pasos para crear un efecto de chroma key utilizando la cámara android
  • Convertir un mapa de bits en GrayScale en Android
  • Procesamiento de fotogramas de cámara Android en tiempo real
  • Detección de imágenes en paralelo y vista previa de la cámara OpenCV Android
  • Croping la imagen en android usando opencv
  • Encuentra color dominante en un marco de cámara en OpenCV Android
  • Usando get () y put () para acceder a valores de píxeles en OpenCV para Java
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.