OpenCV实现RGB颜色空间和HSI颜色空间的相互转换
2013-04-17 16:22
861 查看
关于HSI颜色空间参照维基百科:http://zh.wikipedia.org/wiki/HSI%E8%89%B2%E5%BD%A9%E5%B1%AC%E6%80%A7%E6%A8%A1%E5%BC%8F
核心的转换公式:
RGB-->HSI
截图来自中科院刘定生老师的《数字图像处理与分析》课件。
HSI-->RGB
具体的数学公式参照冈萨雷斯版《数字图像处理(第三版)》432-434页,中译版的260-261页。
下面贴代码:
写的比较仓促,代码结构稍微有点混乱。
测试图像为彩色Lena图,运行结果如下:
左图为显示出来的HSI颜色模型图,右图为RGB颜色模型图。
HSI颜色模型为了显示,做了点处理,具体见代码。
核心的转换公式:
RGB-->HSI
截图来自中科院刘定生老师的《数字图像处理与分析》课件。
HSI-->RGB
具体的数学公式参照冈萨雷斯版《数字图像处理(第三版)》432-434页,中译版的260-261页。
下面贴代码:
#include "opencv_libs.h" #include <highgui.h> #include <cv.h> #include <math.h> /* * 描述:实现RGB颜色模型到HSI颜色模型之间的相互转换 * 作者:qdsclove(qdsclove@gmail.com) * 时间:16:01 4/17 星期三 2013 */ // 将HSI颜色空间的三个分量组合起来,便于显示 IplImage* catHSImage(CvMat* HSI_H, CvMat* HSI_S, CvMat* HSI_I) { IplImage* HSI_Image = cvCreateImage( cvGetSize( HSI_H ), IPL_DEPTH_8U, 3 ); for(int i = 0; i < HSI_Image->height; i++) { for(int j = 0; j < HSI_Image->width; j++) { double d = cvmGet( HSI_H, i, j ); int b = (int)(d * 255/360); d = cvmGet( HSI_S, i, j ); int g = (int)( d * 255 ); d = cvmGet( HSI_I, i, j ); int r = (int)( d * 255 ); cvSet2D( HSI_Image, i, j, cvScalar( b, g, r ) ); } } return HSI_Image; } // 将HSI颜色模型的数据转换为RGB颜色模型的图像 IplImage* HSI2RGBImage(CvMat* HSI_H, CvMat* HSI_S, CvMat* HSI_I) { IplImage * RGB_Image = cvCreateImage(cvGetSize(HSI_H), IPL_DEPTH_8U, 3 ); int iB, iG, iR; for(int i = 0; i < RGB_Image->height; i++) { for(int j = 0; j < RGB_Image->width; j++) { // 该点的色度H double dH = cvmGet( HSI_H, i, j ); // 该点的色饱和度S double dS = cvmGet( HSI_S, i, j ); // 该点的亮度 double dI = cvmGet( HSI_I, i, j ); double dTempB, dTempG, dTempR; // RG扇区 if(dH < 120 && dH >= 0) { // 将H转为弧度表示 dH = dH * 3.1415926 / 180; dTempB = dI * (1 - dS); dTempR = dI * ( 1 + (dS * cos(dH))/cos(3.1415926/3 - dH) ); dTempG = (3 * dI - (dTempR + dTempB)); } // GB扇区 else if(dH < 240 && dH >= 120) { dH -= 120; // 将H转为弧度表示 dH = dH * 3.1415926 / 180; dTempR = dI * (1 - dS); dTempG = dI * (1 + dS * cos(dH)/cos(3.1415926/3 - dH)); dTempB = (3 * dI - (dTempR + dTempG)); } // BR扇区 else { dH -= 240; // 将H转为弧度表示 dH = dH * 3.1415926 / 180; dTempG = dI * (1 - dS); dTempB = dI * (1 + (dS * cos(dH))/cos(3.1415926/3 - dH)); dTempR = (3* dI - (dTempG + dTempB)); } iB = dTempB * 255; iG = dTempG * 255; iR = dTempR * 255; cvSet2D( RGB_Image, i, j, cvScalar( iB, iG, iR ) ); } } return RGB_Image; } int main() { IplImage* img = cvLoadImage("lena.bmp"); // 三个HSI空间数据矩阵 CvMat* HSI_H = cvCreateMat( img->height, img->width, CV_32FC1 ); CvMat* HSI_S = cvCreateMat( img->height, img->width, CV_32FC1 ); CvMat* HSI_I = cvCreateMat( img->height, img->width, CV_32FC1 ); // 原始图像数据指针, HSI矩阵数据指针 uchar* data; // rgb分量 byte img_r, img_g, img_b; byte min_rgb; // rgb分量中的最小值 // HSI分量 float fHue, fSaturation, fIntensity; for(int i = 0; i < img->height; i++) { for(int j = 0; j < img->width; j++) { data = cvPtr2D(img, i, j, 0); img_b = *data; data++; img_g = *data; data++; img_r = *data; // Intensity分量[0, 1] fIntensity = (float)((img_b + img_g + img_r)/3)/255; // 得到RGB分量中的最小值 float fTemp = img_r < img_g ? img_r : img_g; min_rgb = fTemp < img_b ? fTemp : img_b; // Saturation分量[0, 1] fSaturation = 1 - (float)(3 * min_rgb)/(img_r + img_g + img_b); // 计算theta角 float numerator = (img_r - img_g + img_r - img_b ) / 2; float denominator = sqrt( pow( (img_r - img_g), 2 ) + (img_r - img_b)*(img_g - img_b) ); // 计算Hue分量 if(denominator != 0) { float theta = acos( numerator/denominator) * 180/3.14; if(img_b <= img_g) { fHue = theta ; } else { fHue = 360 - theta; } } else { fHue = 0; } // 赋值 cvmSet( HSI_H, i, j, fHue ); cvmSet( HSI_S, i, j, fSaturation); cvmSet( HSI_I, i, j, fIntensity ); } } IplImage* HSI_Image = catHSImage( HSI_H, HSI_S, HSI_I ); IplImage* RGB_Image = HSI2RGBImage( HSI_H, HSI_S, HSI_I ); cvShowImage("img", img); cvShowImage("HSI Color Model", HSI_Image); cvShowImage("RGB Color Model", RGB_Image); cvWaitKey(0); cvReleaseImage( &img ); cvReleaseImage( &HSI_Image ); cvReleaseImage( &RGB_Image ); cvReleaseMat( &HSI_H); cvReleaseMat( &HSI_S); cvReleaseMat( &HSI_I); cvDestroyAllWindows(); return 0; }
写的比较仓促,代码结构稍微有点混乱。
测试图像为彩色Lena图,运行结果如下:
左图为显示出来的HSI颜色模型图,右图为RGB颜色模型图。
HSI颜色模型为了显示,做了点处理,具体见代码。
相关文章推荐
- OpenCV实现RGB颜色空间和HSI颜色空间的相互转换
- OpenCV实现RGB颜色空间和HSI颜色空间的相互转换
- OpenCV实现RGB颜色空间和HSI颜色空间的相互转换
- OpenCV实现RGB颜色空间和HSI颜色空间的相互转换
- 使用OpenCV实现RGB、HSI、CMYK颜色空间的转换
- opencv实现将RGB图像转换到HSI空间
- Java 利用 ICC 色彩空间 color space profile 实现 RGB 和 CMYK 颜色的相互转换
- 数字图像处理 颜色空间RGB、HSI、CMYK、YUV的相互转换
- 数字图像处理 颜色空间RGB、HSI、CMYK、YUV的相互转换
- HSI颜色空间和RGB颜色空间之间的相互转换
- RGB空间与HSV空间的相互转换(C++实现,修正网上大多数的代码错误)
- javascript实现十六进制颜色值(HEX)和RGB格式相互转换
- VC编程实现色彩空间RGB与XYZ相互转换
- 使用Opencv将RGB颜色空间转换到HSV颜色空间/灰度图
- HSV颜色空间 与 RGB 颜色空间的相互转换
- javascript实现十六进制颜色值(HEX)和RGB格式相互转换
- OPENCV 从RGB空间转换到HSI空间
- 利用cvtColor实现图像颜色空间的转换-比如RGB转灰度图等
- 【OpenCV】 RGB和CIEXYZ颜色空间的转换及相关优化。
- 基于OpenCV的RGB和HSV色彩空间相互转换C++程序