错误输出RGB到HSI转换

时间:2013-03-16 16:08:12

标签: c++ opencv image-manipulation

我正在尝试将RGB转换为给定图像的HSI。 但我似乎无法得到正确的输出。 强度已经是正确的。但是,当R + G + B不等于765时,Hue和Saturation一直给出相同的结果-2147483648。 我用这个计算器检查过: http://www.had2know.com/technology/hsi-rgb-color-converter-equations.html 并使用这个公式: http://web2.clarkson.edu/class/image_process/RGB_to_HSI.pdf 请指出我做错了什么..谢谢。

#include <iostream>
#include <cv.h>
#include <highgui.h>
#include "rgb.h"
#include <cmath>
#include <math.h>
#include <algorithm> 
using namespace std;


int main()
{
  char infname[256];

  cout << "Enter input image  : ";
  cin >> infname;
  IplImage *img = cvLoadImage(infname, 0);
  RgbImage pic(img);
  int H = img->height;
  int W = img->width;

 for (int j=0;j<H;j++) 
 for (int i=0;i<W;i++) {
            const double PI = 4.0*atan(1.0);
        double norm = 0;
        double R =(double) pic[j][i].r;
        double G =(double) pic[j][i].g;
        double B =(double) pic[j][i].b;
        double omega = 0;
        double intensity = 0;
        double hue = 0;
        double saturation = 0;
            double r = 0;
            double g = 0;
            double b = 0;

        //Intensity
        intensity = (double) (R + G + B) / (3.0*255);         

        //norm colours
        norm = sqrt(pow(r,2) + pow(g,2) + pow(b,2));
        r = (double) (R / norm);
        g = (double) (G / norm);
        b = (double) (B / norm);

        //Saturation and Hue
        if (R + G + B == 765) {
            saturation = 0;
            hue = 0;
        }

        else {
            double tmp = min(r, min(g, b));
            saturation = 1.0 - ((3.0 * tmp)/ (double)(r + g + b));
               if (saturation < 0.5 ){
                 saturation = 0;
                    }
                else if (saturation >= 0.5){
                 saturation = 1;
                  }
             }
        if (saturation != 0) {
            omega = 0.5 * ((r-g) + (r-b)) / sqrt(pow ((r-g),2) + (r-b)*(g-b));
            omega = acos(omega);
            if (B <= G) {
                hue = omega;
            }
            else if (B > G) {
                hue = 2 * PI - omega;
            }
        }

        //convert it to degrees
        int resultHue = (int) round((hue * 180.0) / PI);
        int resultSaturation = (int) (saturation*100.0);
        int resultIntensity = (int) round(intensity * 255);

cout<<"Red = "<<R<<", Green = "<<G<<", Blue =  "<<B<<endl;
cout<<"Hue  = "<<resultHue<<", Saturation = "<<resultSaturation<<", Intensity = "<<resultIntensity<<endl;


}

   return 0;
    }

2 个答案:

答案 0 :(得分:1)

您使用normrg计算b,但此时它们始终为0。

答案 1 :(得分:0)

#include <iostream>
#include <cv.h>
#include <highgui.h>
#include "rgb.h"
#include <cmath>
#include <algorithm> 
#include <fstream>
using namespace std;


int main()
{
  char infname[256];
  ofstream outputFile;
  outputFile.open("RGB_HSI.txt");

  cout << "Enter input image  : ";
  cin >> infname;
  IplImage *img = cvLoadImage(infname, 0);
  RgbImage pic(img);
  int H = img->height;
  int W = img->width;


 for (int j=0;j<H;j++) 
 for (int i=0;i<W;i++) {
        double norm = 0;
        double omega = 0;
        double R =(double) pic[j][i].r;
        double G =(double) pic[j][i].g;
        double B =(double) pic[j][i].b;
        double intensity = 0;
        double hue = 0;
        double saturation = 0;
            double r = 0;
            double g = 0;
            double b = 0;
            int resultHue = 0;
            int resultSaturation = 0;
            int resultIntensity = 0;

        //Intensity
        intensity = (double) (R + G + B) / (3.0*255);         

        //norm colours
        norm = sqrt((R*R) + (G*G) + (B*B));
        r = (double) (R / norm);
        g = (double) (G / norm);
        b = (double) (B / norm);

        //Saturation and Hue
        if (R + G + B == 765) {
            saturation = 0;
            hue = 0;
        }

        else {
            double tmp = min(r, min(g, b));
            saturation = 1.0 - ((3.0 * tmp)/ (double)(r + g + b));
               if (saturation < 0.5 ){
                 saturation = 0;
                    }
                else if (saturation >= 0.5){
                 saturation = 1;
                  }
             }
        if (saturation != 0) {
            omega = 0.5 * ((r-g) + (r-b)) / sqrt(((r-g) * (r-g)) + (r-b)*(g-b));
            omega = acos(omega);
            if (B <= G) {
                hue = omega;
            }
            else if (B > G) {
                hue = 2 * M_PI - omega;
            }
        }

        //convert it to degrees
         resultHue = (int) round((hue * 180.0) / M_PI);
         resultSaturation = (int) (saturation);
         resultIntensity = (int) round(intensity * 255);

           if ((R == 0) && (G == 0) && ( B== 0 )) {
              resultHue = 0;
              resultSaturation = 0;
              resultIntensity = 0;
            }

outputFile<<"Red = "<<R<<", Green = "<<G<<", Blue =  "<<B<<endl;
outputFile<<"Hue  = "<<resultHue<<", Saturation = "<<resultSaturation<<", Intensity = "<<resultIntensity<<endl;


}
outputFile.close();
cout << "\nRGB_HSI printed as text file: RGB_HSI.text\n";

   return 0;
    }