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.
- No se puede construir caffe en android
- Umbral adaptable rápido para Canny Edge Detector en Android
- OpenCV para ANDROID comparar imagen
- Detección de objetos Android OpenCV
- Cuadros de bits en escala de grises en android
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.
-
Canny edge -> Contorno mayor -> rectángulo más grande -> encontrar esquinas -> cambio de perspectiva
-
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.
- Cortar la imagen después de seleccionar el área mediante la detección de bordes en android
- Hacer que la imagen superpuesta sea transparente al tocar en Android?
- Android: BitmapFactory.decodeByteArray ofrece bitmap pixelado
- ¿Cómo detectar la intensidad promedio de píxeles de la vista previa de cámara en vivo?
- Recortar parte particular de la imagen en android
- Sobel Edge Detection en Android
- Cómo configurar la imagen de salida use com.android.camera.action.CROP
- Recortar imagen por área de polígono
¡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
- Tire para actualizar en Android sin biblioteca popular
- Haga clic en notificación para ingresar mi aplicación en android