2015-03-28 2 views
1

Я пытаюсь нарисовать выпуклый корпус на изображении. Для этого я нахожу все контуры и выбираю контур максимальной площади. drawContours принимает MatOfPoint, но convexHull дает мне MatOfInt. Я прочитал это question и запустил некоторые коды. Некоторые из них рисуют выпуклый корпус, но они не могут найти действительно выпуклых точек.Нарисовать выпуклый корпус на android

Я использую ниже код, но на последней строке m.fromArray(hullpoints.get(i));. hullpoints.get(i) имеет только одну точку и код не может создать объект MatOfPoint. Как я могу конвертировать в MatOfPoint от MatOfInt?

 // Find the convex hull 
     List<MatOfInt> hull = new ArrayList<MatOfInt>(); 
     for(int j=0; j < contours.size(); j++){ 
      hull.add(new MatOfInt()); 
     } 
     for(int j=0; j < contours.size(); j++){ 
      Imgproc.convexHull(contours.get(j), hull.get(j)); 
     } 

     // Convert MatOfInt to MatOfPoint for drawing convex hull 
     // Loop over all contours 
     List<Point[]> hullpoints = new ArrayList<Point[]>(); 
     for(int j=0; j < hull.size(); j++){ 
      Point[] points = new Point[hull.get(j).rows()]; 

      // Loop over all points that need to be hulled in current contour 
      for(int k=0; k < hull.get(j).rows(); k++){ 
       int index2 = (int)hull.get(j).get(k, 0)[0]; 
       points[k] = new Point(contours.get(j).get(index2, 0)[0], contours.get(j).get(index2, 0)[1]); 
      } 
      hullpoints.add(points); 
     } 

     // Convert Point arrays into MatOfPoint 
     List<MatOfPoint> hullmop = new ArrayList<MatOfPoint>(); 
     for(int j=0; j < hullpoints.size(); j++){ 
      MatOfPoint m = new MatOfPoint(); 
      m.fromArray(hullpoints.get(i)); 
      hullmop.add(m); 
     } 
+0

для моей ошибки индекса. Я не удаляю этот вопрос, чтобы руководить рисованием выпуклого корпуса в приложении Android. Замените 'hullpoints.get (i)' 'hullpoints.get (j)' – zumma

+0

Каковы типы классов 'contours' и' hull'? Что такое 'Imgproc'? –

ответ

1

FWIW, я изменил FastConvexHull от here использовать com.google.android.gms.maps.model.LatLong. Минимально проверены, поэтому никаких гарантий нет.

Интерфейс:

import com.google.android.gms.maps.model.LatLng; 
import java.util.ArrayList; 

public interface ConvexHullAlgorithm 
{ 
    ArrayList<LatLng> execute(ArrayList<LatLng> points); 
} 

Класс:

public class FastConvexHull implements ConvexHullAlgorithm { 

    @Override 
    public ArrayList<LatLng> execute(ArrayList<LatLng> points) { 
     ArrayList<LatLng> xSorted = (ArrayList<LatLng>) points.clone(); 
     Collections.sort(xSorted, new XCompare()); 

     int n = xSorted.size(); 

     LatLng[] lUpper = new LatLng[n]; 

     lUpper[0] = xSorted.get(0); 
     lUpper[1] = xSorted.get(1); 

     int lUpperSize = 2; 

     for (int i = 2; i < n; i++) { 
      lUpper[lUpperSize] = xSorted.get(i); 
      lUpperSize++; 

      while (lUpperSize > 2 && !rightTurn(lUpper[lUpperSize - 3], lUpper[lUpperSize - 2], lUpper[lUpperSize - 1])) { 
       // Remove the middle point of the three last 
       lUpper[lUpperSize - 2] = lUpper[lUpperSize - 1]; 
       lUpperSize--; 
      } 
     } 

     LatLng[] lLower = new LatLng[n]; 

     lLower[0] = xSorted.get(n - 1); 
     lLower[1] = xSorted.get(n - 2); 

     int lLowerSize = 2; 

     for (int i = n - 3; i >= 0; i--) { 
      lLower[lLowerSize] = xSorted.get(i); 
      lLowerSize++; 

      while (lLowerSize > 2 && !rightTurn(lLower[lLowerSize - 3], lLower[lLowerSize - 2], lLower[lLowerSize - 1])) { 
       // Remove the middle point of the three last 
       lLower[lLowerSize - 2] = lLower[lLowerSize - 1]; 
       lLowerSize--; 
      } 
     } 

     ArrayList<LatLng> result = new ArrayList<LatLng>(); 

     for (int i = 0; i < lUpperSize; i++) { 
      result.add(lUpper[i]); 
     } 

     for (int i = 1; i < lLowerSize - 1; i++) { 
      result.add(lLower[i]); 
     } 

     return result; 
    } 

    private boolean rightTurn(LatLng a, LatLng b, LatLng c) { 
     return (b.latitude - a.latitude) * (c.longitude - a.longitude) - (b.longitude - a.longitude) * (c.latitude - a.latitude) > 0; 
    } 

    private class XCompare implements Comparator<LatLng> { 
     @Override 
     public int compare(LatLng o1, LatLng o2) { 
      return (new Float(o1.latitude)).compareTo(new Float(o2.latitude)); 
     } 
    } 
} 
Смежные вопросы