RGB与HSV图像互相转换

2023-10-28  本文已影响0人  大龙10
资料:「萌萌哒程序猴」的博客  
https://blog.csdn.net/shandianfengfan/article/details/120600453

一、RGB图像

二、HSV图像

由以上介绍可知,RGB图像与硬件输出相对应,而HSV图像则更符合人眼的直观视觉,因此处理图像时,往往先将RGB图像转换为HSV图像,在HSV色彩空间对图像进行处理,处理完毕后再将HSV图像转换为RGB图像。

三、RGB与HSV的互相转换原理

1、8位彩色图点的其取值范围

2、Opencv中的其取值范围

在Opencv中,为了对HSV图像进行可视化,通常将其像素值转换到0~255之间:


3、RGB转HSV原理

4、HSV转RGB原理

四、基于Opencv的RGB与HSV互相转换

void rgb_hsv(void)
{
  //读取原图像
  Mat img = imread("000000000902.bmp", CV_LOAD_IMAGE_COLOR);
 
  Mat img_hsv;
  cvtColor(img, img_hsv, CV_BGR2HSV);  //将RGB图像转换为HSV图像
  
  Mat img_rgb;
  cvtColor(img_hsv, img_rgb, CV_HSV2BGR);   //将HSV图像转换为RGB图像
 
  imshow("ori rgb", img);
  imshow("hsv", img_hsv);
  imshow("rgb", img_rgb);
  waitKey();
}

五、使用C++自己实现HSV与RGB的互相转换

1、RGB转换为HSV的代码

void RGB2HSV(Mat img_rgb, Mat &img_hsv)
{
  img_hsv = Mat::zeros(img_rgb.size(), CV_8UC3);
 
 
  for (int i = 0; i < img_rgb.rows; i++)
  {
    Vec3b *p0 = img_rgb.ptr<Vec3b>(i);   //B--p[0]  G--p[1]  R--p[2]
    Vec3b *p1 = img_hsv.ptr<Vec3b>(i);   //B--p[0]  G--p[1]  R--p[2]
 
 
    for (int j = 0; j < img_rgb.cols; j++)
    {
      float B = p0[j][0] / 255.0;
      float G = p0[j][1] / 255.0;
      float R = p0[j][2] / 255.0;
      
      float V = (float)std::max({ B, G, R });     //B/G/R
      float vmin = (float)std::min({ B, G, R });
      float diff = V - vmin;
 
 
      float S, H;
      S = diff / (float)(fabs(V) + FLT_EPSILON);
      diff = (float)(60.0 / (diff + FLT_EPSILON));
 
 
      if (V == B)   //V=B
      {
        H = 240.0 + (R - G) * diff;
      }
      else if (V == G)  //V=G
      {
        H = 120.0 + (B - R) * diff;
      }
      else if (V == R)   //V=R
      {
        H = (G - B) * diff;
      }
 
 
      H = (H < 0.0) ? (H + 360.0) : H;
 
 
      p1[j][0] = (uchar)(H / 2);
      p1[j][1] = (uchar)(S * 255);
      p1[j][2] = (uchar)(V * 255);
    }
  }
}

2、HSV转换为RGB的代码

void HSV2BGR(Mat img_hsv, Mat &img_rgb)
{
  img_rgb = Mat::zeros(img_hsv.size(), CV_8UC3);
 
 
  for (int i = 0; i < img_rgb.rows; i++)
  {
    Vec3b *p0 = img_hsv.ptr<Vec3b>(i);   //B--p[0]  G--p[1]  R--p[2]
    Vec3b *p1 = img_rgb.ptr<Vec3b>(i);   //B--p[0]  G--p[1]  R--p[2]
 
 
    for (int j = 0; j < img_hsv.cols; j++)
    {
      float H = p0[j][0] * 2.0;
      float S = p0[j][1] / 255.0;
      float V = p0[j][2] / 255.0;
      
      float h = H / 60.0;            
      int i = floor(h);
      float f = h - i;         
      float p = V * (1 - S);
      float q = V * (1 - f * S);
      float t = V * (1 - (1 - f) * S);
 
 
      switch (i)
      {
      case 0:
        p1[j][2] = (uchar)(V * 255);
        p1[j][1] = (uchar)(t * 255);
        p1[j][0] = (uchar)(p * 255);
        break;
      case 1:
        p1[j][2] = (uchar)(q * 255);
        p1[j][1] = (uchar)(V * 255);
        p1[j][0] = (uchar)(p * 255);
        break;
      case 2:
        p1[j][2] = (uchar)(p * 255);
        p1[j][1] = (uchar)(V * 255);
        p1[j][0] = (uchar)(t * 255);
        break;
      case 3:
        p1[j][2] = (uchar)(p * 255);
        p1[j][1] = (uchar)(q * 255);
        p1[j][0] = (uchar)(V * 255);
        break;
      case 4:
        p1[j][2] = (uchar)(t * 255);
        p1[j][1] = (uchar)(p * 255);
        p1[j][0] = (uchar)(V * 255);
        break;
      default:
        p1[j][2] = (uchar)(V * 255);
        p1[j][1] = (uchar)(p * 255);
        p1[j][0] = (uchar)(q * 255);
        break;
      }
    }
  }
}

3、测试代码

RGB与HSV图像
void rgb_hsv(void)
{
  Mat img = imread("000000000902.bmp", CV_LOAD_IMAGE_COLOR);
 
 
  Mat img_hsv;
  //cvtColor(img, img_hsv, CV_BGR2HSV);
  RGB2HSV(img, img_hsv);
 
 
  Mat img_rgb;
  //cvtColor(img_hsv, img_rgb, CV_HSV2BGR);
  HSV2BGR(img_hsv, img_rgb);
 
 
  imshow("ori rgb", img);
  imshow("hsv", img_hsv);
  imshow("rgb", img_rgb);
  waitKey();
}
上一篇下一篇

猜你喜欢

热点阅读