harshit
harshit

Reputation: 7951

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

Upvotes: 0

Views: 4187

Answers (5)

Achint
Achint

Reputation: 164

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.

Upvotes: 0

sudhanshu
sudhanshu

Reputation: 462

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);

Upvotes: 0

Shervin Emami
Shervin Emami

Reputation: 2765

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.

Upvotes: 0

Yogi
Yogi

Reputation: 2540

firs use cv::cvtColor to convert RGB to HSV then use cv::calcHist to compute the histogram

Upvotes: 2

Philippe Beaudoin
Philippe Beaudoin

Reputation: 3310

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.

Upvotes: 1

Related Questions