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)