【问题标题】:OpenCV color detection in yellow黄色的 OpenCV 颜色检测
【发布时间】:2014-03-15 14:42:57
【问题描述】:

这是一个来自 OpenCV ColorBlobDetectionActivity.java 示例的程序,我尝试对其进行修改,以便在触摸屏幕时检测黄色物体,但即使我将颜色标量指定为黄色,它也始终只检测黑色物体.我已将“NOTICE”的 cmets 放在我认为相关的地方。

 package com.example.road_guiding;

import java.util.List;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;



public class ColorBlobDetectionActivity extends Activity implements View.OnTouchListener, CameraBridgeViewBase.CvCameraViewListener2 {
//  private static final String TAG = "OCVSample::Activity";
    private Scalar CONTOUR_COLOR;
    private Scalar mBlobColorHsv;
    private Scalar mBlobColorRgba;

    //NOTICE
    private Scalar temp;    

    private ColorBlobDetector mDetector;
    private boolean mIsColorSelected = false;
    private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
        public void onManagerConnected(int paramAnonymousInt) {
            switch (paramAnonymousInt) {
            default:
                super.onManagerConnected(paramAnonymousInt);
//              Log.i("OCVSample::Activity", "OpenCV loaded successfully");
                ColorBlobDetectionActivity.this.mOpenCvCameraView.enableView();
                ColorBlobDetectionActivity.this.mOpenCvCameraView.setOnTouchListener(ColorBlobDetectionActivity.this);

                return;
            }

        }
    };
    private CameraBridgeViewBase mOpenCvCameraView;
    private Mat mRgba;
//  private Size SPECTRUM_SIZE;
//  private Mat mSpectrum;

    public ColorBlobDetectionActivity() {
        Log.i("OCVSample::Activity", "Instantiated new " + getClass());
    }

    private Scalar converScalarHsv2Rgba(Scalar paramScalar) {
        Mat localMat = new Mat();
        Imgproc.cvtColor(new Mat(1, 1, CvType.CV_8UC3, paramScalar), localMat, 71, 4);
        return new Scalar(localMat.get(0, 0));
    }

    public Mat onCameraFrame( CameraBridgeViewBase.CvCameraViewFrame paramCvCameraViewFrame) {
        this.mRgba = paramCvCameraViewFrame.rgba(); // mRbga = input frame with color

        if (this.mIsColorSelected) {
            this.mDetector.process(this.mRgba);

            //contour info is ready in detector
            List colorContour = this.mDetector.getContours();
//          Log.e("OCVSample::Activity", "Contours count: " + localList.size());
            Imgproc.drawContours(this.mRgba, colorContour, -1, this.CONTOUR_COLOR); //draw contour around detected area     

            this.mRgba.submat(4, 68, 4, 68).setTo(this.mBlobColorRgba);

//          Producing spectrum
//          Mat localMat = this.mRgba.submat(4, 4 + this.mSpectrum.rows(), 70, 70 + this.mSpectrum.cols());
//          this.mSpectrum.copyTo(localMat);
        }
        return this.mRgba;
    }

    public void onCameraViewStarted(int paramInt1, int paramInt2) {
        this.mRgba = new Mat(paramInt2, paramInt1, CvType.CV_8UC4); //width - - the width of the frames that will be delivered
        this.mDetector = new ColorBlobDetector();
        this.mBlobColorRgba = new Scalar(255.0);
        this.mBlobColorHsv = new Scalar(255.0);
        this.CONTOUR_COLOR = new Scalar(255.0, 0.0, 0.0, 255.0); //Specfiy the color of contour

        //NOTICE
        this.temp = new Scalar (237.0, 169.0, 50.0, 255.0); 

        //yellow to be used:
//      this.mBlobColorRgba.val[0] = 237;
//      this.mBlobColorRgba.val[1] = 169;   
//      this.mBlobColorRgba.val[2] = 50;
//      this.mBlobColorRgba.val[3] = 255;   


//      this.mSpectrum = new Mat();
//      this.SPECTRUM_SIZE = new Size(200.0, 64.0);
    }

    public void onCreate(Bundle paramBundle) {
//      Log.i("OCVSample::Activity", "called onCreate");
        super.onCreate(paramBundle);
//      requestWindowFeature(1); // do not show app title
//      getWindow().addFlags(128);
        setContentView(R.layout.activity_color_blob_detection);
        this.mOpenCvCameraView = ((CameraBridgeViewBase) findViewById(R.id.HelloOpenCvView));
        this.mOpenCvCameraView.setCvCameraViewListener(this);
    }

    public boolean onTouch(View paramView, MotionEvent paramMotionEvent)
      {
        int cameraViewWidth = this.mRgba.cols(); //  cameraViewWidth = i
        int cameraViewHeight = this.mRgba.rows(); // cameraViewHeight = j
        int xOffset = (this.mOpenCvCameraView.getWidth() - cameraViewWidth) / 2;
        int yOffset = (this.mOpenCvCameraView.getHeight() - cameraViewHeight) / 2;
        int touchX = (int)paramMotionEvent.getX() - xOffset;
        int touchY = (int)paramMotionEvent.getY() - yOffset;

        //      Log.i("OCVSample::Activity", "Touch image coordinates: (" + n = touchX + ", " + i1=touchY + ")");
        if ((touchX < 0) || (touchY < 0) || (touchX > cameraViewWidth) || (touchY > cameraViewHeight)) {
          return false;
        }

        Rect touchedRect = new Rect();
        if (touchX > 4) {
          touchedRect.x = touchX - 4;
          touchedRect.y = touchY - 4;
          touchedRect.width = touchX + 4 - touchedRect.x;
        }

        for (int i5 = touchY + 4 - touchedRect.y;; i5 = cameraViewHeight - touchedRect.y) {
            touchedRect.height = i5;

//          Mat touchedRegionRgba = this.mRgba.submat(touchedRect);
            Mat touchedRegionRgba = new Mat();

            //NOTICE
            Imgproc.cvtColor(new Mat(1, 1, CvType.CV_8UC3, temp), touchedRegionRgba, 71, 0);

            Mat touchedRegionHsv = new Mat();

            Imgproc.cvtColor(touchedRegionRgba, touchedRegionHsv, Imgproc.COLOR_RGB2HSV_FULL); //67
            this.mBlobColorHsv = Core.sumElems(touchedRegionHsv); //calculate average color of touched region
            int pixelCount = touchedRect.width * touchedRect.height;
            for (int i = 0; i < this.mBlobColorHsv.val.length; i++) {
                double[] arrayOfDouble = this.mBlobColorHsv.val;
                arrayOfDouble[i] /= pixelCount;
          }
            touchedRegionRgba.release();
            touchedRegionHsv.release();

        break;
        }

        this.mBlobColorRgba = converScalarHsv2Rgba(this.mBlobColorHsv);

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

        this.mDetector.setHsvColor(this.mBlobColorHsv);

//      Imgproc.resize(this.mDetector.getSpectrum(), this.mSpectrum, this.SPECTRUM_SIZE);
        this.mIsColorSelected = true;
        return false;
      }

    public void onDestroy() {
        super.onDestroy();
        if (this.mOpenCvCameraView != null) {
            this.mOpenCvCameraView.disableView();
        }
    }

    public void onPause() {
        super.onPause();
        if (this.mOpenCvCameraView != null) {
            this.mOpenCvCameraView.disableView();
        }
    }

    public void onResume() {
        super.onResume();
        OpenCVLoader.initAsync("2.4.3", this, this.mLoaderCallback);
    }

    public void onCameraViewStopped() {
        this.mRgba.release();
    }
}

任何帮助将不胜感激,谢谢!

【问题讨论】:

    标签: java android opencv image-processing colors


    【解决方案1】:

    抱歉,我不懂 Java,但我可以建议检测“黄色”颜色的一般逻辑。您应该将RGB 图像转换为YUV 图像,然后均衡Y 通道。由于 Y 通道用于亮度,因此您可以通过这样做来减少照明变化的影响。

    -然后将您的图像从YUV转换回RGB - 现在将图像转换为HSV。 - 现在尝试只计算那些可能代表“黄色”颜色的像素。为此,请使用以下条件:

    1. 像素应具有S&gt;0(或其他接近 0 的值)以消除在计算中造成问题的白色像素。
    2. 像素应具有V&gt;0 以移除 V=0 的“黑色像素”
    3. 如果H&gt; 22 &amp;&amp; H&lt;37 则将yellowPixelCount 增加1。

    -因此,按照上述过程,您可以计算图像中的“黄色”像素。而且,如果计数大于阈值,那么您可以预测它是“黄色”颜色。

    PS:不要忘记计算满足条件1和2的像素总数,以便您可以使用该值来找到黄色分量的百分比来预测图像是否具有黄色或不是。

    if (condition 1 & 2 satisfied)
    {
        totalPixelCount++;
        if(condition 3 satisfied)
        {
            yellowPixelCount
        }
    }
    
    % of yellow componet = yellowPixelCount/totalPixelCount*100
    

    【讨论】:

    • 谢谢skm!我会试试你的方法,非常感谢你的建议!
    猜你喜欢
    • 2012-02-29
    • 2019-09-17
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 2021-08-20
    • 2018-04-22
    • 1970-01-01
    • 2016-10-17
    相关资源
    最近更新 更多