对于初学者,我试图在OpenCV Android中的矩阵上绘制轮廓和凸包。我跟着these codes跟我这样显示的程序:
/// Start contourImg
Log.i(TAG, "called contourImg");
//init
List<MatOfInt> hull = new ArrayList<MatOfInt>();
List<Point[]> hullPoints = new ArrayList<Point[]>();
List<MatOfPoint> hullMOP = new ArrayList<MatOfPoint>();
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Mat overlay = input.clone();
Mat hierarchy = new Mat(mask.rows(), mask.cols(), CvType.CV_8UC1, new Scalar(0));
Point titik1 = new Point(0,0);
Imgproc.findContours(mask, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE, titik1);
//Find the convex hull
for (int i = 0; i < contours.size(); i++) {
hull.add(new MatOfInt());
}
for (int i = 0; i < contours.size(); i++) {
Imgproc.convexHull(contours.get(i), hull.get(i), false);
}
// Convert MatOfInt to MatOfPoint for drawing convex hull
// Loop over all contours
for (int i = 0; i < contours.size(); i++) {
Point[] points = new Point[hull.get(i).rows()];
// Loop over all points that need to be hulled in current contour
for (int j = 0; j < hull.get(i).rows(); j++) {
int index = (int) hull.get(i).get(j, 0)[0];
points[j] = new Point(contours.get(i).get(index, 0)[0], contours.get(i).get(index, 0)[1]);
}
hullPoints.add(points);
}
// Convert Point arrays into MatOfPoint
for (int i = 0; i < hullPoints.size(); i++) {
MatOfPoint mop = new MatOfPoint();
mop.fromArray(hullPoints.get(i));
hullMOP.add(mop);
}
// Draw contours + hull results
for (int i = 0; i < contours.size(); i++) {
Imgproc.drawContours(overlay, contours, i, green);
Imgproc.drawContours(overlay, hullMOP, i, red);
}
基本上,输出将分别以绿色和红色绘制获得的轮廓和凸包。不幸的是,绘图变得太荒谬,以至于也绘制了小轮廓和凸包。
编辑:这是图片示例。注意那些也出现了较小的红色和绿色区域,而我希望它们不会出现。
问题是:我应该如何操纵hullMOP
arraylist,以便我得到指向MatOfPoint
的索引,只包含最大的轮廓和凸包?我尝试通过尝试找到最大的区域(如下所示)来应用与Imgproc.boundingRect()
方法相同的思路:
for (int i = 0; i < contours.size(); i++) {
boundRect[i] = Imgproc.boundingRect(polyMOP.get(i));
}
Rect bigRect = new Rect();
for (int i = 0; i < boundRect.length; i++) {
if (bigRect.area() < boundRect[i].area()) {
bigRect = boundRect[i];
}
}
Core.rectangle(image3, bigRect.tl(), bigRect.br(), green, 2);
,但我无法获得任何打击。任何建议都会有帮助。谢谢。
答案 0 :(得分:0)
如果有点太晚,我很抱歉。
我认为您可以使用@Override
public boolean equals(Object obj){
//check for null
if(this == null){
return false;
}
//make sure obj is a item
if(getClass() != obj.getClass()){
return false;
}
//cast obj as an item
final Item passsedItem = (Item) obj;
//check fields
if(!Objects.equals(this.name, passsedItem.name)){
return false;
}
if(!Objects.equals(this.price, passsedItem.price)){
return false;
}
return true;
}
/**
* Override hashcode method to be able to compare item state to see if they are the same
* @return
*/
@Override
public int hashCode() {
int hash = 7;
hash = 31 * hash + Objects.hashCode(this.price);
return hash;
}
来检查Imgproc.contourArea
和hullMOP
的最大区域。
以下是一个例子:
contours
因此Mat maxContour = null;
double maxContourarea=0;
for (int idx = 0; idx < contours.size(); idx++) {
Mat contour = contours.get(idx);
double contourarea = Imgproc.contourArea(contour);
if (contourarea > maxContourarea){
maxContourarea = contourarea;
maxContour = contour;
}
}
将包含最大轮廓,maxContour
是区域值。
答案 1 :(得分:0)
您可以使用Imgproc.RETR_EXTERNAL
。
CV_RETR_EXTERNAL
仅检索极端外轮廓。它为所有轮廓设置hierarchy[i][2]=hierarchy[i][3]=-1
。
换句话说,请使用Imgproc.findContours(mask, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE, titik1)
。