图像处理
分配与释放图像空间
分配图像空间:
IplImage* cvCreateImage(CvSize size, int depth, int channels);
举例:
// 分配一个单通道字节图像
IplImage* img1=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
// 分配一个三通道浮点图像
IplImage* img2=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
释放图像空间:
IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
cvReleaseImage(&img);
复制图像:
IplImage* img1=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
IplImage* img2;
img2=cvCloneImage(img1);
设定/获取兴趣区域:
void
void
vRect cvGetImageROI(const IplImage* image);
大部分OpenCV函数都支持ROI.
设定/获取兴趣通道:
void cvSetImageCOI(IplImage* image, int coi); // 0=all
int cvGetImageCOI(const IplImage* image);
大部分OpenCV函数暂不支持COI.
读取存储图像
从文件中载入图像:
载入图像默认转为3通道彩色图像. 如果不是,则需加flag:
图像存储为图像文件:
输入文件格式由文件扩展名决定.
存取图像元素
假设需要读取在i行j列像点的第k通道. 其中, 行数i的范围为[0, height-1], 列数j的范围为[0, width-1], 通道k的范围为[0, nchannels-1].
间接存取: (比较通用, 但效率低, 可读取任一类型图像数据)
对单通道字节图像:
IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
CvScalar s;
s=cvGet2D(img,i,j); // get the (i,j) pixel value
printf("intensity=%f\n",s.val[0]);
s.val[0]=111;
cvSet2D(img,i,j,s); // set the (i,j) pixel value
对多通道浮点或字节图像:
IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
CvScalar s;
s=cvGet2D(img,i,j); // get the (i,j) pixel value
printf("B=%f, G=%f, R=%f\n",s.val[0],s.val[1],s.val[2]);
s.val[0]=111;
s.val[1]=111;
s.val[2]=111;
cvSet2D(img,i,j,s); // set the (i,j) pixel value
直接存取: (效率高, 但容易出错)
对单通道字节图像:
IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
((uchar *)(img->imageData + i*img->widthStep))[j]=111;
对多通道字节图像:
IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 0]=111; // B
((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 1]=112; // G
((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 2]=113; // R
对多通道浮点图像:
IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 0]=111; // B
((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 1]=112; // G
((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 2]=113; // R
用指针直接存取 : (在某些情况下简单高效)
对单通道字节图像:
IplImage* img
int height
int width
int step
uchar* data
data[i*step+j] = 111;
对多通道字节图像:
IplImage* img
int height
int width
int step
int channels
uchar* data
data[i*step+j*channels+k] = 111;
对单通道浮点图像(假设用4字节调整):
IplImage* img
int height
int width
int step
int channels
float * data
data[i*step+j*channels+k] = 111;
使用 c++ wrapper 进行直接存取: (简单高效)
对单/多通道字节图像,多通道浮点图像定义一个 c++ wrapper:
template<class T> class Image
{
};
typedef struct{
} RgbPixel;
typedef struct{
} RgbPixelFloat;
typedef Image<RgbPixel>
typedef Image<RgbPixelFloat>
typedef Image<unsigned char>
typedef Image<float>
单通道字节图像:
IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
BwImage imgA(img);
imgA[i][j] = 111;
多通道字节图像:
IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
RgbImage
imgA[i][j].b = 111;
imgA[i][j].g = 111;
imgA[i][j].r = 111;
多通道浮点图像:
IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
RgbImageFloat imgA(img);
imgA[i][j].b = 111;
imgA[i][j].g = 111;
imgA[i][j].r = 111;
图像转换
转为灰度或彩色字节图像:
cvConvertImage(src, dst, flags=0);
转换彩色图像为灰度图像:
使用OpenCV转换函数:
cvCvtColor(cimg,gimg,CV_BGR2GRAY); // cimg -> gimg
直接转换:
for(i=0;i<cimg->height;i++) for(j=0;j<cimg->width;j++)
颜色空间转换:
cvCvtColor(src,dst,code); // src -> dst
e.g.: CV_BGR2GRAY, CV_BGR2HSV, CV_BGR2Lab
绘图命令
画长方体:
// 用宽度为1的红线在(100,100)与(200,200)之间画一长方体
cvRectangle(img, cvPoint(100,100), cvPoint(200,200), cvScalar(255,0,0), 1);
画圆:
// 在(100,100)处画一半径为20的圆,使用宽度为1的绿线
cvCircle(img, cvPoint(100,100), 20, cvScalar(0,255,0), 1);
画线段:
// 在(100,100)与(200,200)之间画绿色线段,宽度为1
cvLine(img, cvPoint(100,100), cvPoint(200,200), cvScalar(0,255,0), 1);
画一组线段:
CvPoint
CvPoint
CvPoint* curveArr[2]={curve1, curve2};
int
int
int
int
cvPolyLine(img,curveArr,nCurvePts,nCurves,isCurveClosed,cvScalar(0,255,255),lineWidth);
画内填充色的多边形:
cvFillPoly(img,curveArr,nCurvePts,nCurves,cvScalar(0,255,255));
添加文本:
CvFont font;
double hScale=1.0;
double vScale=1.0;
int
cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX|CV_FONT_ITALIC, hScale,vScale,0,lineWidth);
cvPutText (img,"My comment",cvPoint(200,400), &font, cvScalar(255,255,0));
Other possible fonts:
CV_FONT_HERSHEY_SIMPLEX, CV_FONT_HERSHEY_PLAIN,
CV_FONT_HERSHEY_DUPLEX, CV_FONT_HERSHEY_COMPLEX,
CV_FONT_HERSHEY_TRIPLEX, CV_FONT_HERSHEY_COMPLEX_SMALL,
CV_FONT_HERSHEY_SCRIPT_SIMPLEX, CV_FONT_HERSHEY_SCRIPT_COMPLEX,