图像分配和释放与访问图像元素

来源:互联网 发布:什么叫淘宝流量 编辑:程序博客网 时间:2024/05/02 00:47

引言

本节主要介绍OpenCV中图像分配、释放几种方式和访问图像元素实现方式。

分配和释放图像

对图像分配和释放操作可以通过以下几种方式实现。

1. 分配图像

分配图像的函数原型为:

Iplimage* cvCreateImage(CvSize size, int depth, int channels);
其中size可使用函数cvSize(width,height);depth 为像素深度用比特表示,包括以下几种:

  • IPL_DEPTH_8U:无符号8位整数(8u)
  • IPL_DEPTH_8S:有符号8位整数(8s)
  • IPL_DEPTH_16U:无符号16位整数(16u)
  • IPL_DEPTH_16S:有符号16位整数(16s)
  • IPL_DEPTH_32S:有符号32位整数(32s)
  • IPL_DEPTH_32F:32位浮点数单精度(32f)
  • IPL_DEPTH_64F:64位浮点数双精度(64f)

channels 为每个像素值的通道数,可以是1,2,3或4.通道是交叉排列的,一幅彩色图通常的排列顺序是B0G0R0B1G1R1B2G2R2.........

例如:分配一个单通道单字节图像的语句和一个3通道浮点数图像的语句是

Ipllmage *im1 = cvCreateImage(cvGet(640,480),IPL_DEPTH_8U,1); //单通道单字节图像Ipllmage *im2 = cvCreateImage(cvGet(640,480),IPL_DEPTH_32F,3); //3通道浮点数图像

2. 释放图像

释放图像的函数原型为:

void cvReleaseImage(IplImage**);

例如:

Ipllmage *im1 = cvCreateImage(cvGet(640,480),IPL_DEPTH_8U,1); //单通道单字节图像cvReleaseImage(&im1);

3. 复制图像

复制图像的函数原型为:

Ipllmage*cvCloneImage(Ipllmage*);

4. 设置或得到感兴趣区域ROI

函数原型分别为:

void cvSetImageROI(Ipllmage* image, CvRect rect);void cvResedtImageROI(Ipllmage* image);CvRect cvGetImageROI(const Ipllmage* image);
大多数OpenCV函数都支持ROI .

实例:图像反转

图像反转代码

#include <opencv/cv.h>#include <opencv/highgui.h>int main(int argc, char *argv[]){  IplImage* img = cvLoadImage("test.jpg");   if(!img){    printf("Could not load image file\n");    exit(0);  }   int step,channels;  uchar *data;  step      = img->widthStep;  data      = (uchar *)img->imageData;  cvNamedWindow("Win", CV_WINDOW_AUTOSIZE);   cvMoveWindow("Win", 100, 100);  for(int i=0;int i<img->height;i++)     for(int j=0;j<img->width;j++)       for(int k=0;k<img->nChannels;k++)    data[i*step+j*(img->nChannels)+k]=255-data[i*step+j*(img->nChannels)+k];  cvShowImage("Win", img );  cvWaitKey(0);  cvReleaseImage(&img );  return 0;}
输出结果效果:

           

图1 原始图像                      图2测试图像输出结果

访问图像元素

假设要访问图像第k通道,第i行、第j列的像素值,那么可采用的方式如下所示:

1.间接方式

这是一种常用的方式,可以访问任何类型的图像,但是效率不高。

对单通道单字节图像可采用如下语句:

Ipllmage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);CvScale  sVal = cvGet2D(img,i,j); // get the (i,j) pixel values.val[0] = 120;cvSet2D(img,i,j,sval); // set the (i,j) pixel value
对多通道单字节/浮点数图像可采用如下语句:

Ipllmage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);CvScale  sVal = cvGet2D(img,i,j); // get the (i,j) pixel values.val[0] = 120;s.val[1] = 120;s.val[2] = 120;cvSet2D(img,i,j,sval); // set the (i,j) pixel value

2.直接方式

直接访问效率高,但容易出错

对单通道单字节图像可采用如下语句:

Ipllmage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);((uchar*)(img->imageData +i*img->widthStep))[j] = 120;
对多通道单字节/浮点数图像可采用如下语句:

Ipllmage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);((uchar*)(img->imageData +i*img->widthStep))[j*img->nChannels+ 0] = 120; //B((uchar*)(img->imageData +i*img->widthStep))[j*img->nChannels+ 1] = 120; //G((uchar*)(img->imageData +i*img->widthStep))[j*img->nChannels+ 2] = 120; //R

3.用指针访问

在某种情况下,这是简单高效的访问方式。

对单通道单字节图像可采用如下语句:

Ipllmage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);int height = img->height;int width  = img->width;int step   = img->widthStep/sizeof(uchar);uchar* data =(uchar*)img->imageData;data[i*step +j] =120; 
对多通道单字节/浮点数图像可采用如下语句:
Ipllmage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);int height = img->height;int width  = img->width;int step   = img->widthStep/sizeof(uchar);int channels = img->nChannels;uchar* data =(uchar*)img->imageData;data[i*step + j*channels + k] =120; 


关于Image Engineering & Computer Vision的更多讨论与交流,敬请关注本博和新浪微博songzi_tea.


原创粉丝点击