0

I'm trying to make an app in Android Studio using OpenCV that basically looks at an image of a group of dots and extracts all of the bright dots and then counts them. The dot shape is not consistent, but the color of the dots should be white with a black background.

I start by uploading an image like this: Original Image

I then take the the bitmap of the image and convert it to gray scale. Then I check that the gray values are within a a range and return a bitmap of binary values. The returned image looks like this:

Processed Image

I've unsuccessfully tried a few different methods to count these dots including using Imgproc.findContours and following along tutorials such as this one but I am not looking for a particular shape. It is mostly just a grouping of 1 to 50 pixels at a time with rgb values 225, 255, 255 and irregular shapes. How can these individual shapes be counted?

Here is my image processing portion of the code, the countNonZero portion is just to give me an idea of how many white pixels there are, which is 179 for this particular image

public void convertToGray(View v){
    int whitePix;
    Mat Rgba = new Mat();
    Mat grayMat = new Mat();
    Mat dots = new Mat();
    BitmapFactory.Options o = new BitmapFactory.Options();
    o.inDither=false;
    o.inSampleSize=4;

    int width = imageBitmap.getWidth();
    int height = imageBitmap.getHeight();

    grayBitmap = Bitmap.createBitmap(width,height,Bitmap.Config.RGB_565);


    //bitmap to MAT

    Utils.bitmapToMat(imageBitmap,Rgba);

    Imgproc.cvtColor(Rgba,Rgba,Imgproc.COLOR_RGB2GRAY);

    Core.inRange(Rgba,scalarLow,scalarHigh,grayMat);

    whitePix = Core.countNonZero(grayMat);

    Utils.matToBitmap(grayMat,grayBitmap);

     MediaStore.Images.Media.insertImage(getApplicationContext().getContentResolver(), grayBitmap, "Result", "Descrip");

    mImageView.setImageBitmap(grayBitmap);



}

This function is called when a button is clicked after an image has been uploaded to the app.

Kyle G
  • 71
  • 10

2 Answers2

1

i used this code to iterate over a template matching result Mat to find possible matches.

public static List<Point> getPointsFromMatAboveThreshold(Mat m, float t){
    List<Point> matches = new ArrayList<Point>();
    FloatIndexer indexer = m.createIndexer();
    for (int y = 0; y < m.rows(); y++) {
        for (int x = 0; x < m.cols(); x++) {
            if (indexer.get(y,x)>t) {
                System.out.println("(" + x + "," + y +") = "+ indexer.get(y,x));
                matches.add(new Point(x, y));                   
            }
        }           
    }       
    return matches;
}

this will give you a list of coordinates over a certain amount white. you would then need to cluster those

mavriksc
  • 1,130
  • 1
  • 7
  • 10
  • Is the point you are using from the opencv.core class or the android.graphics class? Also where does the class FloatIndexer come from? Thank you for the reply – Kyle G Oct 05 '18 at 21:20
  • 1
    can see my whole cvutils [here](https://github.com/mavriksc/overcomp/blob/master/src/main/java/com/mavriksc/service/OpenCVUtils.java) – mavriksc Oct 05 '18 at 21:21
0

It turns out I was using findContours incorrectly, and I was able solve my problem by appending the following code in my function:

    Mat dots = new Mat();
    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    Imgproc.findContours(grayMat, contours, dots, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE, new Point(0,0));

    Imgproc.drawContours(grayMat, contours, -1, new Scalar(Math.random()*255, Math.random()*255, Math.random()*255));//, 2, 8, hierarchy, 0, new Point());

And the countours list contains the number of entires of contours, which is the number of blobs I am looking for.

Kyle G
  • 71
  • 10