一:色彩模式:
1、颜色模式HSV:色象 饱和度 明度,是基于视觉反映的颜色
2、颜色模式RGB:红 绿 蓝,是基于光色的颜色,也为加色模式,即两这重合变亮
R.红色:Red,0~255阶,一共256阶色G.绿色:Green,0~255阶,一共256阶色
B:.蓝色,Blue,0~255阶,一共256阶色
三者放到一起表示一种颜色:如R:255 G:0 B:0表示红色;R:0 G:255 B:0表示绿色
两个分量的变化都是从-128到127;当a=0、b=0时显示灰色,同时L=100时为百色,L=0时为黑色;如果一定要用Lab模式来表达颜色,那么R色值为:L=54、a=81、b=70;G色值为:L=88、a=-79、b=81;B色值为:L=29、a=68、b=-112;C色值为:L=62、a=-31、b=-64;M色值为:L=48、a=83、b=-3;Y色值为:L=94、a=-14、b=100。
大致上说:在表达色彩范围上,最全的是Lab模式,其次是RGB模式,最窄的是CMYK模式。也就是说Lab模式所定义的色彩最多,且与光线及设备无关,并且处理速度与RGB模式同样快,比CMYK模式快数倍。因此,您可放心大胆的在图像编辑中使用Lab模式,而且,Lab模式保证在转换成CMYK模式时色彩最少丢失或被替代。因此,从理论上讲最佳避免色彩损失的方法是:应用Lab模式编辑图像,再转换CMYK模式打印。
至于从RGB转化到hsv或者lab直接调用cvtColor就行。
二:对各通道的操作
通过搜索找到以下几种方法:
1.、at方法
使用at模板函数能访问某行某列的像素
例如:
Mat::.at<cv::Vec3b>(j,i)
访问其各个通道:
Mat::at<cv::Vec3b>(j,i)[0] b通道
Mat::at<cv::Vec3b>(j,i)[1] g通道
Mat::at<cv::Vec3b>(j,i)[2] r通道
2.ptr方法
使用ptr模板可以得到行数据的头指针
uchar * data=iMat::.ptr<uchar>(j);//得到j行指针(储存行数据的地址)
访问第i个像素各个通道:
本质是根据指针移步实现,根据图像结构来移步
data[i*img1.nchanles+0]
data[i*img1.nchanles+1]
data[i*img1.nchanles+2]
3.iterator方法(迭代器)
迭代器方法,类似一维数组的模式,利用迭代器操作,方便操作像素
cv::Mat_<cv::Vec3b>::iterator it=img1.begin<cv::Vec3b>();cv::Mat_<cv::Vec3b>::iterator it_end=img1.end<cv::Vec3b>();
访问像素:
(*it)[0] b通道
(*it)[1] g通道
(*it)[2] r通道
it++
如果图像为单通道 src.at<uchar>(j,i)
如果图像为三通道 src.at<Vec3b>(j,i)[channel]
注意:
mage.at<uchar>(x,y)
image.at<uchar>(point)这两者的区别
打断一下:
数据的存储,这一直就是一个值得关注的问题,Mat_<uchar>对应的是CV_8U,Mat_<uchar>对应的是CV_8U,Mat_<char>对应的是CV_8S,Mat_<int>对应的是CV_32S,Mat_<float>对应的是CV_32F,Mat_<double>对应的是CV_64F。
在这里用的是at方法,代码如下:
// 1.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include"opencv243.h" #include"stdlib.h" using namespace std; using namespace cv; int _tmain(int argc, _TCHAR* argv[]) { //...取图像中像素第二通道g大于128,全部置成红色.......// Mat img=imread("C:\\Users\\sony\\Desktop\\Airplane.jpg",1); Mat dst_hsv,dst_hsl; for(int j=0;j<img.rows;j++) { for(int i=0;i<img.cols;i++) { if(img.at<Vec3b>(j,i)[2]>128) { img.at<Vec3b>(j,i)=Vec3b(0,0,255); } } } imshow("k",img); //.....在图像的正中间画一个实心圆........// Mat m(400,400,CV_8UC3,Scalar(255,255,255)); Mat_<Vec3b> m1=m; // m2 是 Mat_<Vec3b> 类型的, 因为 m 中元素的类型是 CV_8UC3, 可以用 Vec3b 存储 3 个通道的值 // 注意 Mat_<CV_8UC3> 这种写法是错误的, 因为 CV_8UC3 只是一个宏定义 for(int j=0;j<m.rows;j++) { for(int i=0;i<m.cols;i++) { if(pow(double(i-200),2)+pow(double(j-200),2)-20000.0<0.0000000000001) m1(j,i)=Vec3b(0,0,255); } } imshow("1",m1); waitKey(0); return 0; }