OpenCV Java:比较边界矩形';s y值,清除不需要的

OpenCV Java:比较边界矩形';s y值,清除不需要的,java,android,opencv,Java,Android,Opencv,在下图中,应用程序检测到多个“黑色”,并在其周围绘制了一个边框。现在我想比较每个矩形的rect3.tl().y值,只保留最小的一个,删除其他的边界矩形。但我不知道该怎么做 代码: Rect rectBlack = new Rect(); Bitmap roiBitmap = null; Scalar green = new Scalar(0, 255, 0, 255); Mat sourceMat = new Mat(sourceBitmap.getWidth(), s

在下图中,应用程序检测到多个“黑色”,并在其周围绘制了一个边框。现在我想比较每个矩形的
rect3.tl().y
值,只保留最小的一个,删除其他的边界矩形。
但我不知道该怎么做

代码:

Rect rectBlack = new Rect();
    Bitmap roiBitmap = null;
    Scalar green = new Scalar(0, 255, 0, 255);
    Mat sourceMat = new Mat(sourceBitmap.getWidth(), sourceBitmap.getHeight(), CvType.CV_8UC3);
    Utils.bitmapToMat(sourceBitmap, sourceMat);

    Mat roiTmp = sourceMat.clone();
    bitmapWidth = sourceBitmap.getWidth();
    Log.e("bitmapWidth", "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
    final Mat hsvMat = new Mat();
    sourceMat.copyTo(hsvMat);

    // convert mat to HSV format for Core.inRange()
    Imgproc.cvtColor(hsvMat, hsvMat, Imgproc.COLOR_RGB2HSV);

    Scalar lowerb = new Scalar(85, 50, 40);         // lower color border for BLUE
    Scalar upperb = new Scalar(135, 255, 255);      // upper color border for BLUE

    Scalar lowerblack = new Scalar(0, 0, 0);         // lower color border for BLACK
    Scalar upperblack = new Scalar(180, 255, 40);      // upper color border for BLACK

    Scalar testRunL = new Scalar(60, 50, 40); // lower Green   83 100 51
    Scalar testRunU = new Scalar(90, 255, 255); // upper Green

    Core.inRange(hsvMat, lowerblack, upperblack, roiTmp);   // select only blue pixels
    // find contours
    List<MatOfPoint> contours = new ArrayList<>();
    List<RotatedRect> boundingRects = new ArrayList<>();
    Imgproc.findContours(roiTmp, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);

    // find appropriate bounding rectangles
    for (MatOfPoint contour : contours) {
        MatOfPoint2f areaPoints = new MatOfPoint2f(contour.toArray());
        RotatedRect boundingRect = Imgproc.minAreaRect(areaPoints);

        double rectangleArea = boundingRect.size.area();

        // test min ROI area in pixels
        if (rectangleArea > 1300 ) {
            Point rotated_rect_points[] = new Point[4];
            boundingRect.points(rotated_rect_points);
            Rect rect3 = Imgproc.boundingRect(new MatOfPoint(rotated_rect_points));


            // test horizontal ROI orientation
            if (rect3.height > rect3.width) {
                Log.e("w,h", String.valueOf(rect3.width)+ " h " + String.valueOf(rect3.height));
                double w = rect3.width;
                double h = rect3.height;
                double ratio= h/w;

                    Log.e("h:w ratio", String.valueOf(ratio));
                    Log.e("Black Area", String.valueOf(rect3.area()));
                    Imgproc.rectangle(sourceMat, rect3.tl(), rect3.br(), green, 3);
                    rectBlack = rect3;
                    Log.e("blackArea", String.valueOf(rect3.area()));
                    xBlack = rect3.br().x;
                    xBlackCenter = (rect3.br().x + rect3.tl().x) / 2;
                    yBlack = rect3.br().y;//bottom
                    battHeight = (rect3.br().y - rect3.tl().y); //batt height in pixel


            }

        }

    }
Rect Rect black=new Rect();
位图=空;
标量绿色=新标量(0,255,0,255);
Mat sourceMat=new Mat(sourceBitmap.getWidth()、sourceBitmap.getHeight()、CvType.CV_8UC3);
bitmapToMat(sourceBitmap,sourceMat);
Mat roiTmp=sourceMat.clone();
bitmapWidth=sourceBitmap.getWidth();
Log.e(“位图宽度”、“~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~”;
最终材料hsvMat=新材料();
sourceMat.copyTo(hsvMat);
//将Core.inRange()的mat转换为HSV格式
Imgproc.cvtColor(hsvMat,hsvMat,Imgproc.COLOR_RGB2HSV);
标量下限b=新标量(85,50,40);//蓝色的较低颜色边框
标量上限B=新标量(135、255、255);//蓝色的上颜色边框
标量lowerblack=新标量(0,0,0);//黑色的较低颜色边框
标量上限黑=新标量(180、255、40);//黑色的上颜色边框
标量testRunL=新标量(60,50,40);//下绿83 100 51
标量testRunU=新标量(90255255);//上绿
Core.inRange(hsvMat、lowerblack、upperblack、roiTmp);//仅选择蓝色像素
//寻找轮廓
列表等高线=新的ArrayList();
List boundingRects=新建ArrayList();
Imgproc.findContours(roiTmp、等高线、new Mat()、Imgproc.RETR\u列表、Imgproc.CHAIN\u近似值\u简单值);
//找到合适的边界矩形
用于(点轮廓:轮廓){
MatOfPoint2f areaPoints=新的MatOfPoint2f(contour.toArray());
RotatedRect boundingRect=Imgproc.minareRect(面积点);
double rectangleArea=boundingRect.size.area();
//测试最小ROI区域(像素)
如果(矩形区域>1300){
点旋转的直线点[]=新点[4];
边界直点(旋转直点);
Rect rect3=Imgproc.boundingRect(新的MatOfPoint(旋转的矩形点));
//测试水平ROI方向
如果(rect3.height>rect3.width){
Log.e(“w,h”,String.valueOf(rect3.width)+“h”+String.valueOf(rect3.height));
双w=3.5米宽;
双h=3.5米高度;
双倍比=h/w;
Log.e(“h:w比率”,String.valueOf(比率));
Log.e(“黑色区域”,String.valueOf(rect3.Area());
矩形(sourceMat,rect3.tl(),rect3.br(),绿色,3);
rectBlack=rect3;
Log.e(“blackArea”,String.valueOf(rect3.area());
xBlack=rect3.br().x;
xBlackCenter=(rect3.br().x+rect3.tl().x)/2;
yBlack=rect3.br().y;//底部
电池高度=(rect3.br().y-rect3.tl().y);//以像素为单位的电池高度
}
}
}

您可以创建矩形列表:

List<Rect> rects = new ArrayList<>();
然后使用方法查找最底部的矩形,如下所示:

public static Rect getBottomMostRect(List<Rect> rects) {
    Rect bottomMostRect = null;

    if (rects != null && rects.size() >= 1) {
        Rect rect;
        double minY;
        int ixMinY = 0;

        rect = rects.get(ixMinY);
        minY = rect.tl().y;

        for (int ix = 1; ix < rects.size(); ix++) {
            rect = rects.get(ix);
            if (rect.tl().y < minY) {
                minY = rect.tl().y;
                ixMinY = ix;
            }
        }

        bottomMostRect = rects.get(ixMinY);
    }

    return bottomMostRect;
}

或者将
getbottomostrect()
实现直接添加到
for(MatOfPoint contour:contours)
循环中。

快速注意:
minY
值越大,图片中的黑色对象越“低”,因此if-else语句应该如下所示:
if(rect.tl().y>minY)
除此之外,我对代码没有任何问题,非常感谢您的帮助,包括这个问题和我的其他问题。哦!是的,你说得对!当然你应该找到maxY,而不是min。
public static Rect getBottomMostRect(List<Rect> rects) {
    Rect bottomMostRect = null;

    if (rects != null && rects.size() >= 1) {
        Rect rect;
        double minY;
        int ixMinY = 0;

        rect = rects.get(ixMinY);
        minY = rect.tl().y;

        for (int ix = 1; ix < rects.size(); ix++) {
            rect = rects.get(ix);
            if (rect.tl().y < minY) {
                minY = rect.tl().y;
                ixMinY = ix;
            }
        }

        bottomMostRect = rects.get(ixMinY);
    }

    return bottomMostRect;
}
Rect bottomMostRect = getBottomMostRect(rects)