creating HSV histogram using RGB image
Is there a way in Java or OpenCv开发者_开发百科 ; preferably Java, that i can have an HSV histogram give RGB image.
I tried exploring JAI but it creates histogram for RGB image. Thanks Harshit
firs use cv::cvtColor to convert RGB to HSV then use cv::calcHist to compute the histogram
Here is the pseudocode for a simple RGB to HSV converter. It will give a H of UNDEFINED
if the color is a shade of gray, otherwise H is between 0 and 6.
x = min(R, G, B);
V = max(R, G, B);
if (V == x) {
H = UNDEFINED
S = 0
}
else {
if( R == x ) {
f = G - B;
i = 3;
} else if( G == x ) {
f = B - R;
i = 5;
} else {
f = R - G;
i = 1;
}
H = i - f /(V - x);
S = (V - x)/V;
}
Now you can either convert all your pixels and bin them to construct your HSV histogram, or you can convert each bin of your RGB histogram to an HSV bin.
You can use the "JavaCV" library to access OpenCV functions directly from Java:
http://code.google.com/p/javacv/
Then you can use my code for RGB to HSV that is better than OpenCV's cvConvert function: http://www.shervinemami.co.cc/colorConversion.html
Cheers,
Shervin Emami.
Here is a code to do this:
// Assume SourceImage is a Bitmap ARGB_8888
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap refImage = BitmapFactory.decodeFile(mBaseDir + "some_reference.jpg", options);
Mat hsvRef = new Mat();
Mat hsvSource = new Mat();
Mat srcRef = new Mat(refImage.getHeight(), refImage.getWidth(), CvType.CV_8U, new Scalar(4));
Utils.bitmapToMat(refImage, srcRef);
Mat srcSource = new Mat(SourceImage.getHeight(), SourceImage.getWidth(), CvType.CV_8U, new Scalar(4));
Utils.bitmapToMat(SourceImage, srcSource);
/// Convert to HSV
Imgproc.cvtColor(srcRef, hsvRef, Imgproc.COLOR_BGR2HSV);
Imgproc.cvtColor(srcSource, hsvSource, Imgproc.COLOR_BGR2HSV);
/// Using 50 bins for hue and 60 for saturation
int hBins = 50;
int sBins = 60;
MatOfInt histSize = new MatOfInt( hBins, sBins);
// hue varies from 0 to 179, saturation from 0 to 255
MatOfFloat ranges = new MatOfFloat( 0f,180f,0f,256f );
// we compute the histogram from the 0-th and 1-st channels
MatOfInt channels = new MatOfInt(0, 1);
Mat histRef = new Mat();
Mat histSource = new Mat();
ArrayList<Mat> histImages=new ArrayList<Mat>();
histImages.add(hsvRef);
Imgproc.calcHist(histImages,
channels,
new Mat(),
histRef,
histSize,
ranges,
false);
Core.normalize(histRef,
histRef,
0,
1,
Core.NORM_MINMAX,
-1,
new Mat());
histImages=new ArrayList<Mat>();
histImages.add(hsvSource);
Imgproc.calcHist(histImages,
channels,
new Mat(),
histSource,
histSize,
ranges,
false);
Core.normalize(histSource,
histSource,
0,
1,
Core.NORM_MINMAX,
-1,
new Mat());
double resp1 = Imgproc.compareHist(histRef, histSource, 0);
double resp2 = Imgproc.compareHist(histRef, histSource, 1);
double resp3 = Imgproc.compareHist(histRef, histSource, 2);
double resp4 = Imgproc.compareHist(histRef, histSource, 3);
First, you have to convert image to HSV using cv::cvtColor to convert RGB image into HSV image and then, you can use cv::calcHist to compute the HSV histogram.
精彩评论