zoukankan      html  css  js  c++  java
  • OpenCV 基础知识------图像创建、访问、转换

    cvCreateImage函数-- Cxcore数组操作

    创建头并分配数据

    IplImage* cvCreateImage( CvSize size, int depth, int channels ); 

    size

    图像宽、高.

    depth 

    图像元素的位深度,可以是下面的其中之一:

    IPL_DEPTH_8U - 无符号8位整型

    IPL_DEPTH_8S - 有符号8位整型

    IPL_DEPTH_16U - 无符号16位整型

    IPL_DEPTH_16S - 有符号16位整型

    IPL_DEPTH_32S - 有符号32位整型

    IPL_DEPTH_32F - 单精度浮点数

    IPL_DEPTH_64F - 双精度浮点数

    channels 

    每个元素(像素)的颜色通道数量.可以是 1, 2, 3 4.通道是交叉存取的,例如通常的彩色图像数据排列是:

    b0 g0 r0 b1 g1 r1 ...

    虽然通常 IPL 图象格式可以存贮非交叉存取的图像,并且一些OpenCV 也能处理他, 但是这个函数只能创建交叉存取图像.

    函数 cvCreateImage 创建头并分配数据,这个函数是下列的缩写型式

    header = cvCreateImageHeader(size,depth,channels); 
    cvCreateData(header); //只是创建空间,并不会初始化空间内的数据 
    
    

    cvCopy函数-- Cxcore数组操作

    拷贝一个数组给另一个数组

    void cvCopy( const CvArr* src, CvArr* dst, const CvArr* mask=NULL ); 

    src

    输入数组。

    dst

    输出数组。

    mask

    操作掩码是8比特单通道的数组,它指定了输出数组中被改变的元素。

    函数cvCopy从输入数组中复制选定的成分到输出数组:

    如果mask(I)!=0,dst(I)=src(I)

    如果输入输出数组中的一个是IplImage类型的话,其ROICOI将被使用。输入输出数组必须是同样的类型、维数和大小。函数也可以用来复制散列数组(这种情况下不支持mask)。

    
    

    cvSaveImage函数-- HighGUI读取与保存图像

    保存图像到文件

    int cvSaveImage( const char* filename, const CvArr* image ); 

    filename 

    文件名。

    image 

    要保存的图像。

    函数cvSaveImage保存图像到指定文件。图像格式的的选择依赖于filename的扩展名,请参考cvLoadImage。只有8位单通道或者3通道(通道顺序为'BGR' )可以使用这个函数保存。如果格式,深度或者通道不符合要求,请先用cvCvtScale cvCvtColor转换;或者使用通用的cvSave保存图像为XML或者YAML格式。

    图像文件读入和显示中用到的函数

    cvLoadImage函数-- HighGUI读取与保存图像

    从文件中读取图像

     

    #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

     

    IplImage* cvLoadImage( const char* filename, int flags=CV_LOAD_IMAGE_COLOR );

    filename 

    要被读入的文件的文件名。

    flags 

    指定读入图像的颜色和深度:

    指定的颜色可以将输入的图片转为3信道(CV_LOAD_IMAGE_COLOR), 单信道 (CV_LOAD_IMAGE_GRAYSCALE), 或者保持不变(CV_LOAD_IMAGE_ANYCOLOR)

    深度指定输入的图像是否转为每个颜色信道每象素8位,(OpenCV的早期版本一样),或者同输入的图像一样保持不变。

    选中CV_LOAD_IMAGE_ANYDEPTH,则输入图像格式可以为8位无符号,16位无符号,32位有符号或者32位浮点型。

    如果输入有冲突的标志,将采用较小的数字值。比如CV_LOAD_IMAGE_COLOR | CV_LOAD_IMAGE_ANYCOLOR 将载入3信道图。CV_LOAD_IMAGE_ANYCOLORCV_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

    便携式图像格式 - PBMPGMPPM

    Sun rasters - SRRAS

    TIFF文件 - TIFFTIF;

    OpenEXR HDR 图片 - EXR;

    JPEG 2000 图片- jp2

    cvNamedWindow 函数-- HighGUI简单图形界面

    创建窗口

    int cvNamedWindow( const char* name, int flags=CV_WINDOW_AUTOSIZE );

    name 

    窗口的名字,它被用来区分不同的窗口,并被显示为窗口标题。

    flags 

    窗口属性标志。目前唯一支持的标志是CV_WINDOW_AUTOSIZE。当这个标志被设置后,用户不能手动改变窗口大小,窗口大小会自动调整以适合被显示图像(参考cvShowImage)。

    函数cvNamedWindow创建一个可以放置图像和trackbar的窗口。被创建的窗口可以通过它们的名字被引用。

    如果已经存在这个名字的窗口,这个函数将不做任何事情。

    cvShowImage 函数--HighGUI简单图形界面

    在指定窗口中显示图像

    void cvShowImage( const char* name, const CvArr* image );

    name

    窗口的名字。

    image

    被显示的图像。

    函数cvShowImage 在指定窗口中显示图像。如果窗口创建的时候被设定标志CV_WINDOW_AUTOSIZE,那么图像将以原始尺寸显示;否则,图像将被伸缩以适合窗口大小。

    cvDestroyWindow函数-- HighGUI简单图形界面

    销毁一个窗口

    void cvDestroyWindow( const char* name ); 

    name 

    要被销毁的窗口的名字。

    函数cvDestroyWindow销毁指定名字的窗口。

    cvWaitKey 函数--HighGUI简单图形界面

    等待按键事件

    int cvWaitKey( int delay=0 );

    delay 

    延迟的毫秒数。

    函数cvWaitKey无限制的等待按键事件(delay<=0时);或者延迟"delay"毫秒。返回值为被按键的值,如果超过指定时间则返回-1

    注释:这个函数是HighGUI中唯一能够获取和操作事件的函数,所以在一般的事件处理中,它需要周期地被调用,除非HighGUI被用在某些能够处理事件的环境中。

    译者注:比如在MFC环境下,这个函数不起作用

    cvReleaseImage函数-- Cxcore数组操作

    释放头和图像数据

    void cvReleaseImage( IplImage** image ); 

    image 

    双指针指向图像内存分配单元。

    函数 cvReleaseImage 释放头和图像数据,相似于:

    if( *image ) 
    { 
     cvReleaseData( *image ); 
     cvReleaseImageHeader( image ); 
    } 

    设置或得到感兴趣区域ROI 

    void  cvSetImageROI(IplImage* image,CvRect rect);  void cvResetImageROI(IplImage*  image);  CvRect cvGetImageROI(const IplImage* image);

    设置和得到感兴趣通道的COI 

    void  cvSetImageCOI(IplImage* image,int coi);  int cvGetImageCOI(const IplImage*  image);

    图像的读写 

    IplImage*  cvLoadImage(fileName,int flag); flag>0,载入图像强制为3通道彩色图像 flag=0,载入图像强制为单通道灰度图像  flag<0,载入图像由文件中的通道数决定  int cvSaveImage(fileName,const CvArr* img);  保存图像的格式由fileName的后缀名决定 如果保存成功返回非零数

    访问图像元素

    (访问图像第k通道,第i行,第j列的像素值,k[0,通道总数-1],i[0,height-1],j[0,width-1])

    • 间接方式(常用,可访问任意类型图像,访问效率不高)
      • CvScalar  s=cvGet2D(img,i,j);//获取值,CvScalar是一struct,里面只有一个double类型的val大小为4的数组
        • s.val[0]=111;//0位置表示G通道,1位置表示R通道,2位置表示B通道,  cvSet2D(img,i,j,s);//把值设置到实际图像中
    • 直接方式(访问效率高,易出错)
      • 单通道(cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);)
        • 直接获得或者修改((uchar*)(img->imageData+i*img->widthStep))[j]
      • 多通道(cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);)
        • 直接获得或者修改((uchar*)(img->imageData+i*img->widthStep))[j*img->nChannels+0]//B
        • 直接获得或者修改((uchar*)(img->imageData+i*img->widthStep))[j*img->nChannels+1]//G
        • 直接获得或者修改((uchar*)(img->imageData+i*img->widthStep))[j*img->nChannels+2]//R
      • 多通道浮点数(cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);)
        • 直接获得或者修改((float*)(img->imageData+i*img->widthStep))[j*img->nChannels+0]//B
        • 直接获得或者修改((float*)(img->imageData+i*img->widthStep))[j*img->nChannels+1]//G
        • 直接获得或者修改((float*)(img->imageData+i*img->widthStep))[j*img->nChannels+2]//R
      • 用指针直接访问(简单高效)
        • 单通道单字节(cvCreateImage(cvSize(640,480),IPL_DEPTH8U,1);)
          • int step=img->widthStep/sizeof(uchar);
          • uchar* data=(uchar*)img->imageData;
          • data[i*step+j]=111;
        • 多通道单字节(cvCreateImage(cvSize(640,480),IPL_DEPTH8U,3);)
          • int step=img->widthStep/sizeof(uchar);
          • int channels=img->nChannels;
          • uchar* data=(uchar*)img->imageData;
          • data[i*step+j*channels+k]=111;
        • 多通道浮点数(cvCreateImage(cvSize(640,480),IPL_DEPTH32F,3);)
          • int step=img->widthStep/sizeof(float);
          • int channels=img->nChannels;
          • float* data=(float*)img->imageData;
          • data[i*step+j*channels+k]=111;
      • c++外壳直接访问(简单高效)
        • 单通道单字节
          • BwImage imgA(img);
          • imgA[i][j]=111;
        • 多通道单字节
          • RgbImage imgB(img);
          • imgB[i][j].b=111;
          • imgB[i][j].g=111;
          • imgB[i][j].r=111;
        • 多通道浮点
          • RgbImageFloat  imgC(img);
          • imgC[i][j].b=111;
          • imgC[i][j].g=111;
          • imgC[i][j].r=111;

    图像转换

    • 灰度->彩色
      • cvConvertImage(src,dst,flags);
    • 彩色->灰度
    • 彩色空间转换

    绘制命令

    • 矩形
      • cvRectangle(img,cvPoint(100,100),cvPoint(200,200),cvScalar(255,0,0),1);
      • cvCircle(img,cvPoint(100,100),90,cvScalar(200,200,42),,7);
    • 线段
      • cvLine(img,cvPoint(100,100),cvPoint(300,400),cvScalar(32,135,56),12);
    • 多边形
      • CvPoint p1[]={10,10,  10,100, 100,100, 100,10};
      • CvPoint p2[]={30,30,  30,130, 130,130, 150,10};
      • CvPoint*  pointArr[2]={p1,p2};
      • int nCurvePts[2]={4,5};
      • int nCurves=2;
      • int isCurveClosed=1;
      • int lineWidth=1;
      • cvPolyLine(img,pointArr,nCurvePts,nCurves,cvScalar(0,0,255));
    • 填充多边形
      • cvFillPoly(img,pointArr,nCurvePts,nCurves,cvScalar(0,0,255));
    • 写字
      • CvFont font;
      • double hScale=1.0;
      • double vScale=1.0;
      • int lineWidth=1;
      • cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX|CV_FONT_ITALIC,hScale,vScale,0,lineWidth);
      • cvPutText(img,"Hello  World",cvPoint(200,400),&font,cvScalar(255,255,0));
      • 字体
        • CV_FONT_HERSHEY_SIMPLEX - normal size sans-serif font
        • CV_FONT_HERSHEY_PLAIN - small size sans-serif font
        • CV_FONT_HERSHEY_DUPLEX - normal size sans-serif font (more complex  than CV_FONT_HERSHEY_SIMPLEX)
        • CV_FONT_HERSHEY_COMPLEX - normal size serif font
        • CV_FONT_HERSHEY_TRIPLEX - normal size serif font (more complex than  CV_FONT_HERSHEY_COMPLEX)
        • CV_FONT_HERSHEY_COMPLEX_SMALL - smaller version of  CV_FONT_HERSHEY_COMPLEX
        • CV_FONT_HERSHEY_SCRIPT_SIMPLEX - hand-writing style font
        • CV_FONT_HERSHEY_SCRIPT_COMPLEX - more complex variant of  CV_FONT_HERSHEY_SCRIPT_SIMPLEX
    • 代码:

       

       

      #include "cv.h"

      #include "highgui.h"

      #include "stdio.h"

       

      void main(void)

      {

        IplImage* pImg; //声明IplImage指针

       

        char* filename = "E:学习OpenCVpictureLena.jpg"; //图像名

        pImg = cvLoadImage(filename,1) ;  //载入图像

       

        //看是否能成功载入

        if (pImg==0)

               printf("Can't find the picture!:(n"); //不能载入

        else

        {

               printf("Can find the image!:)n");  //成功载入

            IplImage* pImg2 = cvCreateImage(cvGetSize(pImg),

                                        pImg->depth,

                                        pImg->nChannels);

            cvCopy(pImg, pImg2, NULL);

       

                char* filename2 = "E:学习OpenCVpictureLena_New.jpg"; //图像名

            cvSaveImage(filename2, pImg2);//把图像写入文件

        

            cvNamedWindow( "Image", 1 );//创建窗口

            cvShowImage( "Image", pImg );//显示图像

               cvNamedWindow( "Image2", 1 );//创建窗

            cvShowImage( "Image2", pImg2 );//显示图像

           

            cvWaitKey(0); //等待按键

            

            cvDestroyWindow( "Image" );//销毁窗口

            cvReleaseImage( &pImg ); //释放图像   

               cvDestroyWindow( "Image2" );//销毁窗口

            cvReleaseImage( &pImg2 ); //释放图像

             }

      }

  • 相关阅读:
    Release COM Objects in AE
    图像相关系数
    Geoprocessor edit the featureclasses in memmory
    NetLogo AStar path finding
    IDL+C#三种调用方式
    Dictionary is not like a array
    C# DataGridView 禁止列排序
    工作总结
    (转)常见数据库设计(1)——字典数据
    碎碎念(3)
  • 原文地址:https://www.cnblogs.com/Anita9002/p/3885231.html
Copyright © 2011-2022 走看看