Histogram: Get number of pixels for specified range of pixel values-java [closed]

asked 2017-11-20 03:30:24 -0600

EleDiam gravatar image

updated 2017-11-20 10:31:03 -0600

I have a histogram of a grayscale image with a histSize= 256. What I want is to get the sum of the pixels values found in the ranges: 0 - 64 and 70 - 255. I am calling a for loop (i = 0; I < histSize * 0.25) but then I cannot find a way to calculate what I want. I am new in OpenCV and Java so any help would be appreciated.

Code to calculate the histogram (code found here):

    Mat lrgba = new Mat();
    Utils.bitmapToMat(grayBitmap, lrgba);

    //get the bitmap size of the lines array
    Size crgbaSize = lrgba.size();

    int histSize = 256;
    MatOfInt histogramSize = new MatOfInt(histSize); //Set the amount of bars in the histogram
    int histogramHeight = (int) crgbaSize.height; //Set the height of the histogram
    double getBinLowValue = 0;
    double getBinHighValue = 0;
    double binWidth = 1.76; //width of the bar for each pixel

    MatOfFloat histogramRange = new MatOfFloat(0f, 256f);//Set the value range

    //Create two separate lists: one for colors and one for channels 
    Scalar[] colorsRgb = new Scalar[]{new Scalar(200, 200, 250, 0)};
    MatOfInt[] channels = new MatOfInt[]{new MatOfInt(0)};

   //Create an array to be saved in the histogram and a second array, on which the histogram chart will be drawn.
    Mat[] histograms = new Mat[]{new Mat(), new Mat(), new Mat()};
    Mat histMatBitmap = new Mat(crgbaSize, lrgba.type());

    //Calculate histogram for each channel, standardize the channels and then draw it
    for (int k = 0; k < channels.length; k++) {
        Imgproc.calcHist(Collections.singletonList(lrgba), channels[k], new Mat(), histograms[k], histogramSize, histogramRange);
        Core.normalize(histograms[k], histograms[k], histogramHeight, 0, Core.NORM_MINMAX, -1, new Mat());//normalize the data
        //Draw the chart
        for (int l = 0; l < histSize; l++) {
            Point h1 = new Point(binWidth * (l - 1), histogramHeight - Math.round(histograms[k].get(l - 1, 0)[0]));
            Point h2 = new Point(binWidth * l, histogramHeight - Math.round(histograms[k].get(l, 0)[0]));
            Imgproc.line(histMatBitmap, h1, h2, colorsRgb[k], 1, 8, 0);

Thanks in advance, EleDiam

edit retag flag offensive reopen merge delete

Closed for the following reason the question is answered, right answer was accepted by berak
close date 2017-11-21 01:38:44.987052

Comments

can you show the piece of code, where you calculate the histogram ?

(it's probably something fairly easy, like extracting a range from the histogram mat)

berak gravatar imageberak ( 2017-11-20 05:16:26 -0600 )edit
1

I have added it to my question. Sure I think that this should be something easy but I am getting confused between Mat() and MatOfPoints. Thanks a lot for your quick response

EleDiam gravatar imageEleDiam ( 2017-11-20 07:37:58 -0600 )edit

untried (so not an answer yet), but as we can see from the code above, your 3 seperate (per channel) histograms are simple column Mat's. thus:

// the MAX part of a range is "exclusive", so +1, if you wanted 64 included !
Mat part_0_64 = histogram[i].submat(0,65,0,1); 
double sum0_64 = Core.sumElems(part_0_64);

and:

Mat part_70_255 = histogram[i].submat(70,256,0,1);
double sum70_255 = Core.sumElems(part_70_255);

(and don't get scared by the points, they're only for drawing !)

berak gravatar imageberak ( 2017-11-20 07:55:58 -0600 )edit

I have tried it and the sub matrix is created successfully but the sum gives error: required double, found Scalar..

EleDiam gravatar imageEleDiam ( 2017-11-20 08:30:08 -0600 )edit

apologies, the sum is ofc. the sum per (expected) channel, a Mat can have more than one.

so in java it is:

Scalar sum0_64 = Core.sumElems(part_0_64);
double what_i_wanted = sum_0_64.val[0]; // we only have a single channel here
berak gravatar imageberak ( 2017-11-20 08:59:20 -0600 )edit

Thank you very much it works perfectly now!!!

EleDiam gravatar imageEleDiam ( 2017-11-20 09:15:22 -0600 )edit