2017-08-17 671 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); 
    } 
} 

等等......