1

I am fairly new to openCV on Android and I am using the ColorBlobDetector class from the OpenCV Samples to detect traffic light blobs such as Red, Green Amber. I cant seem to understand the use of mColorRadius. I also cannot figure out where to compare colors to find the appropriate blob I am looking for.

Here's my code

PS: I even tried entering values for mLowerBound and mUpperBound, but it kept highlighting black blobs.

package edu.csueb.ilab.blindbike.lightdetection;

import android.os.Environment;
import android.util.Log;

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.highgui.Highgui;
import org.opencv.imgproc.Imgproc;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

// Lower and Upper bounds for range checking in HSV color space
private Scalar mLowerBound = new Scalar(0);     //for blue 120,100,100 Current: 176,255,244 ::perfect working Green 70,20,100
// for flouracent green light 57,255,20
private Scalar mUpperBound = new Scalar(0);     // for blue 179,255,255 , blue cap 28,28,37 Current: 177,255,252:: perfect working Green 85,35,125
// for flouracent green light 57,255,200
// for gray signs 76,55,28
// for gray signs 89,62,33 ,blue cap 80,109,149
// Minimum contour area in percent for contours filtering
private static double mMinContourArea = 0.01; //<></>ried 0.4
// Color radius for range checking in HSV color space
private Scalar mColorRadius = new Scalar(25,50,50,0);   //initial val 25,50,50,0 //214,55,52,0 for the blue cap
private Mat mSpectrum = new Mat();                      //
private List<MatOfPoint> mContours = new ArrayList<MatOfPoint>();

// Cache
Mat mPyrDownMat = new Mat();
Mat mHsvMat = new Mat();
Mat mMask = new Mat();
Mat mDilatedMask = new Mat();
Mat mHierarchy = new Mat();

SimpleDateFormat df= new SimpleDateFormat("yyyy_MM_dd_HH_mm_yyyy");

public void setColorRadius(Scalar radius) {
    mColorRadius = radius;
}

public void setHsvColor(Scalar hsvColor) {
    double minH = (hsvColor.val[0] >= mColorRadius.val[0]) ? hsvColor.val[0]-mColorRadius.val[0] : 0;
    double maxH = (hsvColor.val[0]+mColorRadius.val[0] <= 255) ? hsvColor.val[0]+mColorRadius.val[0] : 255;

    mLowerBound.val[0] = minH;
    mUpperBound.val[0] = maxH;

    mLowerBound.val[1] = hsvColor.val[1] - mColorRadius.val[1];
    mUpperBound.val[1] = hsvColor.val[1] + mColorRadius.val[1];

    mLowerBound.val[2] = hsvColor.val[2] - mColorRadius.val[2];
    mUpperBound.val[2] = hsvColor.val[2] + mColorRadius.val[2];

    mLowerBound.val[3] = 0;
    mUpperBound.val[3] = 255;

    Mat spectrumHsv = new Mat(1, (int)(maxH-minH), CvType.CV_8UC3);

    for (int j = 0; j < maxH-minH; j++) {
        byte[] tmp = {(byte)(minH+j), (byte)255, (byte)255};
        spectrumHsv.put(0, j, tmp);
    }

    Imgproc.cvtColor(spectrumHsv, mSpectrum, Imgproc.COLOR_HSV2BGR_FULL, 4); //COLOR_HSV2RGB_FULL
}

public Mat getSpectrum() {
    return mSpectrum;
}

public void setMinContourArea(double area) {
    mMinContourArea = area;
}

public void process(Mat rgbaImage) {
    Scalar colorGreen=new Scalar(0, 128, 0);


    Imgproc.pyrDown(rgbaImage, mPyrDownMat);
    Imgproc.pyrDown(mPyrDownMat, mPyrDownMat);

    Imgproc.cvtColor(mPyrDownMat, mHsvMat, Imgproc.COLOR_BGR2HSV_FULL);

    Core.inRange(mHsvMat, mLowerBound, mUpperBound, mMask);
    Imgproc.dilate(mMask, mDilatedMask, new Mat());

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

    Imgproc.findContours(mDilatedMask, contours, mHierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);

    // Find max contour area
    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
    mContours.clear();
    each = contours.iterator();
    while (each.hasNext()) {
        MatOfPoint contour = each.next();       //Current: >=50 && <200 //testig at jan 9700 || 25200
        if (Imgproc.contourArea(contour) >= 49656 || Imgproc.contourArea(contour)<53177) {  //mMinContourArea*maxArea //red 30 300-440 green 510 1600
            Core.multiply(contour, new Scalar(4,4), contour);               //Perfect working: Green 880 || 1800

            mContours.add(contour);
        }
    }

    File path =Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);

    String filename = "christ"+df.format(new Date()).toString()+".png";
    File file = new File(path, filename);
    filename = file.toString();
    Boolean save;

    MatOfPoint2f approxCurve=new MatOfPoint2f();
    for(int i=0;i<contours.size();i++)
    {
        MatOfPoint2f countour2f = new MatOfPoint2f(contours.get(i).toArray());
        double approxDistance = Imgproc.arcLength(countour2f, true)*0.02;
        Imgproc.approxPolyDP(countour2f, approxCurve, approxDistance, true);

        // Convert back to Contour
        MatOfPoint points=new MatOfPoint(approxCurve.toArray());

        //Get Bounding rect of contour
        Rect rect=Imgproc.boundingRect(points);

        //draw enclosing rectangle
        Mat ROI = rgbaImage.submat(rect.y, rect.y + rect.height, rect.x, rect.x + rect.width);

 //       save= Highgui.imwrite(filename,ROI);
 //       if (save == true)
 //           Log.i("Save Status", "SUCCESS writing image to external storage");
 //       else
  //          Log.i("Save Status", "Fail writing image to external storage");

        Core.rectangle(rgbaImage, new Point(rect.x,rect.y), new Point(rect.x+rect.width,rect.y+rect.height),new Scalar(255,225,0,0),3);
    }


}

public List<MatOfPoint> getContours() {
    return mContours;
}
}
Misa Lazovic
  • 2,805
  • 10
  • 32
  • 38
ChristoL
  • 27
  • 3
  • Have a look at [this](http://stackoverflow.com/questions/31460267/python-opencv-color-tracking/31465462#31465462) as a starting point... might help! – Miki Jan 31 '16 at 01:25
  • Thanks Miki! I do have the ranges that I am looking for which I extracted from training images using GIMP. But I cannot figure out which parameters do I play with to compare the color values. I Initially tried setting values for mLowerBound and mUpperBound in setHsvColor() but didnt seem to work. – ChristoL Jan 31 '16 at 01:44
  • I don't follow. Btw, your `mColorRadius` is basically the `sensitivity` parameter in the linked answer. – Miki Jan 31 '16 at 01:47
  • ohh!!!! Thats where the sensitivity parameter goes!! Oh now I seem to get it. I did use training images and photoshop to extract HSV values for Red light which range from HSV(129,2.55,209) to HSV(159,2.55,209). but i couldn't figure out where to plug these values in to get the red color. Initially i initialized mLowerBound and mUpperBound as the above ranges but it detected black color. Here is the sampled Image [link]http://imgur.com/xAZ0kHo – ChristoL Jan 31 '16 at 02:13
  • That doesn't seem _red_ color... See [here](http://stackoverflow.com/a/32523532/5008845). Also, go back to the first answer I linked to know about the ranges in HSV. 2.55 is a very very low saturation, it's probably wrong. Also, you need to give a broader range for S and V channels. – Miki Jan 31 '16 at 02:17
  • Here is the image that I had sampled http://imgur.com/xAZ0kHo – ChristoL Jan 31 '16 at 02:19
  • These ranges works pretty good: `lower(170, 230, 230)` and `upper(180, 255, 255)` – Miki Jan 31 '16 at 02:24
  • Awesome! U were right! My ranges were wrong. These r the new ranges I found HSV(171,249.9,234.6) to (172.5,255,255). Yup Just like the ones you specified. The Other question is where does these values go? Do I need to tamper with setHsvColor() function?? – ChristoL Jan 31 '16 at 02:41
  • You need these ranges in the `inRange` function. If you need to call setHsvColor first, just pass `hsvColor` something like `(175,240,240)`, and restrict `mColorRadius ` to something like `(10,15,15)` – Miki Jan 31 '16 at 02:45
  • Hey! I tried it out! You were right @Miki ...It does work. I plugged the values in setHSVColor and the detection is accurate. THank you so much!! – ChristoL Feb 09 '16 at 07:18

0 Answers0