【问题标题】:Open CV Code - Can someone help me understand what the code is doingOpencv 代码 - 有人可以帮我理解代码在做什么吗
【发布时间】:2015-06-28 12:47:31
【问题描述】:

我正在研究 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));
    }

【问题讨论】:

    标签: android opencv comments


    【解决方案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));
        }
    

    【讨论】:

      【解决方案2】:

      对于任何对“mDetector.process(mRgba)”方法的作用感兴趣的人,以下可能会有用。

      作为另一个答案的回顾,当用户触摸一个区域时,程序会检测他们所触摸区域的颜色。

      每次新的相机帧到达时,程序都会检查是否选择了颜色,如果是,则调用方法“mDetector.process(mRgba)”来处理帧。

      此方法在下面注释,但高级步骤是:

      • 缩小图片尺寸
      • 过滤掉所有不是我们正在寻找的颜色的东西
      • 增强图像的其余部分,以便更轻松地检测边缘或轮廓
      • 找到剩余颜色“斑点”的轮廓(轮廓或边缘)
      • 过滤掉任何太小而无法感兴趣的内容
      • 返回剩余斑点的列表,或更准确地说,返回作为剩余斑点轮廓的轮廓列表

      注释代码(Android):

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-26
        • 2021-12-24
        • 1970-01-01
        • 1970-01-01
        • 2020-11-03
        相关资源
        最近更新 更多