RGB to HSI、CMYK的代码实现

前言:

在之前博文的基础上,我使用OpenCV2实现了RGB颜色空间向HIS、CMYK转换的代码。下列链接为各种经典颜色空间的介绍及转换公式的介绍。

http://blog.csdn.net/solomon1558/article/details/43772147

1. RGB to HIS

HSI与RGB颜色空间可以进行相互转换。RGB转换到HSI 的计算公式如下:首先给定RGB颜色空间的值(R,G,B),其中R,G,B∈[ 0,2 5 5],则转换到HSI  空间的(H,S,I)值的计算如下:设将(R ,G ,B)归一化得(R',G',B')为:

int rgb2hsi(Mat &image,Mat &hsi){if(!image.data){cout<<"Miss Data"<<endl;return -1;}int nl = image.rows;int nc = image.cols;if(image.isContinuous()){nc = nc*nl;nl = 1;}for(int i = 0;i < nl;i++){uchar *src = image.ptr<uchar>(i);uchar *dst = hsi.ptr<uchar>(i);for(int j = 0;j < nc;j++){float b = src[j*3]/255.0;float g = src[j*3+1]/255.0;float r = src[j*3+2]/255.0;float num = (float)(0.5*((r-g)+(r-b)));float den = (float)sqrt((r-g)*(r-g)+(r-b)*(g-b));float H,S,I;if(den == 0){  //分母不能为0H = 0;}else{double theta = acos(num/den);if(b <= g)H = theta/(PI*2);elseH = (2*PI - theta)/(2*PI);}double minRGB = min(min(r,g),b);den = r+g+b;if(den == 0)   //分母不能为0S = 0;elseS = 1 - 3*minRGB/den;I = den/3.0;//将S分量和H分量都扩充到[0,255]区间以便于显示;//一般H分量在[0,2pi]之间,S在[0,1]之间dst[3*j] = H*255;dst[3*j+1] = S*255;dst[3*j+2] = I*255;}}return 0;
}

【注】:

程序中将S分量和H分量都扩充到[0,255]区间以便于显示;

一般H分量在[0,2pi]之间,S在[0,1]之间。

2.   RGB to CMYK

给定RGB颜色空间的值(R,G,B),其中R,G ,B∈ [0, 2 5 5],则转换到CMYK 空间的(C,M,Y,K)值的计算如下:

【注】式中,maxG是每个矢量分量的最大允许值(255);C , M , Y , K ∈ [ 0,255]。

int rgb2cmyk( Mat &image,Mat &cmyk){if(!image.data){cout<<"Miss Data"<<endl;return -1;}int nl = image.rows;   //行数int nc = image.cols;   //列数if(image.isContinuous()){   //没有额外的填补像素nc = nc*nl;nl = 1;                 //It is now a 1D array}//对于连续图像,本循环只执行1次for(int i=0;i<nl;i++){uchar *data = image.ptr<uchar>(i);uchar *dataCMYK = cmyk.ptr<uchar>(i);for(int j = 0;j < nc;j++){uchar b = data[3*j];uchar g = data[3*j+1];uchar r = data[3*j+2];uchar c = 255 - r;uchar m = 255 - g;uchar y = 255 - b;uchar k = min(min(c,m),y);dataCMYK[4*j] = c - k;dataCMYK[4*j+1] = m  - k;dataCMYK[4*j+2] = y  - k;dataCMYK[4*j+3] = k;}}return 0;
}

3. 完整的工程

#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\opencv.hpp>
#include<vector>
#define PI 3.1416
#define min(a,b) (a<b?a:b)
using namespace std;
using namespace cv;int rgb2hsi(Mat &image,Mat &hsi){if(!image.data){cout<<"Miss Data"<<endl;return -1;}int nl = image.rows;int nc = image.cols;if(image.isContinuous()){nc = nc*nl;nl = 1;}for(int i = 0;i < nl;i++){uchar *src = image.ptr<uchar>(i);uchar *dst = hsi.ptr<uchar>(i);for(int j = 0;j < nc;j++){float b = src[j*3]/255.0;float g = src[j*3+1]/255.0;float r = src[j*3+2]/255.0;float num = (float)(0.5*((r-g)+(r-b)));float den = (float)sqrt((r-g)*(r-g)+(r-b)*(g-b));float H,S,I;if(den == 0){  //分母不能为0H = 0;}else{double theta = acos(num/den);if(b <= g)H = theta/(PI*2);elseH = (2*PI - theta)/(2*PI);}double minRGB = min(min(r,g),b);den = r+g+b;if(den == 0)   //分母不能为0S = 0;elseS = 1 - 3*minRGB/den;I = den/3.0;//将S分量和H分量都扩充到[0,255]区间以便于显示;//一般H分量在[0,2pi]之间,S在[0,1]之间dst[3*j] = H*255;dst[3*j+1] = S*255;dst[3*j+2] = I*255;}}return 0;
}int rgb2cmyk( Mat &image,Mat &cmyk){if(!image.data){cout<<"Miss Data"<<endl;return -1;}int nl = image.rows; //行数int nc = image.cols;   //列数if(image.isContinuous()){   //没有额外的填补像素nc = nc*nl;nl = 1;                 //It is now a 1D array}//对于连续图像,本循环只执行1次for(int i=0;i<nl;i++){uchar *data = image.ptr<uchar>(i);uchar *dataCMYK = cmyk.ptr<uchar>(i);for(int j = 0;j < nc;j++){uchar b = data[3*j];uchar g = data[3*j+1];uchar r = data[3*j+2];uchar c = 255 - r;uchar m = 255 - g;uchar y = 255 - b;uchar k = min(min(c,m),y);dataCMYK[4*j] = c - k;dataCMYK[4*j+1] = m  - k;dataCMYK[4*j+2] = y  - k;dataCMYK[4*j+3] = k;}}return 0;
}
int main(){Mat img = imread("E:\\CV视频处理工作室\\Test_Photo\\lena_1.jpg");if(!img.data){cout<<"Miss Data"<<endl;return -1;}Mat img_cmyk,img_hsi;Mat img_hsv;vector <Mat> vecRgb,vecHsi,vecHls,vecHsv,vecCmyk;img_hsv.create(img.rows,img.cols,CV_8UC3);Mat img_hls;img_hls.create(img.rows,img.cols,CV_8UC3);//生成与输入图像尺寸一样的4通道cmyk图像img_cmyk.create(img.rows,img.cols,CV_8UC4);img_hsi.create(img.rows,img.cols,CV_8UC3);rgb2cmyk(img,img_cmyk);rgb2hsi(img,img_hsi);cvtColor(img,img_hsv,CV_BGR2HSV);cvtColor(img,img_hls,CV_BGR2HLS);split(img_cmyk,vecCmyk);split(img_hsi,vecHsi);cout<<"pixel(0,0) in RGB"<<endl;for(int i=0;i<3;i++){cout<<(int)img.at<Vec3b>(0,0)[i]<<" ";}cout<<endl<<"pixel(0,0) in CMYK"<<endl;for(int i=0;i<4;i++){cout<<(int)img_cmyk.at<Vec4b>(0,0)[i]<<" ";}int a = min(min(24,32),16);cout<<endl<<a;namedWindow("RGB_Image");namedWindow("CMYK_Image");//namedWindow("HSV_Image");//namedWindow("HLS_Image");namedWindow("HSI_Image");namedWindow("CMYK_C");namedWindow("CMYK_M");namedWindow("CMYK_Y");namedWindow("CMYK_K");imshow("CMYK_C",vecCmyk[0]);imshow("CMYK_M",vecCmyk[1]);imshow("CMYK_Y",vecCmyk[2]);imshow("CMYK_K",vecCmyk[3]);imshow("HSI_H",vecHsi[0]);imshow("HSI_S",vecHsi[1]);imshow("HSI_I",vecHsi[2]);imshow("RGB_Image",img);imshow("CMYK_Image",img_cmyk);//imshow("HSV_Image",img_hsv);//imshow("HLS_Image",img_hls);imshow("HSI_Image",img_hsi);waitKey();return 0;
}

使用OpenCV实现RGB、HSI、CMYK颜色空间的转换相关推荐

  1. 颜色空间系列2: RGB和CIELAB颜色空间的转换及优化算法

    颜色空间系列代码下载链接:http://files.cnblogs.com/Imageshop/ImageInfo.rar (同文章同步更新) 在几个常用的颜色空间中,LAB颜色空间是除了RGB外,最 ...

  2. RGB与Lab颜色空间互相转换

    RGB与Lab颜色空间互相转换 1.Lab颜色空间 同RGB颜色空间相比(见博客<光与色的故事--颜色空间浅析>),Lab是一种不常用的色彩空间.它是在1931年国际照明委员会(CIE)制 ...

  3. RGB与Lab颜色空间互相转换 持续更新中

    RGB与Lab颜色空间互相转换 1.Lab颜色空间 同RGB颜色空间相比(见博客<光与色的故事–颜色空间浅析>),Lab是一种不常用的色彩空间.它是在1931年国际照明委员会(CIE)制定 ...

  4. 基于matlab的RGB到YCbCr颜色空间的转换

    在matlab中,图像处理工具箱会将彩色图像当做RGB图像或者索引图像来处理.除了这两种颜色空间外还有其他一些以RGB模型为基础的颜色空间,如常见的YCbCr.HSV.HSI颜色空间等.这里只讲图像从 ...

  5. RGB和YCbCr颜色空间的转换及优化算法

    RGB和YCbCr颜色空间转换和优化 转载于颜色空间系列3: RGB和YCbCr颜色空间的转换及优化算法 在常用的几种颜色空间中,YCbCr颜色空间在学术论文中出现的频率是相当高的,常用于肤色检测等等 ...

  6. Opencv的RGB到HSV颜色空间转换

    从 RGB 到 HSL 或 HSV 的转换 设 (r, g, b) 分别是一个颜色的红.绿和蓝坐标,它们的值是在 0 到 1 之间的实数.设 max 等价于 r, g 和 b 中的最大者.设 min ...

  7. RGB与YCbCr颜色空间的转换

    YCbCr是YUV经过缩放和偏移的翻版,可以看做YUV的子集.主要用于优化彩色视频信号的传输,使其向后相容老式黑白电视.与RGB视频信号传输相比,它最大的优点在于只需占用极少的频宽(RGB要求三个独立 ...

  8. 使用OpenCv实现RGB, YUV, GRAY像素格式转换

    RGB: RGB色彩模式是工业界的一种颜色标准,是通过对红(R).绿(G).蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红.绿.蓝三个通道的颜色,这个标准几乎 ...

  9. 使用Opencv将RGB颜色空间转换到HSV颜色空间/灰度图

    一. 使用cvCvtColor函数将RGB颜色空间转换到HSV颜色空间 所需函数: 1.cvCvtColor 函数功能:颜色空间转换 函数原型: void cvCvtColor( const CvAr ...

最新文章

  1. C# 窗体位置 Show和ShowDialog (转载)
  2. java 打包目录_Java打包文件目录问 zip文件
  3. abap 转换成字符串_SAP ABAP 处理字符串串串串串串串串(详细)
  4. Android多媒体开发
  5. sql 获取本周周一和周日
  6. mysql的show profile使用总结
  7. 【转】3.7(译)构建Async同步基元,Part 7 AsyncReaderWriterLock
  8. 【MySQL】系统命令与基础查询
  9. mysql mongodb b树_为何Mongodb索引用B树,而Mysql用B+树?
  10. button点击后变色_炒丝瓜怎么不变色?鹏厨教你制作小窍门,健康美味、颜色碧绿...
  11. 个人收藏的一些资料(一)Installshield制作友好的更新
  12. WPF的TextBox产生内存泄露的情况
  13. property attribute: assign, strong, weak, unsafe_unretain and copy
  14. 活动选择问题的贪心算法c语言,c语言背包问题_背包问题贪心算法_背包问题 贪心算法...
  15. 如何让百度快速收录网站及文章
  16. 20dbm是多少mw
  17. 《Java解惑》系列——01表达式之谜——谜题09:半斤
  18. linux虚拟机cents7配置静态ip
  19. 高清视频文件丢了怎么恢复丨电脑下载好的缓存数据
  20. 【小波变换】小波变换入门----haar小波

热门文章

  1. VMware虚拟机断网安装Ubuntu系统图解
  2. P4:编程网络的转发平面
  3. 清华发布《中国AI发展报告2018》:中科院系统AI论文产出全球第一(附下载)...
  4. elasticsearch(二)---基本数据操作
  5. kerberos认证原理---讲的非常细致,易懂
  6. DS3231模块使用
  7. javaWeb 使用线程池+队列解决订单并发问题
  8. 帝国网站管理服务器配置信息,帝国cms 服务器设置
  9. 刘晓燕-语法长难句-第一章简单句(不简单)
  10. 除了Confluence,还有哪些好用的文档管理软件?测评