100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > OpenCV 颜色空间RGB 到HSI CMYK的转换 C++

OpenCV 颜色空间RGB 到HSI CMYK的转换 C++

时间:2020-05-28 22:48:55

相关推荐

OpenCV 颜色空间RGB 到HSI CMYK的转换 C++

从RGB 到HSI 的空间转换

给定一幅RGB彩色格式的图像,每个RGB像素的H分量可用下式得到:

其中等于

饱和度分量由下式给出:

强度分量下式得出:

上式已假定RGB归一化到【0-1】,且角度是根据HSI空间的红轴来度量。色调可以用6.2-2的结果除以360度归一化到[0-1];

如果RGB已经归一化到[0-1],那其他两个分量已经归一化到0-1了。

从 RGB 到 CMYK 转换

蓝绿色,深红色,黄色是光的二次色,换句话说,是颜料的颜色;

转换公式如下:

这里假定RGB都归一化到[0-1]了。

K是指黑色,这里

草莓转换 CMYK结果:

HSI结果:

RGB单独通道结果:

代码实现:

#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){ //分母不能为0

H = 0;

}

else{

double theta = acos(num/den);

if(b <= g)

H = theta/(PI*2);

else

H = (2*PI - theta)/(2*PI);

}

double minRGB = min(min(r,g),b);

den = r+g+b;

if(den == 0) //分母不能为0

S = 0;

else

S = 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;

}

uchar minimum(uchar a, uchar b)

{

return a <= b ? a : b;

}

cv::Mat bgr2cmyk(cv::Mat& rgb)

{

cv::Mat cmyk = cv::Mat::zeros(rgb.rows, rgb.cols, CV_8UC4);

int pixel_num = rgb.rows * rgb.cols;

for (int i = 0; i < pixel_num; i++)

{

uchar c = 255 - rgb.data[3 * i + 2];

uchar m = 255 - rgb.data[3 * i + 1];

uchar y = 255 - rgb.data[3 * i + 0];

uchar K = minimum(minimum(c, m), y);

cmyk.data[4 * i + 0] = c;

cmyk.data[4 * i + 1] = m;

cmyk.data[4 * i + 2] = y;

cmyk.data[4 * i + 3] = K;

}

return cmyk;

}

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 c = 255 - data[3*j+2];

uchar m = 255 - data[3*j+1];

uchar y = 255 - data[3*j];

uchar k = min(min(c,m),y);

dataCMYK[4*j] = c ;

dataCMYK[4*j+1] = m ;

dataCMYK[4*j+2] = y ;

dataCMYK[4*j+3] = k;

}

}

return 0;

}

int main(){

Mat img = imread("630.tif");

if(!img.data){

cout<<"Miss Data"<<endl;

return -1;

}

resize(img,img,Size(), 0.5, 0.5);

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图像

split(img, vecRgb);

imshow( " src_b", vecRgb[0]);

imshow( " src_g", vecRgb[1]);

imshow( " src_r", vecRgb[2]);

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;

}

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