- cvLoadImage函数使用方法
这一函数是最基本的载入图像函数,此时会自动分配内存返回给image,也即是说image不用用cvCreateImage函数申请内存。一般情况
IplImage* cvLoadImage( const char* filename, int flags=CV_LOAD_IMAGE_COLOR );
cvLoadImage( filename, -1 ); 默认读取图像的原通道数
cvLoadImage( filename, 0 ); 强制转化读取图像为灰度图
cvLoadImage( filename, 1 ); 读取彩色图
用默认参数载入的图像文件自动转换为三通道,即使源图像是“单通道的图像”,nchannels的含义是OPENCV中图像的通道是没错的,关键是保存在硬盘上的图像文件在载入OPENCV的时候载入参数决定了那个图像数据是几个通道。即使保存了一个对OPENCV来说是一个单通道的灰度图像文件,但在读取时却以彩色图像文件读取了。就是说黑白图像也可以载入到OPENCV中成为三通道的图像。
filename :要被读入的文件的文件名(包括后缀);
flags :指定读入图像的颜色和深度:
指定的颜色可以将输入的图片转为3信道(CV_LOAD_IMAGE_COLOR), 单信道 (CV_LOAD_IMAGE_GRAYSCALE), 或者保持不变(CV_LOAD_IMAGE_ANYCOLOR)。
选中CV_LOAD_IMAGE_ANYDEPTH(=2),则输入图像格式可以为8位无符号,16位无符号,32位有符号或者32位浮点型。
如果输入有冲突的标志,将采用较小的数字值。比如
CV_LOAD_IMAGE_COLOR | CV_LOAD_IMAGE_ANYCOLOR 将载入3信道图。
CV_LOAD_IMAGE_ANYCOLOR和CV_LOAD_IMAGE_UNCHANGED是等值的。但是,CV_LOAD_IMAGE_ANYCOLOR有着可以和CV_LOAD_IMAGE_ANYDEPTH同时使用的优点,所以CV_LOAD_IMAGE_UNCHANGED不再使用了。
如果想要载入最真实的图像,选择CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR。
函数cvLoadImage从指定文件读入图像,返回读入图像的指针。目前支持如下文件格式:
Windows位图文件 - BMP, DIB;
JPEG文件 - JPEG, JPG, JPE;
便携式网络图片- PNG;
便携式图像格式 - PBM,PGM,PPM;
Sun rasters - SR,RAS;
TIFF文件 - TIFF,TIF;
OpenEXR HDR 图片 - EXR;
JPEG 2000 图片- jp2。
cvSaveImage
保存图像到文件
int cvSaveImage( const char* filename, const CvArr* image );
filename
文件名。
image
要保存的图像。
函数cvSaveImage保存图像到指定文件。图像格式的的选择依赖于filename的扩展名,请参考cvLoadImage。只有8位单通道或者3通道(通道顺序为'BGR' )可以使用这个函数保存。如果格式,深度或者通道不符合要求,请先用cvCvtScale 和cvCvtColor转换;或者使用通用的cvSave保存图像为XML或者YAML格式。
特别提醒!由于TIFF文件格式比较混乱,难以统一,此函数读取TIFF图片可能会失败。
2.轮廓提取
cvFindContours(edge,stor,&cont,sizeof(CvContour),CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0));
输入为8比特单通道的源二值图像。如果不是二值图像,非零像素作为1处理,0像素保存不变。从一个灰度图像得到二值图像的函数有:cvThreshold,cvAdaptiveThreshold和cvCanny。处理之前最好先对图像进行预处理,比如二值化和Canny检测,如果不进行处理,将会有很大一部分白色区域。
函数中最后一个参数offset
偏移量,用于移动所有轮廓点。当轮廓是从图像的ROI提取的,并且需要在整个图像中分析时,这个参数将很有用。
cvThreshold(image,edge,100,255,CV_THRESH_BINARY);
cvCanny(image,edge,5,10,3); //如果不加二值化和边缘等处理,cvFindCountours会把非零设为255,其余设为0,则图像一片白
//下面代码找到轮廓
CvMemStorage*stor;
CvSeq*cont=NULL;
CvSeqReader reader;
stor=cvCreateMemStorage(0);
cont=cvCreateSeq(CV_SEQ_ELTYPE_POINT,sizeof(CvSeq),sizeof(CvPoint),stor);
IplImage *pContourImg = cvCreateImage(cvGetSize(edge),IPL_DEPTH_8U,3);
cvCvtColor(image,pContourImg,CV_GRAY2BGR);
//找到所有轮廓,返回轮廓个数
int nc=cvFindContours(edge,stor,&cont,sizeof(CvContour),CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0));
for (;cont;cont=cont->h_next)
{
//点数大于200
if (cont->total<200)
{
continue;
}
//画出轮廓
cvDrawContours(pContourImg,cont,CV_RGB(255,0,0),CV_RGB(255,0,0),0,1,8,cvPoint(0,0));
}
cvNamedWindow("Contours",1);
cvShowImage("Contours",pContourImg);
cvWaitKey(0);
cvReleaseImage(&edge);
cvReleaseImage(&pContourImg);
cvDestroyWindow("Contours");