600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > 使用OpenCV实现RGB HSI CMYK颜色空间的转换

使用OpenCV实现RGB HSI CMYK颜色空间的转换

时间:2022-08-29 09:18:39

相关推荐

使用OpenCV实现RGB HSI CMYK颜色空间的转换

RGB to HSI、CMYK的代码实现

前言:

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

/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;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。