6

I have try below code using OpenCV functions cvtColor,Canny and HoughLinesP but not able to get accurate result or not work in some cases.

private boolean opencvProcessCount(Uri picFileUri) {
hairCount = 0;
totalC = 0;
//Log.e(">>>>>>>>","count " + picFileUri);
try {
    InputStream iStream = getContentResolver().openInputStream(picFileUri);
    byte[] im = getBytes(iStream);
    BitmapFactory.Options opt = new BitmapFactory.Options();
    opt.inDither = true;
    opt.inPreferredConfig = Bitmap.Config.ARGB_8888;
    Bitmap image = BitmapFactory.decodeByteArray(im, 0, im.length);

    Mat mYuv = new Mat();
    Utils.bitmapToMat(image, mYuv);
    Mat mRgba = new Mat();
    Imgproc.cvtColor(mYuv, mRgba, Imgproc.COLOR_RGB2GRAY, 4);
    Imgproc.Canny(mRgba, mRgba, 80, 90);
    Mat lines = new Mat();
    int threshold = 80;
    int minLineSize = 30;
    int lineGap = 100;

    Imgproc.HoughLinesP(mRgba, lines, 1, Math.PI/180, threshold, minLineSize, lineGap);

    for (int x = 0; x < lines.rows(); x++)
    {
        double[] vec = lines.get(x, 0);
        double x1 = vec[0],
                y1 = vec[1],
                x2 = vec[2],
                y2 = vec[3];
        Point start = new Point(x1, y1);
        Point end = new Point(x2, y2);
        double dx = x1 - x2;
        double dy = y1 - y2;

        double dist = Math.sqrt (dx*dx + dy*dy);
        totalC ++;
        Log.e(">>>>>>>>","dist " + dist);
        if(dist>300.d)
        {
            hairCount ++;
            // Log.e(">>>>>>>>","count " + x);
            Imgproc.line(mRgba, start, end, new Scalar(0,255, 0, 255),5);// here initimg is the original image.
        }// show those lines that have length greater than 300


    }

    Log.e(">>>>>>>>",totalC+" out hairCount " + hairCount);

    // Imgproc.
} catch (Throwable e) {
    // Log.e(">>>>>>>>","count " + e.getMessage());
    e.printStackTrace();
}
return false;
}

Below are sample images to count hair :

enter image description here

enter image description here

Haresh Chhelana
  • 24,720
  • 5
  • 57
  • 67
  • Hi, could you provide a minimalistic code? (No Bitmap, no global member variables, etc.) This will help others to focus more on problem. – saurabheights Oct 11 '16 at 17:26
  • 1
    and maybe some images from your pre-processing steps, like canny and also the found hough lines? – PSchn Oct 11 '16 at 20:35
  • @saurabheights,Here i have added actual code so anyone can identified my problem or wrong implementation if i did. – Haresh Chhelana Oct 12 '16 at 04:47
  • 2
    @HareshChhelana: Here are my thoughts: 1. Save Canny output. 2. Put temporary constraint of only black hairs(no brunette, no blonde). 3. Refine Canny output to remove outliers before running Hough. 4. No preprocessing done: removal of reflection and seperating skin from hair using Hue/Saturation. 5. Remove the second test picture, the occlusion will only add the complexity in terms of how to process after canny. Instead, use a larger dataset of images similar to first test picture. 6. Once hough transform gives enough lines, use smarter logic to find which lines forms hair. – saurabheights Oct 12 '16 at 13:23
  • @saurabheights,If possible can you please share some code ? – Haresh Chhelana Oct 12 '16 at 13:25
  • @HareshChhelana I wont be able to give more time soon, hence I wrote my initial analysis as a comment, in case you find it helpful. My updated code is here: Here is my updated code: https://drive.google.com/file/d/0B6DvvsgRzPZXeUFLSmhYNGJENU0/view?usp=sharing. Ignore the thresholding part as it needs more work. P.S.: passing the image name as argument helps in running the same code over a lot of images using bash find and exec. – saurabheights Oct 12 '16 at 13:27
  • I know it's not much, but just wanted to not let the partial work to go to waste. I am also working on a HSV analyzer to solve problems like this(Separate hair and skin), but it needs small work done. I will update soon. – saurabheights Oct 12 '16 at 13:34
  • @saurabheights thanks you so much such for share this will try and let you know if more help need to achieve my requirement. – Haresh Chhelana Oct 12 '16 at 13:49
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/125511/discussion-between-saurabheights-and-haresh-chhelana). – saurabheights Oct 12 '16 at 14:07
  • Did this ever work? Is there a solution for this? – Orcun Jan 19 '21 at 22:13

1 Answers1

0

I think you will find this article interesting:

http://www.cs.ubc.ca/~lowe/papers/aij87.pdf

They take a 2D bitmap, apply canny edge detector and then regroup segments of the different edges based on how likely they belong to a same object - in this case hair (and give criterias for such regrouping).

I think you could use this to know how many objects there are on the image, and if the image contains only hair, then you'd have a count for hair.

Exeko
  • 56
  • 7