2015-04-21 41 views
1

我正在使用OpenCV顏色blob,並且正在審查代碼。我需要一些幫助來理解代碼的作用,以便我可以進一步研究它並幫助進一步整合。是否有人可以幫助我理解/評論代碼,以便更容易地進行交流。打開簡歷代碼 - 有人可以幫我理解代碼在做什麼

public boolean onTouch(View v, MotionEvent event) { 
     int cols = mRgba.cols(); //get resolution of display 
     int rows = mRgba.rows(); // get resolution of display 

     int xOffset = (mOpenCvCameraView.getWidth() - cols)/2; //get resolution of display 
     int yOffset = (mOpenCvCameraView.getHeight() - rows)/2; // get resolution of display 

     int x = (int)event.getX() - xOffset; // get resolution of display 
     int y = (int)event.getY() - yOffset; //get resolution of display 

     Log.i(TAG, "Touch image coordinates: (" + x + ", " + y + ")"); 

     if ((x < 0) || (y < 0) || (x > cols) || (y > rows)) return false; 

     Rect touchedRect = new Rect(); 

     touchedRect.x = (x>4) ? x-4 : 0; 
     touchedRect.y = (y>4) ? y-4 : 0; 

     touchedRect.width = (x+4 < cols) ? x + 4 - touchedRect.x : cols - touchedRect.x; 
     touchedRect.height = (y+4 < rows) ? y + 4 - touchedRect.y : rows - touchedRect.y; 

     Mat touchedRegionRgba = mRgba.submat(touchedRect); 

     Mat touchedRegionHsv = new Mat(); 
     Imgproc.cvtColor(touchedRegionRgba, touchedRegionHsv, Imgproc.COLOR_RGB2HSV_FULL); 

     // Calculate average color of touched region 
     mBlobColorHsv = Core.sumElems(touchedRegionHsv); 
     int pointCount = touchedRect.width*touchedRect.height; 
     for (int i = 0; i < mBlobColorHsv.val.length; i++) 
      mBlobColorHsv.val[i] /= pointCount; 

     //converts scalar to hsv to RGB 
     mBlobColorRgba = converScalarHsv2Rgba(mBlobColorHsv); 

     Log.i(TAG, "Touched rgba color: (" + mBlobColorRgba.val[0] + ", " + mBlobColorRgba.val[1] + 
       ", " + mBlobColorRgba.val[2] + ", " + mBlobColorRgba.val[3] + ")"); 

     mDetector.setHsvColor(mBlobColorHsv); 

     Imgproc.resize(mDetector.getSpectrum(), mSpectrum, SPECTRUM_SIZE); 

     mIsColorSelected = true; 

     touchedRegionRgba.release(); 
     touchedRegionHsv.release(); 

     return false; // don't need subsequent touch events 
    } 

    public Mat onCameraFrame(CvCameraViewFrame inputFrame) { 
     mRgba = inputFrame.rgba(); 

     if (mIsColorSelected) { 
      mDetector.process(mRgba); 
      List<MatOfPoint> contours = mDetector.getContours(); 
      Log.e(TAG, "Contours count: " + contours.size()); 
      Imgproc.drawContours(mRgba, contours, -1, CONTOUR_COLOR); 

      Mat colorLabel = mRgba.submat(4, 68, 4, 68); 
      colorLabel.setTo(mBlobColorRgba); 

      Mat spectrumLabel = mRgba.submat(4, 4 + mSpectrum.rows(), 70, 70 + mSpectrum.cols()); 
      mSpectrum.copyTo(spectrumLabel); 
     } 

     return mRgba; 
    } 
//final conversion 
    private Scalar converScalarHsv2Rgba(Scalar hsvColor) { 
     Mat pointMatRgba = new Mat(); 
     Mat pointMatHsv = new Mat(1, 1, CvType.CV_8UC3, hsvColor); 
     Imgproc.cvtColor(pointMatHsv, pointMatRgba, Imgproc.COLOR_HSV2RGB_FULL, 4); 

     return new Scalar(pointMatRgba.get(0, 0)); 
    } 

回答

1

我已經通過並且盡我所能地評論了代碼,儘管我認爲這是相當自我記錄。 通常,此代碼會從用戶觸摸繪製的座標中獲取圖像。最後在轉換色彩空間 並調整它的大小頻譜

// When a motion event happens (someone touches the device) 
public boolean onTouch(View v, MotionEvent event) { 
    int cols = mRgba.cols(); //get resolution of display 
    int rows = mRgba.rows(); // get resolution of display 

    int xOffset = (mOpenCvCameraView.getWidth() - cols)/2; //get resolution of display 
    int yOffset = (mOpenCvCameraView.getHeight() - rows)/2; // get resolution of display 

    int x = (int)event.getX() - xOffset; // get resolution of display 
    int y = (int)event.getY() - yOffset; //get resolution of display 

     //The place where the screen was touched 
    Log.i(TAG, "Touch image coordinates: (" + x + ", " + y + ")"); 
    // ensure it is within the screen. 
    if ((x < 0) || (y < 0) || (x > cols) || (y > rows)) return false; 

    Rect touchedRect = new Rect(); 

    //Ensure it is a multiple of 4 
    touchedRect.x = (x>4) ? x-4 : 0; 
    touchedRect.y = (y>4) ? y-4 : 0; 

    // If x+4 < cols then ?"" else :"" 
    touchedRect.width = (x+4 < cols) ? x + 4 - touchedRect.x : cols - touchedRect.x; 
    touchedRect.height = (y+4 < rows) ? y + 4 - touchedRect.y : rows - touchedRect.y; 

    create a touched regionmat from the image created from the touches 
    Mat touchedRegionRgba = mRgba.submat(touchedRect); 

    //Convert the new mat to HSV colour space 
    Mat touchedRegionHsv = new Mat(); 
    Imgproc.cvtColor(touchedRegionRgba, touchedRegionHsv, Imgproc.COLOR_RGB2HSV_FULL); 

    // Calculate average color of touched region 
    mBlobColorHsv = Core.sumElems(touchedRegionHsv); 
    int pointCount = touchedRect.width*touchedRect.height; 
    for (int i = 0; i < mBlobColorHsv.val.length; i++) 
     mBlobColorHsv.val[i] /= pointCount; 

    //converts scalar to hsv to RGB 
    mBlobColorRgba = converScalarHsv2Rgba(mBlobColorHsv); 

    Log.i(TAG, "Touched rgba color: (" + mBlobColorRgba.val[0] + ", " + mBlobColorRgba.val[1] + 
      ", " + mBlobColorRgba.val[2] + ", " + mBlobColorRgba.val[3] + ")"); 

    mDetector.setHsvColor(mBlobColorHsv); 

    // Resize the image to specture size 
    Imgproc.resize(mDetector.getSpectrum(), mSpectrum, SPECTRUM_SIZE); 

    mIsColorSelected = true; 

    // Release all mats 
    touchedRegionRgba.release(); 
    touchedRegionHsv.release(); 

    return false; // don't need subsequent touch events 
} 

public Mat onCameraFrame(CvCameraViewFrame inputFrame) { 
    mRgba = inputFrame.rgba(); 

    if (mIsColorSelected) { 
     mDetector.process(mRgba); 
     List<MatOfPoint> contours = mDetector.getContours(); 
     Log.e(TAG, "Contours count: " + contours.size()); 
     Imgproc.drawContours(mRgba, contours, -1, CONTOUR_COLOR); 

     Mat colorLabel = mRgba.submat(4, 68, 4, 68); 
     colorLabel.setTo(mBlobColorRgba); 

     Mat spectrumLabel = mRgba.submat(4, 4 + mSpectrum.rows(), 70, 70 + mSpectrum.cols()); 
     mSpectrum.copyTo(spectrumLabel); 
    } 

    return mRgba; 
} 
//final conversion 
    private Scalar converScalarHsv2Rgba(Scalar hsvColor) { 
     Mat pointMatRgba = new Mat(); 
     Mat pointMatHsv = new Mat(1, 1, CvType.CV_8UC3, hsvColor); 
     Imgproc.cvtColor(pointMatHsv, pointMatRgba, Imgproc.COLOR_HSV2RGB_FULL, 4); 

     return new Scalar(pointMatRgba.get(0, 0)); 
    } 
+1

謝謝爲了幫助,非常感謝。 –

0

對於任何人誰也有興趣在什麼樣的方法「mDetector.process(mRgba)」做下面可能是有用的。

作爲對其他答案的回顧,當用戶觸摸某個區域時,程序會檢測到他們觸摸的區域的顏色。

每當新的相機幀到達時,程序檢查是否選擇了顏色,如果是,則調用方法'mDetector.process(mRgba)'來處理該幀。

這種方法在下面評論,但高層次的步驟是:

  • 降低圖像
  • 過濾掉一切,是不是我們要找的
  • 提高剩餘顏色的大小部分圖像使其更易於檢測邊緣或輪廓
  • 找到其餘顏色的「斑點」的輪廓(輪廓或邊緣)
  • 過濾掉任何太小的t Ø感興趣
  • 返回剩餘斑點的列表,或輪廓這是其餘的斑點

註釋代碼(安卓)的輪廓更加精確列表:

public void process(Mat rgbaImage) { 

     //Pyramid Down - this downsizes the image and looses some resolution 
     //See: http://docs.opencv.org/2.4/doc/tutorials/imgproc/pyramids/pyramids.html 
     Imgproc.pyrDown(rgbaImage, mPyrDownMat); 
     Imgproc.pyrDown(mPyrDownMat, mPyrDownMat); 

     //Convert color scheme to HSV - this means that a color can be 
     //identified with a single value, the hue, instead of three values 
     Imgproc.cvtColor(mPyrDownMat, mHsvMat, Imgproc.COLOR_RGB2HSV_FULL); 

     //This creates a new image with only the color values that are wihtin 
     //the lower and upper thresholds set in mLowerBound and mUpperBound. These 
     //values were calculated when the method 'setHsvColor' was called with the 
     //color of the object that the user touched on the screen. 
     //So you effectively get an image with just the red or just the blue or whatever 
     //the color of the blob that the user selected was. Note that if there are multiple 
     //blobs or objects with this color you will get them all. You can see this quite easily 
     //with a simple test of the app with a couple of similar colored objects. 
     Core.inRange(mHsvMat, mLowerBound, mUpperBound, mMask); 

     //dilate effectively emphasises the brighter colors, so making them bigger within the image 
     //In this case it should be the chosen color which is emphasised against the 
     //darker (black) background. 
     //See:http://docs.opencv.org/2.4/doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.html 
     Imgproc.dilate(mMask, mDilatedMask, new Mat()); 

     List<MatOfPoint> contours = new ArrayList<MatOfPoint>(); 

     //Finds the contours which in this case means the edge of the color blobs 
     Imgproc.findContours(mDilatedMask, contours, mHierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); 

     // Find max contour area 
     //This is actually refering to the area enclosed by a contour. For this to work it is important 
     //that the contour be closed, so if this is not the case some objects may be missed here. 
     double maxArea = 0; 
     Iterator<MatOfPoint> each = contours.iterator(); 
     while (each.hasNext()) { 
      MatOfPoint wrapper = each.next(); 
      double area = Imgproc.contourArea(wrapper); 
      if (area > maxArea) 
       maxArea = area; 
     } 

     // Filter contours by area and resize to fit the original image size 
     //Here we are simply discrading any contours that are below the min size that was 
     //set in the method 'setMinContourArea' or the default if it was not set. In other 
     //words discrading any small object detected. 
     mContours.clear(); 
     each = contours.iterator(); 
     while (each.hasNext()) { 
      MatOfPoint contour = each.next(); 
      if (Imgproc.contourArea(contour) > mMinContourArea*maxArea) { 
       Core.multiply(contour, new Scalar(4,4), contour); 
       mContours.add(contour); 
      } 
     } 
    } 

    //Now we return the list of contours - each contour is a closed area that is 
    //colored in whatever color the user selected when they touched the object. 
    //This color, as a reminder, was set by a call to 'setHsvColor'. 
    public List<MatOfPoint> getContours() { 
     return mContours; 
    } 
} 
相關問題