RGB图:R redG greenB blue每一种颜色,在视觉效果上,都可以用不同比例的 红 绿 蓝来合成彩色图像的每一个像素,都用 R G B 的不同比例来表示,这样的图像就是RGB图像
灰度图:每个像素只有一个采样颜色的图像,这类图像通常显示为从最暗黑色到最亮的白色的灰度。
二值图:指每个像素不是黑就是白,其灰度值没有中间过渡的图像。二值图像一般用来描述文字或者图形,其优点是占用空间少,缺点是,当表示人物,风景的图像时,二值图像只能描述其轮廓,不能描述细节。
色彩空间 参见http://www.docin.com/p-223967524.html 色彩空间转换原理。
void cvCvtColor(const CvArr* src, CvArr* dst, int code)
src 输入的8-bit, 16-bit 或 32-bit 单倍精度浮点数影像
dst 输出的8-bit, 16-bit 或 32-bit 单倍精度浮点数影像
code 色彩空间转换,通过定义CV_<src_color_space>2<dst_color_space>常数
RGB<--> GRAY ( CV_BGR2GRAY, CV_RGB2GRAY, CV_GRAY2BGR, CV_GRAY2RGB )
RGB <--> CIE XYZ.Rec 709 with D65 white point ( CV_BGR2XYZ, CV_RGB2XYZ, CV_XYZ2BGR, CV_XYZ2RGB )
RGB <--> YCrCb JPEG (or YCC) ( CV_BGR2YCrCb, CV_RGB2YCrCb, CV_YCrCb2BGR, CV_YCrCb2RGB )
RGB <--> HSV ( CV_BGR2HSV, CV_RGB2HSV, CV_HSV2BGR, CV_HSV2RGB )
RGB <--> HLS ( CV_BGR2HLS, CV_RGB2HLS, CV_HLS2BGR, CV_HLS2RGB )
RGB <--> CIE L*a*b* ( CV_BGR2Lab, CV_RGB2Lab, CV_Lab2BGR, CV_Lab2RGB )
RGB <--> CIE L*u*v* ( CV_BGR2Luv, CV_RGB2Luv, CV_Luv2BGR, CV_Luv2RGB )
Bayer ---> RGB ( CV_BayerBG2BGR, CV_BayerGB2BGR, CV_BayerRG2BGR, CV_BayerGR2BGR, CV_BayerBG2RGB, CV_BayerGB2RGB, CV_BayerRG2RGB, CV_BayerGR2RGB )
void cvThreshold( const CvArr* src, CvArr* dst, double threshold, double max_value, int threshold_type );
函数 cvThreshold 对单通道数组应用固定阈值操作。该函数的典型应用是对灰度图像进行阈值操作得到二值图像。(cvCmpS 也可以达到此目的) 或者是去掉噪声,例如过滤很小或很大象素值的图像点。本函数支持的对图像取阈值的方法由 threshold_type 确定。
src:原始数组 (单通道 , 8-bit of 32-bit 浮点数)
dst:输出数组,必须与 src 的类型一致,或者为cvThresholdcvThreshold 8-bit。
threshold:阈值
max_value:使用 CV_THRESH_BINARY 和 CV_THRESH_BINARY_INV 的最大值。
threshold_type:阈值类型 threshold_type=CV_THRESH_BINARY:
如果 src(x,y)>threshold ,dst(x,y) = max_value; 否则,dst(x,y)=0;
threshold_type=CV_THRESH_BINARY_INV:
如果 src(x,y)>threshold,dst(x,y) = 0; 否则,dst(x,y) = max_value.
threshold_type=CV_THRESH_TRUNC:
如果 src(x,y)>threshold,dst(x,y) = threshold; 否则dst(x,y) = src(x,y).
threshold_type=CV_THRESH_TOZERO: 如果src(x,y)>threshold,dst(x,y) = src(x,y) ; 否则 dst(x,y) = 0。
threshold_type=CV_THRESH_TOZERO_INV:
如果 src(x,y)>threshold,dst(x,y) = 0 ; 否则dst(x,y) = src(x,y).
int cvCreateTrackbar( const char* trackbar_name, const char* window_name, int* value, int count, CvTrackbarCallback on_change );
参数:
trackbar_name 被创建的trackbar名字。
window_name 窗口名字,这个窗口将为被创建trackbar的父对象。
value 整数指针,它的值将反映滑块的位置。这个变量指定创建时的滑块位置。
count 滑块位置的最大值。最小值一直是0。
on_change 每次滑块位置被改变的时候,被调用函数的指针。这个函数应该被声明为void Foo(int); 如果没有回调函数,这个值可以设为NULL。
函数cvCreateTrackbar用指定的名字和范围来创建trackbar(滑块或者范围控制),指定与trackbar位置同步的变量,并且指定当trackbar位置被改变的时候调用的回调函数。
被创建的trackbar默认显示在指定窗口的顶端,可以通过函数cvGetTrackbarPos来获取trackbar显示的位置信息,以及通过函数cvSetTrackbarPos来重新设置trackbar的显示位置
int cvFindContours( CvArr* image, CvMemStorage* storage, CvSeq** first_contour, intheader_size=sizeof(CvContour), int mode=CV_RETR_LIST,
intmethod=CV_CHAIN_APPROX_SIMPLE, CvPoint offset=cvPoint(0,0) );
函数cvFindContours从二值图像中检索轮廓,并返回检测到的轮廓的个数。first_contour的值由函数填充返回,它的值将为第一个外轮廓的指针,当没有轮廓被检测到时为NULL。其它轮廓可以使用h_next和v_next连接,从first_contour到达。
image
8比特单通道的源二值图像。非零像素作为1处理,0像素保存不变。从一个灰度图像得到二值图像的函数有:cvThreshold,cvAdaptiveThreshold和cvCanny。
storage
返回轮廓的容器。
first_contour
输出参数,用于存储指向第一个外接轮廓。
header_size
header序列的尺寸.如果选择method = CV_CHAIN_CODE, 则header_size >= sizeof(CvChain);其他,则header_size >= sizeof(CvContour)。
mode
检索模式,可取值如下:
CV_RETR_EXTERNAL:只检索最外面的轮廓;
CV_RETR_LIST:检索所有的轮廓,并将其放入list中;
CV_RETR_CCOMP:检索所有的轮廓,并将他们组织为两层:顶层是各部分的外部边界,第二层是空洞的边界;
CV_RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次。
method
边缘近似方法(除了CV_RETR_RUNS使用内置的近似,其他模式均使用此设定的近似算法)。可取值如下:
CV_CHAIN_CODE:以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)。
CV_CHAIN_APPROX_NONE:将所有的连码点,转换成点。
CV_CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分。
CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS:使用the flavors of Teh-Chin chain近似算法
的一种。
CV_LINK_RUNS:通过连接水平段的1,使用完全不同的边缘提取算法。使用CV_RETR_LIST检索模式能使用此方法。
offset
偏移量,用于移动所有轮廓点。当轮廓是从图像的ROI提取的,并且需要在整个图像中分析时,这个参数将很有用。
void cvDrawContours( CvArr *img, CvSeq* contour,CvScalar external_color, CvScalar hole_color,int max_level, int thickness=1,
int line_type=8, CvPoint offset=cvPoint(0,0) );
cvDrawContours:在图像上绘制外部和内部轮廓
函数cvDrawContours用于在图像上绘制外部和内部轮廓。当thickness >= 0 时,绘制轮廓线;否则填充由轮廓包围的部分。
img 要在其上绘制轮廓的图像。和在其他绘图函数里一样,轮廓是ROI的修剪结果。
contour 指向第一个轮廓的指针。
external_color 外轮廓的颜色。
hole_color 内轮廓的颜色。
max_level
画轮廓的最大层数。如果是0,只绘制contour;如果是1,将绘制contour后和contour同层的所有轮廓;如果是2,绘制contour后所有同层和低一层的轮廓,以此类推;如果值是负值,则函数并不绘制contour后的轮廓,但是将画出其子轮廓,一直到abs(max_level) - 1层。
thickness
绘制轮廓线的宽度。如果为负值(例如,等于CV_FILLED),则contour内部将被绘制。
line_type
轮廓线段的类型,具体查看cvLine的描述。
offset
按给定值移动所有点的坐标。
以下代码显示RGB原图,经过变换的灰度图、二值图、以及检测到的边缘。在二值图中,可通过Trackbar,调节阀值。
#include "cv.h"
#include "highgui.h"
IplImage *colorImg = NULL; //载入的图像
IplImage *grayImg = NULL; //灰度图像
IplImage *binaryImg = NULL; //二值图像
IplImage *edgeImg = NULL; //边缘
void track(int pos)
{
cvThreshold(grayImg, binaryImg, pos, 255, CV_THRESH_BINARY);
cvShowImage("binaryImg", binaryImg);
CvMemStorage *pcvMStorage = cvCreateMemStorage();
CvSeq *pcvSeq = NULL;
cvFindContours(binaryImg, pcvMStorage, &pcvSeq, sizeof(CvContour), CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cvPoint(0, 0));
// 画轮廓图
IplImage *pOutlineImage = cvCreateImage(cvGetSize(colorImg), IPL_DEPTH_8U, 3);
int nLevels = 5;
// 填充成白色
cvRectangle(pOutlineImage, cvPoint(0, 0), cvPoint(pOutlineImage->width, pOutlineImage->height), CV_RGB(255, 255, 255), CV_FILLED);
cvDrawContours(pOutlineImage, pcvSeq, CV_RGB(255, 0, 0), CV_RGB(0, 255, 0), nLevels, 2);
// 显示轮廓图
cvNamedWindow("edgeImg", CV_WINDOW_AUTOSIZE);
cvShowImage("edgeImg", pOutlineImage);
}
int main()
{
int startPos = 50;
int maxPos = 255;
cvNamedWindow("binaryImg");
cvNamedWindow("colorImg");
cvNamedWindow("grayImg");
colorImg = cvLoadImage("E:\\Visual Studio 2013\\Projects\\graychange\\rgb.jpg");//载入图片
cvShowImage("colorImg", colorImg);
grayImg = cvCreateImage(cvGetSize(colorImg), IPL_DEPTH_8U, 1);
binaryImg = cvCreateImage(cvGetSize(colorImg), IPL_DEPTH_8U, 1);
cvCvtColor(colorImg, grayImg, CV_BGR2GRAY);//将图像变为灰度图
cvShowImage("grayImg", grayImg);
cvCreateTrackbar("bar", "binaryImg", &startPos, maxPos, track); //注册一个滑条
cvWaitKey(0);
cvReleaseImage(&colorImg);
cvDestroyAllWindows();
return 0;
}