我目前有这张图片:
我设法检测到黑色物体。现在我想检测绿色对象,但我只希望应用程序在黑色对象下面找到绿色对象 。我已经有了检测绿色磁带及其工作的代码。只需将其设置为仅在黑色物体下方的区域中。
P.S一些变量被命名为" Blue",请使用绿色标量值放心。
代码:
//Detect Black
private Bitmap findCombine(Bitmap sourceBitmap) {
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", String.valueOf(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 && rectangleArea < 500000) {//400000
Point rotated_rect_points[] = new Point[4];
boundingRect.points(rotated_rect_points);
Rect rect3 = Imgproc.boundingRect(new MatOfPoint(rotated_rect_points));
Log.e("blackArea", String.valueOf(rect3.area()));
// test horizontal ROI orientation
if (rect3.height > rect3.width) {
Imgproc.rectangle(sourceMat, rect3.tl(), rect3.br(), green, 3);
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
Log.e("BLACKBR, TL", String.valueOf(rect3.br().y) + "," + String.valueOf(rect3.tl().y));
}
}
}
roiBitmap = Bitmap.createBitmap(sourceMat.cols(), sourceMat.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(sourceMat, roiBitmap);
//Set area to detect green
Point leftPoint = new Point(0, yBlack); //far left, black object height
Point rightPoint = new Point(roiBitmap.getWidth(), roiBitmap.getHeight()); //btm right of entire bitmap
Rect bottomRect = new Rect(leftPoint, rightPoint);
double rectWidth = sourceBitmap.getWidth() - 0;
double rectHeight = sourceBitmap.getHeight() - yBlack;
Log.e("rectWidth", String.valueOf(rectWidth));
Log.e("rectHeight", String.valueOf(rectHeight));
Mat sourceMatT = new Mat(roiBitmap.getWidth(), roiBitmap.getHeight(), CvType.CV_8UC3);
Utils.bitmapToMat(roiBitmap,sourceMatT);
Bitmap C = Bitmap.createBitmap(sourceMatT.cols(), sourceMatT.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(sourceMatT, C);
Mat dumbMat = sourceMatT.clone();
Log.e("sourceMatT, BottomRect","SMT "+ String.valueOf(sourceMatT.size()) + " bottomRect " + String.valueOf(bottomRect.size()));
Mat cropMat = new Mat(dumbMat, bottomRect);
ImageView imgCropped = (ImageView) findViewById(R.id.cropped_image_view);
//Utils.matToBitmap(cropMat,C);
imgCropped.setImageBitmap(C);
//Detect Green
Bitmap roiBitmap2 = null;
Mat sourceMat2 = new Mat(C.getWidth(), C.getHeight(), CvType.CV_8UC3);
Utils.bitmapToMat(C, sourceMat2);
Mat roiTmp2 = sourceMat2.clone();
final Mat hsvMat2 = new Mat();
sourceMat.copyTo(hsvMat2);
// convert mat to HSV format for Core.inRange()
Imgproc.cvtColor(hsvMat2, hsvMat2, Imgproc.COLOR_RGB2HSV);
Core.inRange(hsvMat2, testRunL, testRunU, roiTmp2); // select only blue pixels
// find contours
List<MatOfPoint> contours2 = new ArrayList<>();
List<RotatedRect> boundingRects2 = new ArrayList<>();
Imgproc.findContours(roiTmp2, contours2, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
// find appropriate bounding rectangles
for (MatOfPoint contour2 : contours2) {
MatOfPoint2f areaPoints2 = new MatOfPoint2f(contour2.toArray());
RotatedRect boundingRect2 = Imgproc.minAreaRect(areaPoints2);
double rectangleArea2 = boundingRect2.size.area();
// test min ROI area in pixels
if (rectangleArea2 > 40) { //214468.32402064091 // 20000
Point rotated_rect_points2[] = new Point[4];
boundingRect2.points(rotated_rect_points2);
Rect rect = Imgproc.boundingRect(new MatOfPoint(rotated_rect_points2));
Log.e("area green", String.valueOf(boundingRect2.size.area()));
// test vertical ROI orientation
if (rect.width > rect.height) {
if (numRect < 2) {
Imgproc.rectangle(sourceMat2, rect.tl(), rect.br(), green, 3);
xBlue = (rect.br().x + rect.tl().x) / 2; //center
yBlue = rect.br().y; //bottom
Log.e("GREEN br,tl", String.valueOf(rect.br().y) + " " + String.valueOf(rect.tl().y));
}
}
}
}
Point firstPoint = new Point(xBlackCenter, yBlack);
Point secondPoint = new Point(xBlackCenter, yBlue);
Point middlePoint = new Point(firstPoint.x,
firstPoint.y + 0.5 * (secondPoint.y - firstPoint.y));
Scalar lineColor = new Scalar(255, 0, 0, 255);
int lineWidth = 3;
Scalar textColor = new Scalar(255, 0, 0, 255);
//height of bounce = BattHeight IRL / battHeihgt Pixel * line Height Pixel
double lineHeightCm = (4.65 / battHeight) * findHeight(yBlack, yBlue);
Log.e("PixelBatt/PixelBounce", "BattH: " + battHeight + " find height " + String.valueOf(findHeight(xBlack, xBlue)) + "!");
Log.e("Blacky-blueY", String.valueOf(xBlue - xBlack));
Imgproc.line(sourceMat2, firstPoint, secondPoint, lineColor, lineWidth);
Imgproc.putText(sourceMat2, String.valueOf(lineHeightCm), middlePoint,
Core.FONT_HERSHEY_PLAIN, 3.5, textColor);
roiBitmap2 = Bitmap.createBitmap(sourceMat2.cols(), sourceMat2.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(sourceMat2, roiBitmap2);
TextView tvR = (TextView) findViewById(R.id.tvR);
tvR.setText("Bounce Height = " + lineHeightCm + "cm");
return roiBitmap2;
}
错误:
CvException [org.opencv.core.CvException:/build/master_pack-android/opencv/modules/java/generator/src/cpp/utils.cpp:97:error:(215)src.dims == 2 &安培;&安培; info.height ==(uint32_t)src.rows&amp;&amp; info.width ==(uint32_t)src.cols in function void Java_org_opencv_android_Utils_nMatToBitmap2(JNIEnv *,jclass,jlong,jobject,jboolean)
答案 0 :(得分:3)
无需在特定区域中找到绿色物体:您可以在整个图像上找到绿色轮廓,然后只测试相对于黑色矩形的坐标。这样的事情:
首先 - 找到黑色矩形。
Rect blackRect = findBlackRect();
然后找到所有绿色物体的轮廓(与找到黑色的方式相同):
// find green contours
List<MatOfPoint> greenContours = new ArrayList<>();
Imgproc.findContours(roiMat, greenContours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
然后测试黑色矩形下面的绿色轮廓(具有更大的Y坐标)
// find appropriate bounding rectangles
for (MatOfPoint contour : greenContours) {
MatOfPoint2f areaPoints = new MatOfPoint2f(contour.toArray());
RotatedRect boundingRect = Imgproc.minAreaRect(areaPoints);
Point rotated_rect_points[] = new Point[4];
boundingRect.points(rotated_rect_points);
Rect rect = Imgproc.boundingRect(new MatOfPoint(rotated_rect_points));
// test top left Y coord of bounding rectangle of green contour grater than
// Y coord of top left of black rectangle
if (rect.tl().y > blackRect.tl().y) {
// that is green contour under black rectangle
// just draw it
Imgproc.rectangle(sourceMat, rect.tl(), rect.br(), green, 3);
}
}
等等......