2017-08-17 79 views
0

我现在有这个图片:OpenCV的,Java的:颜色检测某一指定区域

image

我设法检测的黑色物体。现在我想检测绿色物体,但我只希望应用程序在黑色物体的下方寻找以下的绿色物体。我已经有了检测绿色磁带及其工作的代码。只需要将其设置为仅在黑色物体下面的区域中。

生成的图像仍然应该是这样的: enter image description here

P.S一些变量被命名为“蓝色”,放心使用其绿标量值。

代码:

//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 && info.width == (uint32_t)src.cols in function void Java_org_opencv_android_Utils_nMatToBitmap2(JNIEnv*, jclass, jlong, jobject, jboolean)

+2

那么究竟是什么问题,错误或发现绿色物体? –

+0

我遇到的问题是让应用程序只在黑色物体下面寻找绿色物体,目前它正在搜索我不想要的整个图像。我没有发现绿色/黑色的问题,我只想在特定区域检测绿色。假设有2个绿色物体,一个在黑色物体上方一个下方。我只想要黑色物体被检测到的绿色 – Tix

+0

您可以在图像的_below_部分运行检测。 –

回答

1

有没有需要找到特定区域绿色物体:你可以找到整个图像上的绿色轮廓,然后只是测试它的坐标相对黑色的矩形。类似的东西:

起初 - 找到黑色的矩形。 (因为你会发现黑色同样的方式)

Rect blackRect = findBlackRect(); 

然后找到所有绿色物体的轮廓:

// find green contours 
List<MatOfPoint> greenContours = new ArrayList<>(); 
Imgproc.findContours(roiMat, greenContours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE); 

然后测试绿色轮廓铺设在下面的黑色矩形的是什么(有擦菜板Ÿ坐标)

// 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); 
    } 
} 

等等......