2016-12-04 12 views
1

Обновление вопроса, который я задаю. Я успешно смог конвертировать из RGB в HSI и обратно. Мой преподаватель также дал указание увеличить интенсивность изображения, добавив ((1.0 - I)/2.0) к I (интенсивность), прежде чем я выведу изображение. Когда я это делаю, это вызывает переполнение, поэтому все мои проверки на RGB и т. Д. Если я вычту приведенную выше формулу, она успешно затемняет изображение без проблем с переполнением. Кажется, я не могу определить причину этого переполнения и не знаю, как его исправить. Сначала я подумал, что это связано со значениями, где R = G = B, но я подтвердил вывод этих переменных и отладки, что это не так. Какова причина, когда насыщенность S равна нулю. Когда S = 0, я знаю, что hue, H, не имеет значения. Будем очень благодарны любой помощи!Увеличение интенсивности при преобразовании HSI в RGB в OpenCV с использованием C++

#include<opencv2/core/core.hpp> 
#include<opencv2/highgui/highgui.hpp> 
#include<opencv2/imgproc/imgproc.hpp> 

#include<iostream> 

#define M_PI (3.14159265358979323846) 

using namespace cv; 


int main(int argc, char * argv[]) 
{ 
if (argc <= 1) 
{ 
    std::cerr << "Not enough arguments." << std::endl; 
    return (1); 
} 

Mat img = cv::imread(argv[1], CV_LOAD_IMAGE_COLOR); 
std::cout << img.channels() << std::endl; 

if (img.empty()) 
{ 
    std::cerr << "Unable to open the image " << argv[1] << "." << std::endl; 
    return (1); 
} 

namedWindow("Original Image", CV_WINDOW_AUTOSIZE); 
imshow("Original Image", img); 

Mat hsi(img.rows, img.cols, img.type()); 
Mat newBGRimg = Mat::zeros(img.rows, img.cols, img.type()); 

double B, G, R, H, S, I, b, g, re; 
int intB = 0, intG = 0, intR = 0; 

for (int r = 0; r < img.rows; r++) 
{ 
    for (int c = 0; c < img.cols; c++) 
    { 
     b = img.at<Vec3b>(r, c)[0]; 
     g = img.at<Vec3b>(r, c)[1]; 
     re = img.at<Vec3b>(r, c)[2]; 

     // Normalize colors 
     B = b/255; 
     G = g/255; 
     R = re/255; 

     // BGR to HSI   
     double theta = acos((((R - G) + (R - B))/2)/(sqrt((pow((R - G), 2)) + ((R - B)*(G - B) + 0.0001)))); 

     if (B <= G) 
     { 
      H = theta; 
     } 

     if (B > G) 
     { 
      H = (2 * M_PI) - theta; 
     } 

     if (H < 0) 
      H = 0; 
     if (H > 2 * M_PI) 
      H = 2 * M_PI; 

     double min = std::min({ B, G, R }); 
     S = 1 - (3 * min)/(B + G + R); ///(B + G + R) 
     if (S < 0) 
      S = 0; 
     if (S > 1) 
      S = 1; 

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

     I = I + ((1.0 - I)/2.0); 
     if (I < 0) 
      I = 0; 
     if (I > 1) 
      I = 1; 

     // HSI to BGR 
     if (H >= 0 && H < (2 * M_PI/3)) 
     { 

      B = I * (1 - S); 
      R = I * (1 + ((S * cos(H))/(cos((M_PI/3) - H)))); 
      G = (3 * I) - (R + B); 

      B *= 255; 
      G *= 255; 
      R *= 255; 

      if (B > 255) 
       B = 255; 
      if (G > 255) 
       G = 255; 
      if (R > 255) 
       R = 255; 
      if (B < 0) 
       B = 0; 
      if (G < 0) 
       G = 0; 
      if (R < 0) 
       R = 0; 

      intB = (int)round(B); 
      intG = (int)round(G); 
      intR = (int)round(R); 
      //std::cout << intB << " " << intG << " " << intG << " " << r << " " << c << std::endl; 

      newBGRimg.at<Vec3b>(r, c)[0] = intB; 
      newBGRimg.at<Vec3b>(r, c)[1] = intG; 
      newBGRimg.at<Vec3b>(r, c)[2] = intR; 
     } 
     else if (H >= (2 * M_PI/3) && H < (4 * M_PI/3)) 
     { 
      H = H - (2 * M_PI)/3; 
      R = I * (1 - S); 
      G = I * (1 + ((S * cos(H))/(cos((M_PI/3) - H)))); 
      B = (3 * I) - (R + G); 

      B *= 255; 
      G *= 255; 
      R *= 255; 

      if (B > 255) 
       B = 255; 
      if (G > 255) 
       G = 255; 
      if (R > 255) 
       R = 255; 
      if (B < 0) 
       B = 0; 
      if (G < 0) 
       G = 0; 
      if (R < 0) 
       R = 0; 

      intB = (int)round(B); 
      intG = (int)round(G); 
      intR = (int)round(R); 

      newBGRimg.at<Vec3b>(r, c)[0] = intB; 
      newBGRimg.at<Vec3b>(r, c)[1] = intG; 
      newBGRimg.at<Vec3b>(r, c)[2] = intR; 
     } 
     else if (H >= (4 * M_PI/3)) 
     { 
      H = H - (4 * M_PI)/3; 
      G = I * (1 - S); 
      B = I * (1 + ((S * cos(H))/(cos((M_PI/3 - H))))); 
      R = (3 * I) - (G + B); 

      B *= 255; 
      G *= 255; 
      R *= 255; 

      if (B > 255) 
       B = 255; 
      if (G > 255) 
       G = 255; 
      if (R > 255) 
       R = 255; 
      if (B < 0) 
       B = 0; 
      if (G < 0) 
       G = 0; 
      if (R < 0) 
       R = 0; 

      intB = (int)round(B); 
      intG = (int)round(G); 
      intR = (int)round(R); 

      newBGRimg.at<Vec3b>(r, c)[0] = intB; 
      newBGRimg.at<Vec3b>(r, c)[1] = intG; 
      newBGRimg.at<Vec3b>(r, c)[2] = intR; 
     } 
    } 
} 
namedWindow("New RGB Image", CV_WINDOW_AUTOSIZE); 
imshow("New RGB Image", newBGRimg); 
imwrite("hsi-to-rgb.jpg", newBGRimg); 

waitKey(0); 
return 0; 
} 

ответ

0

В моем исходном коде я пытался нормализовать значения BGR, используя ex. B/B + G + R на дополнительный материал 3-го издания. , Это должно было быть B/255 для нормализации этого значения до [0,1]. Я считаю, что книга была неверна, предлагая этот метод нормализации.