Tuesday 15 May 2007

opencv编程入门2

C程序实例




////////////////////////////////////////////////////////////////////////
//
// hello-world.cpp
//
// 一个简单的OpenCV程序
// 它从一个文件中读取图像,将色彩值颠倒,并显示结果.
//
////////////////////////////////////////////////////////////////////////
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <cv.h>
#include <highgui.h>


int main(int argc, char *argv[])
{
   IplImage* img = 0;
   int height,width,step,channels;
   uchar *data;
   int i,j,k;

   if(argc<2){
     printf("Usage: main <image-file-name>\n\7");
     exit(0);
   }

   // 载入图像  
   img=cvLoadImage(argv[1]);
   if(!img){
     printf("Could not load image file: %s\n",argv[1]);
     exit(0);
   }

   // 获取图像数据
   height     = img->height;
   width      = img->width;
   step       = img->widthStep;
   channels   = img->nChannels;
   data       = (uchar *)img->imageData;
   printf("Processing a %dx%d image with %d channels\n",height,width,channels);

   // 创建窗口
   cvNamedWindow("mainWin", CV_WINDOW_AUTOSIZE);
   cvMoveWindow("mainWin", 100, 100);

   // 反色图像
   for(i=0;i<height;i++) for(j=0;j<width;j++) for(k=0;k<channels;k++)
     data[i*step+j*channels+k]=255-data[i*step+j*channels+k];

   // 显示图像
   cvShowImage("mainWin", img );

   // wait for a key
   cvWaitKey(0);

   // release the image
   cvReleaseImage(&img );
   return 0;
}





GUI命令



窗口管理




  • 创建并放置一个窗口:
       cvNamedWindow("win1", CV_WINDOW_AUTOSIZE); 
       cvMoveWindow("win1", 100, 100); // 以屏幕左上角为起点的偏移量



  • 读入图像:
       IplImage* img=0; 
       img=cvLoadImage(fileName);
       if(!img) printf("Could not load image file: %s\n",fileName);



  • 显示图像:
       cvShowImage("win1",img);

    可显示彩色或灰度的字节/浮点图像。 彩色图像数据认定为BGR顺序.




  • 关闭窗口:
       cvDestroyWindow("win1");



  • 改变窗口尺寸:
       cvResizeWindow("win1",100,100); // 新的宽/高值(象素点)






输入设备




  • 响应鼠标事件:

    • 定义鼠标handler:
         void mouseHandler(int event, int x, int y, int flags, void* param)
         {
           switch(event){
             case CV_EVENT_LBUTTONDOWN:
               if(flags & CV_EVENT_FLAG_CTRLKEY)
                 printf("Left button down with CTRL pressed\n");
               break;

             case CV_EVENT_LBUTTONUP:
               printf("Left button up\n");
               break;
           }
         }

         // x,y:    针对左上角的像点坐标

         // event: CV_EVENT_LBUTTONDOWN,    CV_EVENT_RBUTTONDOWN,    CV_EVENT_MBUTTONDOWN,
         //         CV_EVENT_LBUTTONUP,      CV_EVENT_RBUTTONUP,      CV_EVENT_MBUTTONUP,
         //         CV_EVENT_LBUTTONDBLCLK, CV_EVENT_RBUTTONDBLCLK, CV_EVENT_MBUTTONDBLCLK,
         //         CV_EVENT_MOUSEMOVE:

         // flags: CV_EVENT_FLAG_CTRLKEY, CV_EVENT_FLAG_SHIFTKEY, CV_EVENT_FLAG_ALTKEY,
         //         CV_EVENT_FLAG_LBUTTON, CV_EVENT_FLAG_RBUTTON,   CV_EVENT_FLAG_MBUTTON



    • 注册handler:
         mouseParam=5;
         cvSetMouseCallback("win1",mouseHandler,&mouseParam);







  • 响应键盘事件:

    • 键盘没有事件handler.



    • 直接获取键盘操作:
         int key;
         key=cvWaitKey(10); // 输入等待10ms



    • 等待按键并获取键盘操作:
         int key;
         key=cvWaitKey(0); // 无限等待键盘输入



    • 键盘输入循环:
         while(1){
           key=cvWaitKey(10);
           if(key==27) break;

           switch(key){
             case 'h':
               ...
               break;
             case 'i':
               ...
               break;
           }
         }






  • 处理滚动条事件:

    • 定义滚动条handler:
         void trackbarHandler(int pos)
         {
           printf("Trackbar position: %d\n",pos);
         }



    • 注册handler:
         int trackbarVal=25;
         int maxVal=100;
         cvCreateTrackbar("bar1", "win1", &trackbarVal ,maxVal , trackbarHandler);



    • 获取滚动条当前位置:
         int pos = cvGetTrackbarPos("bar1","win1");



    • 设定滚动条位置:
         cvSetTrackbarPos("bar1", "win1", 25);








OpenCV基础数据结构



图像数据结构




  • IPL 图像:
    IplImage
       |-- int   nChannels;      // 色彩通道数(1,2,3,4)
       |-- int   depth;          // 象素色深:
       |                        //    IPL_DEPTH_8U, IPL_DEPTH_8S,
       |                        //    IPL_DEPTH_16U,IPL_DEPTH_16S,
       |                        //    IPL_DEPTH_32S,IPL_DEPTH_32F,
       |                        //    IPL_DEPTH_64F
       |-- int   width;          // 图像宽度(象素点数)
       |-- int   height;         // 图像高度(象素点数)

       |-- char* imageData;     // 指针指向成一列排列的图像数据
       |                        // 注意色彩顺序为BGR
       |-- int   dataOrder;      // 0 - 彩色通道交叉存取 BGRBGRBGR,
       |                        // 1 - 彩色通道分隔存取 BBBGGGRRR
       |                        // 函数cvCreateImage只能创建交叉存取的图像
       |-- int   origin;         // 0 - 起点为左上角,
       |                        // 1 - 起点为右下角(Windows位图bitmap格式)
       |-- int   widthStep;      // 每行图像数据所占字节大小
       |-- int   imageSize;      // 图像数据所占字节大小 = 高度*每行图像数据字节大小
       |-- struct _IplROI *roi;// 图像ROI. 若不为NULL则表示需要处理的图像
       |                        // 区域.
       |-- char *imageDataOrigin; // 指针指向图像数据原点
       |                           // (用来校准图像存储单元的重新分配)
       |
       |-- int   align;          // 图像行校准: 4或8字节校准
       |                        // OpenCV不采用它而使用widthStep
       |-- char colorModel[4]; // 图像色彩模型 - 被OpenCV忽略






矩阵与向量




  • 矩阵:
    CvMat                       // 2维数组
       |-- int    type;           // 元素类型(uchar,short,int,float,double)
       |-- int    step;           // 一行所占字节长度
       |-- int    rows, cols;     // 尺寸大小
       |-- int    height, width; // 备用尺寸参照
       |-- union data;
          |-- uchar*   ptr;      // 针对unsigned char矩阵的数据指针
           |-- short*   s;        // 针对short矩阵的数据指针
           |-- int*     i;        // 针对integer矩阵的数据指针
           |-- float*   fl;       // 针对float矩阵的数据指针
           |-- double* db;       // 针对double矩阵的数据指针


    CvMatND                     // N-维数组
       |-- int    type;           // 元素类型(uchar,short,int,float,double)
       |-- int    dims;           // 数组维数
       |-- union data;
       |    |-- uchar*   ptr;      // 针对unsigned char矩阵的数据指针
       |    |-- short*   s;        // 针对short矩阵的数据指针
       |    |-- int*     i;        // 针对integer矩阵的数据指针
       |    |-- float*   fl;       // 针对float矩阵的数据指针
       |    |-- double* db;       // 针对double矩阵的数据指针
       |
       |-- struct dim[];         // 每个维的信息
           |-- size;             // 该维内元素个数
           |-- step;             // 该维内元素之间偏移量


    CvSparseMat // 稀疏N维数组



  • 通用数组:
    CvArr*      // 仅作为函数参数,说明函数接受多种类型的数组,例如:
                //     IplImage*, CvMat* 或者 CvSeq*.
                // 只需通过分析数组头部的前4字节便可确定数组类型




  • 标量:
    CvScalar
       |-- double val[4]; //4D向量

    初始化函数:


    CvScalar s = cvScalar(double val0, double val1=0, double val2=0, double val3=0);

    举例:


    CvScalar s = cvScalar(20.0);
    s.val[0]=10.0;

    注意:初始化函数与数据结构同名,只是首字母小写. 它不是C++的构造函数.






其他数据结构




  • 点:
    CvPoint       p = cvPoint(int x, int y);
    CvPoint2D32f p = cvPoint2D32f(float x, float y);
    CvPoint3D32f p = cvPoint3D32f(float x, float y, float z);
    例如:
    p.x=5.0;
    p.y=5.0;



  • 长方形尺寸:
    CvSize        r = cvSize(int width, int height);
    CvSize2D32f   r = cvSize2D32f(float width, float height);



  • 带偏移量的长方形尺寸:
    CvRect        r = cvRect(int x, int y, int width, int height);



No comments:

Post a Comment