我尝试在图像上绘制凸包。为此,我找到所有轮廓并选择最大面积轮廓。 drawContours
接受MatOfPoint
但convexHull
给我MatOfInt
。我读了这个question并运行了一些代码。他们中的一些人绘制了凸包,但他们找不到真正的凸点。
我使用下面的代码,但它在最后一行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 :(得分: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));
}
}
}