图像处理
IplImage* cvCreateImage(CvSize size, int depth, int channels);
size: cvSize(width,height);
depth: 像素深度: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U,
channels: 像素通道数. Can be 1, 2, 3 or 4.
示例:
// Allocate a 1-channel byte image
IplImage* img1=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
// Allocate a 3-channel float image
IplImage* img2=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
(2) 释放图像:
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);
(4) 设置/获取感兴趣区域ROI:
void
void
CvRect cvGetImageROI(const IplImage* image);
(5) 设置/获取感兴趣通道COI:
void cvSetImageCOI(IplImage* image, int coi); // 0=all
int cvGetImageCOI(const IplImage* image);
大多数OpenCV函数不支持 COI.
2、图像读写
IplImage* img=0;
OpenCV默认将读入的图像强制转换为一幅三通道彩色图像. 不过可以按以下方法修改读入方式:
img=cvLoadImage(fileName,flag);
(2) 保存图像:
if(!cvSaveImage(outFileName,img)) printf("Could not save: %s\n", outFileName);
保存的图像格式由 outFileName 中的扩展名确定.
3、访问图像像素
(1) 假设你要访问第k通道、第i行、第j列的像素。
(2) 间接访问: (通用,但效率低,可访问任意格式的图像)
对于单通道字节型图像
IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
CvScalar s;
s=cvGet2D(img,i,j);
printf("intensity=%f\n",s.val[0]);
s.val[0]=111;
cvSet2D(img,i,j,s);
对于多通道字节型/浮点型图像:
IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
CvScalar s;
s=cvGet2D(img,i,j); // get the (j,i) 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 (j,i) pixel value
(3) 直接访问: (效率高,但容易出错)
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
(4) 基于指针的直接访问: (简单高效)
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;
IplImage* img
int height
int width
int step
int channels
float * data
data[i*step+j*channels+k] = 111;
(5) 基于 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;