How to Access Histogram data

1,701 views
Skip to first unread message

Thr3e

unread,
Jan 2, 2012, 12:44:55 AM1/2/12
to javacv
So I am using the OpenCV 2 Computer Vision Application Programming
Cookbook, and I am stuck on the Histogram example from chapter four. I
was trying to translate the C++ code to Java, but there are a lot of
methods that are not the same in the JavaCV API, I worked around a
couple of them but eventually got stuck when trying to access the
histogram data.

Here is the C++ code:

//The class used to get the histogram, returns a histogram for a
grayscale image
class Histogram1D {
private:
int histSize[1]; // number of bins
float hranges[2]; // min and max pixel value
const float* ranges[1];
int channels[1]; // only 1 channel used here
public:
Histogram1D() {
// Prepare arguments for 1D histogram
histSize[0]= 256;
hranges[0]= 0.0;
hranges[1]= 255.0;
ranges[0]= hranges;
channels[0]= 0; // by default, we look at channel 0
}
// Computes the 1D histogram.
cv::MatND getHistogram(const cv::Mat &image) {
cv::MatND hist;
// Compute histogram
cv::calcHist(&image,
1, // histogram from 1 image only
channels, // the channel used
cv::Mat(), // no mask is used
hist, // the resulting histogram
1, // it is a 1D histogram
histSize, // number of bins
ranges // pixel value range
);
return hist;
}
//Initialization code:

// Read input image
cv::Mat image= cv::imread("../group.jpg", 0); // open in b&w
// The histogram object
Histogram1D h;
// Compute the histogram
cv::MatND histo= h.getHistogram(image);

//Looping over the data from the histogram:

// Loop over each bin
for (int i=0; i<256; i++)
cout << "Value " << i << " = " << histo.at<float>(i) << endl;

//Desire Output:
...
Value 7 = 159
Value 8 = 208
Value 9 = 271
Value 10 = 288
Value 11 = 340
Value 12 = 418
Value 13 = 432
Value 14 = 472
Value 15 = 525
...

Now the first problem I encountered was creating the histogram, In the
code above, the histogram information is simply given to the calcHist
method, however I couldn't do the same in Java because that is a C++
method according to OpenCV API: http://opencv.itseez.com/modules/imgproc/doc/histograms.html#calchist
And JavaCV only has the C method. So I searched through the API and
ended up creating a separate CvHistogram using the cvCreateHistogram
method. Then I used that histogram and an a grayscale image with the
calcHist method and it compiled fine.

The real problem is that I can't seem to be able to access the actual
data in the histogram. In the above code they are using the "at"
method, that's not in the CvHistogram class. Then I searched this
group's discussion and found this:
http://groups.google.com/group/javacv/browse_thread/thread/f77a9eca87193567/25bdaa78d675ac54?lnk=gst&q=histogram#25bdaa78d675ac54

From that I tried to look for the method getByteBuffer in the sources,
and found it to be in the cxcore package:
http://www.google.com/codesearch#search/&q=getbytebuffer%20package:http://javacv%5C.googlecode%5C.com&type=cs

The thing is I don't know how to access that package. Here is my code
as you can see I can't get past the call to calcHist, whenever I call
the method asByteBuffer I get an a buffer without an array(used
hasArray method). Any help on how to access the values would be a huge
help thanks!

My Java Code:

public class Histogram {

public static void main(String[] args){
IplImage image = cvLoadImage("C:/Users/Cesar/Desktop/Project
Workspace/Workspace"
+ "/Projects/Netbeans/JavaCV_TestRun/src/
JavaCV_TestRun/util/Histogram_baboom.jpg", CV_LOAD_IMAGE_GRAYSCALE);

CvHistogram hist = cvCreateHist(1, new int[]{256},
CV_HIST_ARRAY, new float[][]{{0.0f, 255.0f}}, 1);

// cvShowImage("Before Calc", image);
// cvWaitKey();

cvCalcHist(new IplImage[]{image}, hist, 0, null);
}
}

All I am doing is loading an image in grayscale, then I want to access

Samuel Audet

unread,
Jan 2, 2012, 11:59:37 PM1/2/12
to jav...@googlegroups.com
Hello,

You could check the camshiftdemo.c sample that comes with OpenCV for
some guidance on the usage of CvHistogram:
https://code.ros.org/trac/opencv/browser/trunk/opencv/samples/c/camshiftdemo.c?rev=1429

Does this do what you need?

Samuel

Thr3e

unread,
Jan 3, 2012, 2:34:18 AM1/3/12
to javacv
Samuel I would like to thank you so much for your help, I feel bad for
not saying so on my previous request for help, so I want to say it
now, thank you!

As for that example, it was not what I was looking for, but I did
managed to access the bin values by using the method cvQueryHistValue
in the legacy package, and its putting out the right data since I
calculated the amount of pixels in the image and it matched the total
sum of all the bins.

Samuel Audet

unread,
Nov 17, 2012, 11:55:01 PM11/17/12
to jav...@googlegroups.com
On 11/15/2012 08:35 AM, Richard McElligott wrote:
> See:
> http://www.mon-club-elec.fr/mes_docs/my_javacv_javadoc/com/googlecode/javacv/cpp/opencv_imgproc.CvHistogram.html
>
> There is a method called:
> *opencv_imgproc.CvHistogram.create(int dims, int[] sizes, int type, float[][] ranges, int uniform) *
> *
> Unfortunately I can see no explination for what the arguements in the
> call are. Can anyone elaborate with an example?
> *
> *Thanks*

They are the same as this:
http://docs.opencv.org/modules/imgproc/doc/histograms.html#CvHistogram*%20cvCreateHist%28int%20dims,%20int*%20sizes,%20int%20type,%20float**%20ranges,%20int%20uniform%29

Samuel

Bruno

unread,
Nov 27, 2012, 9:51:44 AM11/27/12
to jav...@googlegroups.com
Hi Samuel,

I'm getting the following error when trying to access histogram data with the method cvQueryHistValue_3D(hist1, h, s, v) :

# JRE version: 7.0_09-b30
# Java VM: OpenJDK 64-Bit Server VM (23.2-b09 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# V  [libjvm.so+0x539d34]  jni_SetLongField+0x64
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again

In the log i found this:
Stack: [0x00007ffbb4ac3000,0x00007ffbb4bc4000],  sp=0x00007ffbb4bc0490,  free space=1013k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x539d34]  jni_SetLongField+0x64

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  com.googlecode.javacv.cpp.opencv_imgproc$CvHistogram.bins()Lcom/googlecode/javacv/cpp/opencv_core$CvArr;+0
j  com.googlecode.javacv.cpp.opencv_legacy.cvQueryHistValue_3D(Lcom/googlecode/javacv/cpp/opencv_imgproc$CvHistogram;III)F+1

Do you know what could be the problem? The method cvCompareHist works, so I think the histograms are OK.

Thanks.

Samuel Audet

unread,
Nov 30, 2012, 11:20:14 PM11/30/12
to jav...@googlegroups.com
Hello,

Can you provide a few lines of code that crash so I try it out here? thanks

Samuel

Samuel Audet

unread,
Dec 11, 2012, 9:05:37 AM12/11/12
to jav...@googlegroups.com
On 12/11/2012 01:05 PM, Bassel wrote:
>
> I have a sample java code that just dies trying to access the histogram
> bins, could not make it work.

Hum, I can see it crashes yes. Does the same kind of code work in C/C++?

Samuel

Samuel Audet

unread,
Dec 11, 2012, 9:21:58 AM12/11/12
to jav...@googlegroups.com
Never mind, I found what the problem was. To fix that, we only need to
recompile opencv_core.java and update the class files in javacv.jar:
http://code.google.com/p/javacv/source/detail?r=1f0b033893f300e38b7fbe3ee7401e3460df3dff

Samuel

Bassel

unread,
Dec 11, 2012, 9:37:21 AM12/11/12
to jav...@googlegroups.com
That was quick :)

I was about to post that I tried with 32/64bits, java 6, 7 same result.

So what's the next step? will you post an update to javacv or do I compile and repackage myself?

I'm pleasantly surprised by the fast reply :)

Thanks

Bassel

Samuel Audet

unread,
Dec 12, 2012, 7:43:56 AM12/12/12
to jav...@googlegroups.com
On 12/11/2012 11:37 PM, Bassel wrote:
> That was quick :)
>
> I was about to post that I tried with 32/64bits, java 6, 7 same result.
>
> So what's the next step? will you post an update to javacv or do I
> compile and repackage myself?

Yes, I guess that's the simplest thing. We can rebuild javacv.jar with
"mvn clean install -Djavacpp.skip=true", no need to recompile the native
binaries.

> I'm pleasantly surprised by the fast reply :)

You were just lucky :)

Bassel

unread,
Dec 12, 2012, 12:18:51 PM12/12/12
to jav...@googlegroups.com
If i may pick your brains Samuel,

I'm attempting to perform white balance correction on an image received from a camera. The image is RAW and has the Bayer Color space. I successfully use cvCvtColor(src, out, CV_BayerGB2RGB) and that gives me an RGB image that i can display on a Panel or save on disk successfully. I can also apply gamma correction to it using .applyGamma(). all is great. Except that:

The image is greenish and the colors are slightly off. I split the rgb image into single channels for the r,g,b and calculate the histograms and try to find the highest mean so i can scale the other pixels to it, however, all channels have the exact same mean! I'm using the range 0,255 ... The max pixel value is different for all 3.

Do you have any advice on doing such manipulation?

Thank you.

P.S: I recompiled the opencv_core and updated the jar, I can now access the bins perfectly and read the intensity values, thanks again for that update!

Samuel Audet

unread,
Dec 15, 2012, 7:11:34 AM12/15/12
to jav...@googlegroups.com
On 12/13/2012 02:18 AM, Bassel wrote:
> If i may pick your brains Samuel,
>
> I'm attempting to perform white balance correction on an image received
> from a camera. The image is RAW and has the Bayer Color space. I
> successfully use cvCvtColor(src, out, CV_BayerGB2RGB) and that gives me
> an RGB image that i can display on a Panel or save on disk successfully.
> I can also apply gamma correction to it using .applyGamma(). all is
> great. Except that:
>
> The image is greenish and the colors are slightly off. I split the rgb
> image into single channels for the r,g,b and calculate the histograms
> and try to find the highest mean so i can scale the other pixels to it,
> however, all channels have the exact same mean! I'm using the range
> 0,255 ... The max pixel value is different for all 3.
>
> Do you have any advice on doing such manipulation?

Well, I would use an image manipulation tool like GIMP or Photoshop to
try out stuff, and after figuring out what makes it pretty, then
replicate it in Java.

> P.S: I recompiled the opencv_core and updated the jar, I can now access
> the bins perfectly and read the intensity values, thanks again for that
> update!

Great! Thanks for letting me know

Samuel
Reply all
Reply to author
Forward
0 new messages