Reputation: 2152
I would like to get the histogram of an image using Emgu.
I have a Gray scale double image
Image<Gray, double> Crop;
I can get a histogram using
Image<Gray, byte> CropByte = Crop.Convert<Gray, byte>();
DenseHistogram hist = new DenseHistogram(BinCount, new RangeF(0.0f, 255.0f));
hist.Calculate<Byte>(new Image<Gray, byte>[] { CropByte }, true, null);
The problem is, doing it this way I needed to convert to a byte Image. This is problematic because it skews my results. This gives a slightly different histogram to what I would get if it were possible to use a double image.
I have tried using CvInvoke to use the internal opencv function to compute a histogram.
IntPtr[] x = { Crop };
DenseHistogram cropHist = new DenseHistogram
(
BinCount,
new RangeF
(
MinCrop,
MaxCrop
)
);
CvInvoke.cvCalcArrHist(x, cropHist, false, IntPtr.Zero);
The trouble is I'm finding it hard to find how to use this function correctly
Does emgu/opencv allow me to do this? Do I need to write the function myself?
Upvotes: 0
Views: 3932
Reputation: 1327
This is not an EmguCV/OpenCV issue, the idea itself makes no sense as a double histogram would require a lot more memory than what's available. What I say is true when you have an histogram allocated with a fixed size. The only way to go around this would be to have an histogram with dynamic allocation as the image is processed. But this would be dangerous with big images as it could allocate as much memory as the image itself.
I guess that your double image contains many identical values, otherwise an histogram would not be very useful. So one way to go around this is to remap your values to a short (16-bits) instead of byte (8-bits) this way your histogram would be quite similar to what you expect from your double values.
Upvotes: 1
Reputation: 2152
I had a look in histogram.cpp in the opencv source code.
Inside function
void cv::calcHist( const Mat* images, int nimages, const int* channels,
InputArray _mask, OutputArray _hist, int dims, const int* histSize,
const float** ranges, bool uniform, bool accumulate )
There is a section which handles different image types
if( depth == CV_8U )
calcHist_8u(ptrs, deltas, imsize, ihist, dims, ranges, _uniranges, uniform );
else if( depth == CV_16U )
calcHist_<ushort>(ptrs, deltas, imsize, ihist, dims, ranges, _uniranges, uniform );
else if( depth == CV_32F )
calcHist_<float>(ptrs, deltas, imsize, ihist, dims, ranges, _uniranges, uniform );
else
CV_Error(CV_StsUnsupportedFormat, "");
While double images are not handled here yet, float is.
While floating point looses a little bit of precision from double, its not a significant problem.
The following code snippet worked well for me
Image<Gray, float> CropByte = Crop.Convert<Gray, float>();
DenseHistogram hist = new DenseHistogram(BinCount, new RangeF(0.0f, 255.0f));
hist.Calculate<float>(new Image<Gray, float>[] { CropByte }, true, null);
Upvotes: 0