对视频流进行边缘检测

 对视频流进行边缘检测

 

  1. /* 
  2. 功能:从摄像头或者AVI文件中得到视频流,对视频流进行边缘检测,并输出结果。 
  3. */  
  4. #include "stdafx.h"  
  5. #include "cv.h"  
  6. #include "highgui.h"  
  7. #include <ctype.h>  
  8. #include <stdio.h>  
  9. int main( int argc, char** argv )  
  10. {  
  11.     IplImage* laplace = 0;  
  12.     IplImage* colorlaplace = 0;  
  13.     IplImage* planes[3] = { 0, 0, 0 };  // 多个图像面  
  14.     CvCapture* capture = 0;  
  15.     //CvCapture  
  16.     //  
  17.     //视频获取结构  
  18.     //typedef struct CvCapture CvCapture;  
  19.     //结构CvCapture 没有公共接口,它只能被用来作为视频获取函数的一个参数。  
  20.     // 下面的语句说明在命令行执行程序时,如果指定AVI文件,那么处理从  
  21.     // AVI文件读取的视频流,如果不指定输入变量,那么处理从摄像头获取  
  22.     // 的视频流  
  23.     /*     if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0]))) 
  24.     capture = cvCaptureFromCAM( argc == 2 ? argv[1][0] - '0' : 0 ); 
  25.     else if( argc == 2 ) 
  26.     capture = cvCaptureFromAVI( argv[1] ); */  
  27.     //capture = cvCaptureFromAVI( "3.avi" );  
  28.   
  29.     if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0])))  
  30.         capture = cvCaptureFromCAM( argc == 2 ? argv[1][0] - '0' : 0 );  
  31.     else if( argc == 2 )  
  32.         capture = cvCaptureFromAVI( argv[1] );   
  33.   
  34.     if( !capture )  
  35.     {  
  36.         fprintf(stderr,"Could not initialize capturing.../n");  
  37.         return -1;  
  38.     }  
  39.     cvNamedWindow( "Laplacian", 0 );  
  40.     // 循环捕捉,直到用户按键跳出循环体  
  41.     for(;;)  
  42.     {  
  43.         IplImage* frame = 0;  
  44.         int i;  
  45.         //cvQueryFrame  
  46.         //  
  47.         //从摄像头或者文件中抓取并返回一帧  
  48.         //IplImage* cvQueryFrame( CvCapture* capture );  
  49.         //capture   
  50.         //视频获取结构。  
  51.         //函数cvQueryFrame从摄像头或者文件中抓取一帧,然后解压并返回这一帧。  
  52.         //这个函数仅仅是函数cvGrabFrame和函数cvRetrieveFrame在一起调用的组合。  
  53.         //返回的图像不可以被用户释放或者修改。 抓取后,capture被指向下一帧,  
  54.         //可用cvSetCaptureProperty调整capture到合适的帧。  
  55.         //  
  56.         //注意: cvQueryFrame返回的指针总是指向同一块内存。建议cvQueryFrame后拷贝一份  
  57.         //。而且返回的帧需要FLIP后才符合OPENCV的坐标系。 若返回值为NULL,说明到了视频的最后一帧。  
  58.         frame = cvQueryFrame( capture );  
  59.         if( !frame )  
  60.             break;  
  61.         if( !laplace )  
  62.         {  
  63.             for( i = 0; i < 3; i++ )  
  64.                 planes[i] = cvCreateImage( cvSize(frame->width,frame->height), 8, 1 );  
  65.             //CreateImage  
  66.             //创建头并分配数据  
  67.             //IplImage* cvCreateImage( CvSize size, int depth, int channels );  
  68.             //size  
  69.             //图像宽、高.  
  70.             //depth   
  71.             //图像元素的位深度,可以是下面的其中之一:  
  72.             //IPL_DEPTH_8U - 无符号8位整型  
  73.             //IPL_DEPTH_8S - 有符号8位整型  
  74.             //IPL_DEPTH_16U - 无符号16位整型  
  75.             //IPL_DEPTH_16S - 有符号16位整型  
  76.             //IPL_DEPTH_32S - 有符号32位整型  
  77.             //IPL_DEPTH_32F - 单精度浮点数  
  78.             //IPL_DEPTH_64F - 双精度浮点数  
  79.             //channels   
  80.             //每个元素(像素)的颜色通道数量.可以是 1, 2, 3 或 4.通道是交叉存取的,例如通常的彩色图像数据排列是:  
  81.             //b0 g0 r0 b1 g1 r1 ...  
  82.             //虽然通常 IPL 图象格式可以存贮非交叉存取的图像,并且一些OpenCV 也能处理他, 但是这个函数只能创建交叉存取图像.  
  83.             //函数 cvCreateImage 创建头并分配数据,这个函数是下列的缩写型式  
  84.             //header = cvCreateImageHeader(size,depth,channels);  
  85.             //cvCreateData(header); //只是创建空间,并不会初始化空间内的数据  
  86.             laplace = cvCreateImage( cvSize(frame->width,frame->height),  
  87.                 IPL_DEPTH_16S, 1 );  
  88.             colorlaplace = cvCreateImage( cvSize(frame->width,frame->height), 8, 3 );  
  89.         }  
  90.         //cvCvtPixToPlane  
  91.         //  
  92.         //  openCV里面的一个函数  
  93.         //  可以看作cvSplit是他的宏:  
  94.         //  #define cvCvtPixToPlane cvSplit  
  95.         //  void cvSplit( const CvArr* src, CvArr* dst0, CvArr* dst1,CvArr* dst2, CvArr* dst3 );  
  96.         //  作用是:分割多通道数组成几个单通道数组或者从数组中提取一个通道  
  97.         //  一般用法是cvCvtPixToPlane(IplImage * src,IplImage * dst1,IplImage *dst2,IplImage * dst3,IplImage *dst4)  
  98.         //  第一个参数是源图像,后面是分离出来每个通道的目标图像,如果圆筒到时3通道的,可以把最后一个参数设置为空。  
  99.         //  例如cvCvtPixToPlane(IplImage * src,IplImage * dst1,IplImage *dst2,IplImage * dst3,NULL)  
  100.         cvCvtPixToPlane( frame, planes[0], planes[1], planes[2], 0 );  
  101.         for( i = 0; i < 3; i++ )  
  102.         {  
  103.             //          Laplace  
  104.             //计算图像的 Laplacian 变换  
  105.             //void cvLaplace( const CvArr* src, CvArr* dst, int aperture_size=3 );  
  106.             //src  
  107.             //输入图像.  
  108.             //dst  
  109.             //输出图像.  
  110.             //aperture_size  
  111.             //核大小 (与 cvSobel 中定义一样).  
  112.             cvLaplace( planes[i], laplace, 3 ); // 3: aperture_size  
  113.             //ConvertScaleAbs  
  114.             //使用线性变换转换输入数组元素成8位无符号整型  
  115.             //void cvConvertScaleAbs( const CvArr* src, CvArr* dst, double scale=1, double shift=0 );  
  116.             //#define cvCvtScaleAbs cvConvertScaleAbs  
  117.             //src  
  118.             //原数组  
  119.             //dst  
  120.             //输出数组 (深度为 8u).  
  121.             //scale  
  122.             //比例因子.  
  123.             //shift  
  124.             //原数组元素按比例缩放后添加的值。  
  125.             //函数 cvConvertScaleAbs 与前一函数是相同的,但它是存贮变换结果的绝对值:  
  126.             //dst(I)=abs(src(I)*scale + (shift,shift,...))  
  127.             //函数只支持目标数数组的深度为 8u (8-bit 无符号) , 对于别的类型函数仿效于cvConvertScale 和 cvAbs 函数的联合  
  128.             cvConvertScaleAbs( laplace, planes[i], 1, 0 );  // planes[] = ABS(laplace)  
  129.         }  
  130.         //cvCvtPixToPlane是cvCvtPlaneToPix的逆函数  
  131.         cvCvtPlaneToPix( planes[0], planes[1], planes[2], 0, colorlaplace );  
  132.         //IplImage  
  133.         //  IPL 图像头  
  134.         //  typedef struct _IplImage  
  135.         //{  
  136.         //  int  nSize;         /* IplImage大小,=sizeof(IplImage)*/  
  137.         //  int  ID;            /* 版本 (=0)*/  
  138.         //  int  nChannels;     /* 大多数OPENCV函数支持1,2,3 或 4 个通道 */  
  139.         //  int  alphaChannel;  /* 被OpenCV忽略 */  
  140.         //  int  depth;         /* 像素的位深度: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U,  
  141.         //                      IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F 可支持 */  
  142.         //  char colorModel[4]; /* 被OpenCV忽略 */  
  143.         //  char channelSeq[4]; /* 被OpenCV忽略 */  
  144.         //  int  dataOrder;     /* 0 - 交叉存取颜色通道,对三通道RGB图像,像素存储顺序为BGR BGR BGR ... BGR;  
  145.         //                      1 - 分开的颜色通道,对三通道RGB图像,像素存储顺序为RRR...R GGG...G BBB...B。  
  146.         //                      cvCreateImage只能创建交叉存取图像 */  
  147.         //  int  origin;        /* 0 - 顶—左结构,  
  148.         //                      1 - 底—左结构 (Windows bitmaps 风格) */  
  149.         //  int  align;         /* 图像行排列 (4 or 8). OpenCV 忽略它,使用 widthStep 代替 */  
  150.         //  int  width;         /* 图像宽像素数 */  
  151.         //  int  height;        /* 图像高像素数*/  
  152.         //  struct _IplROI *roi;/* 图像感兴趣区域. 当该值非空只对该区域进行处理 */  
  153.         //  struct _IplImage *maskROI; /* 在 OpenCV中必须置NULL */  
  154.         //  void  *imageId;     /* 同上*/  
  155.         //  struct _IplTileInfo *tileInfo; /*同上*/  
  156.         //  int  imageSize;     /* 图像数据大小(在交叉存取格式下imageSize=image->height*image->widthStep),单位字节*/  
  157.         //  char *imageData;  /* 指向排列的图像数据 */  
  158.         //  int  widthStep;   /* 排列的图像行大小,以字节为单位 */  
  159.         //  int  BorderMode[4]; /* 边际结束模式, 被OpenCV忽略 */  
  160.         //  int  BorderConst[4]; /* 同上 */  
  161.         //  char *imageDataOrigin; /* 指针指向一个不同的图像数据结构(不是必须排列的),是为了纠正图像内存分配准备的 */  
  162.         //}  
  163.         //    IplImage;  
  164.         //IplImage结构来自于 Intel Image Processing Library(是其本身所具有的)。OpenCV 只支持其中的一个子集:  
  165.         //alphaChannel 在OpenCV中被忽略。  
  166.         //colorModel 和channelSeq 被OpenCV忽略。OpenCV颜色转换的唯一函数 cvCvtColor把原图像的颜色空间的目标图像的颜色空间作为一个参数。  
  167.         //dataOrder 必须是IPL_DATA_ORDER_PIXEL (颜色通道是交叉存取),然而平面图像的被选择通道可以被处理,就像COI(感兴趣的通道)被设置过一样。  
  168.         //align 是被OpenCV忽略的,而用 widthStep 去访问后继的图像行。  
  169.         //不支持maskROI 。处理MASK的函数把他当作一个分离的参数。MASK在 OpenCV 里是 8-bit,然而在 IPL他是 1-bit。  
  170.         //tileInfo 不支持。  
  171.         //BorderMode和BorderConst是不支持的。每个 OpenCV 函数处理像素的邻近的像素,通常使用单一的固定代码边际模式。  
  172.         //除了上述限制,OpenCV处理ROI有不同的要求。要求原图像和目标图像的尺寸或 ROI的尺寸必须(根据不同的操作,  
  173.         //例如cvPyrDown 目标图像的宽(高)必须等于原图像的宽(高)除以2 ±1)精确匹配,而IPL处理交叉区域,如图像的大小或ROI大小可能是完全独立的。  
  174.         colorlaplace->origin = frame->origin;   //让他们结构一致  
  175.         cvShowImage("Laplacian", colorlaplace );  
  176.         if( cvWaitKey(10) >= 0 )  
  177.             break;  
  178.     }  
  179.     cvReleaseCapture( &capture );  
  180.     cvDestroyWindow("Laplacian");  
  181.     return 0;  
  182. }  

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值