您的位置:首页 > 运维架构

OpenCv基础学习笔记之一[types_c.h][IplImage]

2014-08-05 12:55 337 查看
IplImage 说明:

IplImage 函数结构

typedef struct _IplImage
{
int nSize;
/* sizeof(IplImage) *//* IplImage大小 */
int ID;
/* version (=0)*//* 版本 (=0)*/
int nChannels;
/* Most of OpenCV functions support 1,2,3 or 4 channels *//* 大多数OPENCV函数支持1,2,3 或 4 个通道 */
int alphaChannel;
/* Ignored by OpenCV *//* 被OpenCV忽略 */
int depth;
/* Pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S,
IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported.  */
/* 像素的位深度: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U,IPL_DEPTH_16S,
IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F 可支持 */
char colorModel[4];
/* Ignored by OpenCV *//* 被OpenCV忽略 */
char channelSeq[4];
/* ditto *//* 被OpenCV忽略 */
int dataOrder;
/* 0 - interleaved color channels, 1 - separate color channels. cvCreateImage can only create interleaved images */
/* 0 - 交叉存取颜色通道, 1 - 分开的颜色通道. cvCreateImage只能创建交叉存取图像 */
int origin;
/* 0 - top-left origin,1 - bottom-left origin (Windows bitmaps style).  */
/* 0 - 顶—左结构,1 - 底—左结构 (Windows bitmaps 风格) */
int align;
/* Alignment of image rows (4 or 8). OpenCV ignores it and uses widthStep instead.    */
/* 图像行排列 (4 or 8). OpenCV 忽略它,使用 widthStep 代替 */
int width;
/* Image width in pixels.*//* 图像宽像素数 */
int height;
/* Image height in pixels.*//* 图像高像素数*/

struct _IplROI *roi;
/* Image ROI. If NULL, the whole image is selected. */
/* 图像感兴趣区域. 当该值非空只对该区域进行处理 */
struct _IplImage *maskROI;
/* Must be NULL. *//* 在 OpenCV中必须置NULL */
void *imageId;
/* 同上*/
struct _IplTileInfo *tileInfo;
/*同上*/

int imageSize;
/* Image data size in bytes(==image->height*image->widthStep in case of interleaved data)*/
/* 图像数据大小(在交叉存取格式下imageSize=image->height*image->widthStep),单位字节*/
char *imageData;
/* Pointer to aligned image data.*//* 指向排列的图像数据 */
int widthStep;
/* Size of aligned image row in bytes.*//* 排列的图像行大小,以字节为单位 */
int BorderMode[4];
/* Ignored by OpenCV.*//* 边际结束模式, 被OpenCV忽略 */
int BorderConst[4];
/* 同上 */

char *imageDataOrigin;
/* Pointer to very origin of image data(not necessarily aligned) - needed for correct deallocation */
/* 指针指向一个不同的图像数据结构(不是必须排列的),是为了纠正图像内存分配准备的 */
} IplImage;

元素说明: 



代码1

#include "cv.h"
#include "highgui.h"
int main()
{
IplImage    *srcImage;
srcImage = cvLoadImage("lena.jpg", CV_LOAD_IMAGE_UNCHANGED);

srcImage->origin = IPL_ORIGIN_BL;
printf("nSize          = %d \n", srcImage->nSize);//IplImage->nSize int
printf("ID             = %d \n", srcImage->ID);//IplImage->ID int
printf("nChannels      = %d \n", srcImage->nChannels);//IplImage->nChannels int
printf("alphaChannel   = %d \n", srcImage->alphaChannel);//IplImage->alphaChannel int
printf("depth          = %d \n\n", srcImage->depth);//IplImage->depth int

cvNamedWindow("Lena", 0);
cvShowImage("Lena", srcImage);
cvWaitKey(0);
cvDestroyAllWindows();
cvReleaseImage(&srcImage);
return 0;
}
结果:



Size :用处不明

ID :用处不明 srcImage->ID = 2; 可以赋值 保存读取后无反应。

nChannels : 灰色 1 彩色 3 通道。 opencv支持1,2,3或4 通道。

alphaChannel : 用处不明。

depth : OpenCV的图象类型:

IPL_DEPTH_8U 8bit unsigned integer (0 ~ 255)
IPL_DEPTH_8S
8bit signed integer (-128 ~ 127)
 IPL_DEPTH_16U 
16bit unsigned integer 
IPL_DEPTH_16S
16bit signed integer 
IPL_DEPTH_32S 
32bit signed integer
IPL_DEPTH_32F
32bit floating - point number
IPL_DEPTH_64F
64bit floating - point number
代码2

#include "cv.h"
#include "highgui.h"
int main()
{
IplImage    *srcImage;
srcImage = cvLoadImage("lena.jpg", CV_LOAD_IMAGE_UNCHANGED);

printf("colorModel[4]  = %s \n", srcImage->colorModel);//IplImage->colorModel char
printf("channelSeq[4]  = %s \n", srcImage->channelSeq);//IplImage->channelSeq char
printf("dataOrder      = %d \n\n", srcImage->dataOrder);//IplImage->dataOrder int

printf("origin         = %d \n\n", srcImage->origin);//IplImage->origin int
printf("align          = %d \n\n", srcImage->align);//IplImage->align int

printf("width          = %d \n", srcImage->width);//IplImage->width int
printf("height         = %d \n\n", srcImage->height);//IplImage->height int

cvNamedWindow("Lena", 0);
cvShowImage("Lena", srcImage);
cvWaitKey(0);
cvDestroyAllWindows();
cvReleaseImage(&srcImage);
cvReleaseImage(&srcImage1);
return 0;
}


结果



char colorModel[4]


#define CV_LOAD_IMAGE_UNCHANGED -1 原始图像
#define CV_LOAD_IMAGE_GRAYSCALE 0 灰度图像
#define CV_LOAD_IMAGE_COLOR 1 彩色
#define CV_LOAD_IMAGE_ANYDEPTH 2 任何彩度
#define CV_LOAD_IMAGE_ANYCOLOR 4 任何彩色
 读取原图后更改值后得出的结果。 
CV_LOAD_IMAGE_UNCHANGED” = “RGB”  

“[b][b]CV_LOAD_IMAGE_GRAYSCALE 
= “GRAYGRAY” [/b][/b]

[b]CV_LOAD_IMAGE_COLOR 
= “RGB” [/b]

[b]“[b]CV_LOAD_IMAGE_ANYDEPTH
= “GRAY”[/b][/b]

[b]“[b]CV_LOAD_IMAGE_ANYCOLOR [/b]
= “
[b]RGB[/b]
[/b]

char channelSeq[4]: 

CV_LOAD_IMAGE_UNCHANGED” = “BGR”  

“CV_LOAD_IMAGE_GRAYSCALE ” = “GRAY” 

“CV_LOAD_IMAGE_COLOR ” = “[b]BGR” [/b]

[b]“CV_LOAD_IMAGE_ANYDEPTH
= “
GRAY
[/b]

[b]CV_LOAD_IMAGE_ANYCOLOR [/b]
= “
[b]BGR[/b]
int dataOrder:

[b]这个成员变量定义了多通道图像数据存储时颜色数据的排列方式,dataOrder的取值可以是IPL_DATA_ORDER_PIXEL或者IPL_DATA_ORDER_PLANE,如果是IPL_DATA_ORDER_PIXEL,通道颜色数据排列将会是BGRBGR...的交错排列,如果是IPL_DATA_ORDER_PLANE,则每个通道的颜色值在一起,有几个通道,就有几个“颜色平面”。大多数情况下,通道颜色数据的排列是交错的。[/b]

#define
IPL_DATA_ORDER_PIXEL  0

srcImage->dataOrder = IPL_DATA_ORDER_PIXEL; <pre name="code" class="cpp" style="font-size:10px; line-height: 26px;">srcImage->dataOrder = 0;




#define
IPL_DATA_ORDER_PLANE  1

srcImage->dataOrder = IPL_DATA_ORDER_PLANE; <pre name="code" class="cpp" style="line-height: 26px;">srcImage->dataOrder = 1;




int origin: 

origin变量可以有两个取值:IPL_ORIGIN_TL或者IPL_ORIGIN_BL,分别代表图像坐标系原点在左上角或是左下角。相应的,在计算机视觉领域,一个重要的错误来源就是原点位置的定义不统一。例如,图像的来源不同,操作系统不同,视频解码codec不同,存储方式不同等等,都可以造成原点位置的变化。例如,你可能认为你正在从图像上面的脸部附近取样,但实际上你却在图像下方的裙子附近取样。最初时,就应该检查一下你的系统中图像的原点位置,这可以通过在图像上方画个形状等方式实现。下面更改值后的结果。

#define
IPL_ORIGIN_TL 0 

srcImage->origin = IPL_ORIGIN_TL;<pre name="code" class="cpp" style="line-height: 18px;">srcImage->origin = 0;





#define IPL_ORIGIN_BL 1

srcImage->origin = IPL_ORIGIN_BL; <pre name="code" class="cpp" style="line-height: 18px;">srcImage->origin = 1;






int align :widthStep
代替

int width:图像的宽

int height :图像的高

struct _IplROI *roi :

最后还有一个重要参数roi(region of interest 感兴趣的区域),这个参数是IplROI结构体类型的变量。IplROI结构体包含了xOffset,yOffset,height,width,coi成员变量,其中xOffset,yOffset是x,y坐标,coi代表channel of interest(感兴趣的通道)。有时候,OpenCV图像函数不是作用于整个图像,而是作用于图像的某一个部分。这是,我们就可以使用roi成员变量了。如果IplImage变量中设置了roi,则OpenCV函数就会使用该roi变量。如果coi被设置成非零值,则对该图像的操作就只作用于被coi指定的通道上了。不幸的是,许多OpenCV函数忽略了coi的值。

CVAPI(void) cvSetImageROI( IplImage* image, CvRect rect ); //这样就设置了一个ROI区域 

CVAPI(void) cvResetImageROI( IplImage* image ) ; //重置ROI区域

如:IplImage *pImg = cvLoadImage("1.jpg");  cvSetImageROI(pimg, cvRect(100,200,400,400)) ; 
实际
#include "cv.h"
#include "highgui.h"
int main()
{
IplImage *srcImage;
if ((srcImage = cvLoadImage("lena.jpg")) == NULL)
return -1;
IplImage *dstImage;
dstImage = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 1);
cvSet(dstImage, cvScalar(255));

cvRectangle(srcImage, cvPoint(0, srcImage->height / 2),
cvPoint(srcImage->width / 2 - 1, srcImage->height - 1),
CV_RGB(0, 0, 255), 2);

cvSetImageROI(srcImage,
cvRect(0, srcImage->height / 2, srcImage->width / 2, srcImage->height / 2));
cvSetImageROI(dstImage,
cvRect(0, 0, srcImage->width / 2, srcImage->height / 2));

cvSetImageCOI(srcImage, 1); // Blue Channel

cvCopy(srcImage, dstImage);

cvResetImageROI(srcImage);
cvResetImageROI(dstImage);
// cvSetImageCOI(srcImage, 0);

cvNamedWindow("lena RGB", CV_WINDOW_AUTOSIZE);
cvShowImage("lena RGB", srcImage);
cvNamedWindow("Blue channel", CV_WINDOW_AUTOSIZE);
cvShowImage("Blue channel", dstImage);

cvWaitKey(0);
cvDestroyAllWindows();
cvReleaseImage(&srcImage);
cvReleaseImage(&dstImage);
return 0;
}
结果



函数结构

typedef struct _IplROI
{
    int  coi; /* 0 - no COI (all channels are selected), 1 - 0th channel is selected ...*/
    int  xOffset;
    int  yOffset;
    int  width;
    int  height;
}
IplROI;

struct _IplImage *maskROI  :

void  *imageId :

struct _IplTileInfo *tileInfo  :

函数结构

typedef struct _IplTileInfo IplTileInfo;


int  imageSize :图像大小 imageSize = width × height × nChannels (宽*高*通道 = 图像大小)

char *imageData :用处不明

int  widthStep :

widthStep与CvMat中的step类似,是以字节数计算的图像的宽度。成员变量imageData则保存了指向图像数据区首地址的指针。

指图像一行的字节数 , 比如上一行的指针为uchar  *p1 ;那么对应的下一行指针为 p1+withstep。

注意: widthstep 不一定等于 nChannels * width    .     如对于3通道IPL_DEPTH_8U(即一个像素用3字节表示)
,   widthstep 可能不等于3*cols .

int  BorderMode[4]  :用处不明

int  BorderConst[4] :用处不明

char *imageDataOrigin :用处不明

相关的函数

IplImage* cvLoadImage( const char* filename, int iscolor);载入图像函数结构

IplImage* cvCreateImage( CvSize size, int depth, int channels );创建首地址并分配存储空间

IplImage* cvCreateImageHeader( CvSize size, int depth, int channels ) ;只分配IplImage结构

void cvCreateImageData( CvArr* arr ) 只分配图像数据内存

void cvReleaseImage( IplImage** image )将IplImage*型的变量值赋为NULL

void cvReleaseData( CvArr* arr
)图像数据释放

void
cvShowImage( const char* name, const CvArr* image );图像显示函数

int cvNamedWindow( const char* name, unsigned long flags );窗口定义函数

int
cvSaveImage( const char* filename, const CvArr* image );图像保存函数

实用

CvMat和IplImage的互相转化

CVAPI(IplImage*) cvGetImage( const CvArr* arr, IplImage* image_header ) ; 

CVAPI(CvMat*) cvGetMat( const CvArr* arr, CvMat* header, int* coi CV_DEFAULT(NULL), int allowND CV_DEFAULT(0)) ;

IplImage *pImg = cvLoadImage("1.jpg");
CvMat *pMat = cvCreateMatHeader(pImg->rows , pImg->cols , CV_8UC3); //这里只分配CvMat结构体
cvGetMat(pImg , pMat) ; //注意此时CvMat和IplImage共用数据部分!!! 如果release一个后,另一个也会没数据部分了
// ... process
cvReleaseImageHeader(&pImg) ; //只释放IplImage结构体
cvReleaseMat(&pMat); //释放CvMat结构体和数据内存

注意图像的存储结构:在imageData指向的内存中对于一般的RGB图像,如用cvLoadImage读来的一般的彩色图像存储的时候是交错方式   ,注意次序 BGRBGRBGR   ,  (而不是RGB的顺序) 
图像操作

熟悉函数结构

/* dst(mask) = src1(mask) + src2(mask) , 这个是对两个相同大小,数据类型,通道数的图像相加*/
CVAPI(void) cvAdd( const CvArr* src1, const CvArr* src2, CvArr* dst,
const CvArr* mask CV_DEFAULT(NULL));

/* dst(mask) = src(mask) + value , 这个是对图像的几个通道数分别加上固定值*/
CVAPI(void) cvAddS( const CvArr* src, CvScalar value, CvArr* dst,
const CvArr* mask CV_DEFAULT(NULL));代码

#include <opencv.hpp>//如果用的低版本,如opencv2.0及以下,头文件换成cv.h , cxcore.h , highgui.h
#include <memory>
using namespace std;

void fun(IplImage *pImg)
{
memset(pImg->imageData, 0, pImg->height * pImg->widthStep);
for (int i = pImg->height * 3 / 8; i<pImg->height * 5 / 8; ++i){
char *p = pImg->imageData + i * pImg->widthStep;
for (int j = 0; j<pImg->width; ++j){
p[j] = 255;
}
}
}
int main()
{
IplImage *pImg = cvLoadImage("lena.jpg");
cvShowImage("in", pImg);
CvScalar scalar = cvScalar(50, 30, 20); //存储顺序为BGR
CvRect rect = cvRect(pImg->width / 4, pImg->height / 4, pImg->width / 2, pImg->height / 2);
cvSetImageROI(pImg, rect);
IplImage *pMask = cvCreateImage(cvSize(rect.width, rect.height), IPL_DEPTH_8U, 1);
fun(pMask);
cvShowImage("mask", pMask);
cvWaitKey(0);

cvAddS(pImg, scalar, pImg, pMask);
//输出
cvResetImageROI(pImg);
cvShowImage("out", pImg);
cvWaitKey(0);
cvDestroyAllWindows();
cvReleaseImage(&pImg);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  opencv 数据结构