简体   繁体   English

RGB到HSI和HSI到RGB的转换

[英]RGB to HSI and HSI to RGB conversion

I am trying to covert RGB to HSI and revert it. 我试图将RGBHSI并将其还原。 (The task is required to have it from scratch.) (任务需要从头开始。)

In RGB to HSI convertion, Saturation and Intensity outputs are fine. RGBHSI转换中,饱和度和强度输出都很好。 But I don't seem to get the problem in the formulation of Hue. 但我似乎没有在Hue的制定中遇到问题。 example output: 示例输出:

Red = 255, Green = 255, Blue =  255
Hue  = -2147483648, Saturation = 0, Intensity = 255

Red = 252, Green = 255, Blue =  255
Hue  = 3, Saturation = 0.00787402, Intensity = 254

I use this calculator to check my outputs. 我用这个计算器检查输出。

Please let me know what's wrong. 请让我知道什么是错的。 Thanks. 谢谢。

#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, outputFile2;
  outputFile.open("RGB_HSI.txt");
  outputFile2.open("HSI_RGB.txt");

  cout << "Enter input image  : ";
  cin >> infname;
  IplImage *img = cvLoadImage(infname, 1);
  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 temp = 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;
     int resultHue = 0;
     double resultSaturation = 0;
     int resultIntensity = 0;

   intensity = (R + G + B) / 3;

   if ((R + G + B) == 765) {
      saturation = 0;
      hue = 0;
        }

  double minimum = min(R, min(G, B));

  if (intensity > 0) {
   saturation = 1 - minimum / intensity;
   }

  else if (intensity == 0) {
   saturation = 0;
   }            


  temp = (R - (G/2) - (B/2)) / (sqrt((R*R) + (G*G) + (B*B) - (R*G) - (R*B) - (G*B)));
  if (G >= B) {
    hue = acos(temp); 
    outputFile<<"1. temp = "<<temp<<", H = "<<hue<<endl;
   }

  else if (B > G) {     
    hue = 360 - acos(temp);
    outputFile<<"2. temp = "<<temp<<", H = "<<hue<<endl;
   }

  resultHue = (int) hue;
  resultSaturation = saturation;
  resultIntensity = (int) intensity; 

//outputFile2<<"image = "<<pic[j][i]<<endl;
outputFile<<"Red = "<<R<<", Green = "<<G<<", Blue =  "<<B<<endl;
outputFile<<"Hue  = "<<resultHue<<", Saturation = "<<resultSaturation<<", Intensity = "<<resultIntensity<<endl;



//converting HSI to RGB

int backR = 0, backG = 0, backB = 0;

if (resultHue == 0){
   backR = (int) (resultIntensity + (2 * resultIntensity * resultSaturation));
   backG = (int) (resultIntensity - (resultIntensity * resultSaturation));
   backB = (int) (resultIntensity - (resultIntensity * resultSaturation));
  }

else if ((0 < resultHue) && (resultHue < 120)) {
   backR = (int) (resultIntensity + (resultIntensity * resultSaturation) * cos(resultHue) / cos(60-resultHue));
   backG = (int) (resultIntensity + (resultIntensity * resultSaturation) * (1 - cos(resultHue) / cos(60-resultHue)));
   backB = (int) (resultIntensity - (resultIntensity * resultSaturation));
  }

else if ( resultHue == 120 ){
   backR = (int) (resultIntensity - (resultIntensity * resultSaturation));
   backG = (int) (resultIntensity + (2 * resultIntensity * resultSaturation));
   backB = (int) (resultIntensity - (resultIntensity * resultSaturation));
  }

else if ((120 < resultHue) && (resultHue < 240)) {
   backR = (int) (resultIntensity - (resultIntensity * resultSaturation));
   backG = (int) (resultIntensity + (resultIntensity * resultSaturation) * cos(resultHue-120) / cos(180-resultHue));
   backB = (int) (resultIntensity + (resultIntensity * resultSaturation) * (1 - cos(resultHue-120) / cos(180-resultHue)));
  }

else if (resultHue == 240) {
   backR = (int) (resultIntensity - (resultIntensity * resultSaturation));
   backG = (int) (resultIntensity - (resultIntensity * resultSaturation));
   backB = (int) (resultIntensity + (2 * resultIntensity * resultSaturation));
  }

else if ((240 < resultHue) && (resultHue < 360)) {
   backR = (int) (resultIntensity + (resultIntensity * resultSaturation) * (1 - cos(resultHue-240) / cos(300-resultHue)));
   backG = (int) (resultIntensity - (resultIntensity * resultSaturation));
   backB = (int) (resultIntensity + (resultIntensity * resultSaturation) * cos(resultHue-240) / cos(300-resultHue));
  }

//outputpic[j][i] = (int) (R + G + B); 
//outputFile2<<"output = "<<outputpic[j][i]<<endl;
outputFile2<<"Hue  = "<<resultHue<<", Saturation = "<<resultSaturation<<", Intensity = "<<resultIntensity<<endl;
outputFile2<<"Red = "<<backR<<", Green = "<<backG<<", Blue =  "<<backB<<endl;
}


outputFile.close();
cout << "\nRGB_HSI values printed as text file: RGB_HSI.text\n";
outputFile2.close();
cout << "\nHSI_RGB values printed as text file: HSI_RGB.text\n";

   return 0;
    }

The problem is in this line: 问题出在这一行:

temp = (R - (G/2) - (B/2)) / (sqrt((R*R) + (G*G) + (B*B) - (R*G) - (R*B) - (G*B)));

When R = G = B , then you have a division by zero: R = G = B ,则除以零:

R² - G² - B² - RG - RB - GB = R² + R² + R² - R² - R² - R² = 0

I'm actually surprised it didn't crashed... 我真的很惊讶它没有崩溃......

In that case, just assign 0 to the hue. 在这种情况下,只需为色调指定0即可。 From your link: 从您的链接:

Neutral colors--white, gray, and black--are set to 0° for convenience. 中性色 - 白色,灰色和黑色 - 为方便起见设置为0°。

From others answer it looks like there is a divide by zero issue when R = G = B when you calculate temp but also from what I can tell you are using degree s with the trigonometric function but they are expecting radian s ie: 从其他人那里回答看起来当你计算tempR = G = B时会出现零除以问题,而且我可以告诉你使用三角函数的degree但他们期望radian

#include <cmath>
#include <iostream>

int main()
{
   double pi = atan(1)*4 ;
   std::cout << cos(180) << std::endl ;
   std::cout << cos(360) << std::endl ;
   std::cout << cos(pi) << std::endl ;
   std::cout << cos(2*pi) << std::endl ;   
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM