过滤掉其他对象--Android Open CV库

时间:2014-09-16 07:03:34

标签: android opencv

我正在尝试识别行人交通信号。我正在将图像转换为HSV色彩空间,然后应用范围内功能只获得绿灯。这是我的原始图像 enter image description here

这是我的代码..

  public void onManagerConnected(int status) {
switch (status) {
    case LoaderCallbackInterface.SUCCESS:
        {
            Log.i(TAG, "OpenCV loaded successfully...................");
            Mat img = null;
            try {
                img = Utils.loadResource(getBaseContext(), R.drawable.glarrygreen, Highgui.CV_LOAD_IMAGE_COLOR);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            Mat mHSV = new Mat();
            Mat mRgba2 = new Mat();
            Mat mHSVThreshed = new Mat();
            Imgproc.cvtColor(img, mHSV, Imgproc.COLOR_BGR2HSV, 3);
            //This works for red lights
            Core.inRange(mHSV, new Scalar(0, 64, 200), new Scalar(69, 255, 255), mHSVThreshed);
            //this works for green lights
            Core.inRange(mHSV, new Scalar(85, 64, 200), new Scalar(170, 255, 255),

                mHSVThreshed);
            List < MatOfPoint > contours = new ArrayList < MatOfPoint > ();
            Mat hierarchy = new Mat();
            Imgproc.findContours(mRgba2, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
            double maxArea = -1;
            int maxAreaIdx = -1;
            for (int idx = 0; idx < contours.size(); idx++) {
                Mat contour = contours.get(idx);
                double contourarea = Imgproc.contourArea(contour);
                if (contourarea > maxArea) {

                    maxArea = contourarea;
                    maxAreaIdx = idx;


                }
            }
            Imgproc.cvtColor(mHSVThreshed, img, Imgproc.COLOR_GRAY2BGR, 0);
            Imgproc.cvtColor(img, mRgba2, Imgproc.COLOR_BGR2RGBA, 0);
            Bitmap bmp = Bitmap.createBitmap(img.cols(), img.rows(), Bitmap.Config.ARGB_8888);
            Utils.matToBitmap(mRgba2, bmp);
        }
}

} 这是我的输出图像enter image description here

现在我需要滤除场景中的其他绿色信号。我该怎么做?如何在场景中获得最突出的绿色信号。

编辑1: 我正在尝试使用findCountours()方法,获取轮廓列表,迭代结果并获得最大值,然后仅显示最大轮廓。如何去除较小的轮廓?

2 个答案:

答案 0 :(得分:1)

您可以尝试使用非最大值抑制算法过滤二进制图像。 这是一个Java Demo of non-max suppression。 注意,NMS算法可以使用形态函数(Erosion and Dilatation)进行编码。

编辑似乎opencv已经具有以下原型的NMS功能:

void nonMaximaSuppression(const Mat& src, const int sz, Mat& dst, const Mat mask)

EDIT2 来自opencv doc:对于src中的每个可能的(sz x sz)区域,一个元素是src的局部最大值,如果它严格大于与给定相交的窗口的所有其他元素元件。

尝试50x50补丁(sz:= 50)

FYI该方法源于以下论文:A。Neubeck和L. Van Gool。 “有效的非最大抑制”,ICPR 2006

答案 1 :(得分:0)

我终于通过使用findCountours()和drawContours()方法

来完成这项工作

这是它的工作原理,

Imgproc.GaussianBlur(mHSVThreshed, mHSVThreshed, new Size(5, 5), 5);
                           Imgproc.findContours(mHSVThreshed, contours,newcont, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
                           double maxArea = -1;
                           int maxAreaIdx = -1;
                           for (int idx = 0; idx < contours.size(); idx++) {
                               Mat contour = contours.get(idx);
                               double contourarea = Imgproc.contourArea(contour);
                               if (contourarea > maxArea) {
                                   maxArea = contourarea;
                                   maxAreaIdx = idx;
                               }
                           }
                          Imgproc.drawContours(img, contours, maxAreaIdx, new Scalar(120, 255, 120), 1);

                        Bitmap bmp = Bitmap.createBitmap(img.cols(), img.rows(), Bitmap.Config.ARGB_8888);

                        Scalar c = new Scalar(255, 0, 0, 255);  
                        Core.putText(img, VAL, new Point(100,100), 3, 1, c, 2); 
                        Imgproc.erode(mHSVThreshed, mHSVThreshed, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(1.5,1.5)));  
                        Utils.matToBitmap(img, bmp);