CCV入门教程(二)

梁登的csdn技术博客

1CCV中涉及到的dll,库的调用关系

Addons目录下

ofxKinectCLNUI :包括了采用微软Kinect的设备(如Xbox NUI Audio, NUI Camera, NUI Motor and Accelerometer等)的稳定的驱动程序、SDKAPI

ofxopenCV:openCV的库。OpenCVC/C++的一套函数库,基本上开源的摄像头相关的软件/插件都是基于OpenCV做的,当前版本是2.X。 

ofxPS3 :用于支持多个PS3Eye PlayStation Eye,摄像头)的使用

ofxThread:支持线程操作

ofxOSC:用于OSC支持,说简单点,TUIO协议是基于OSC的,为使用TUIO搭建平台

ofxVectorMath:矩阵运算支持(封装了矩阵转置、求行列式、指定位置的元素进行操作等等运算)

ofxXMLSettings:用于读写xml文件。eXtensible Markup Language,简称:XML

ofxNetwork:用于进程间通信支持,可以支持UDPTCP两种通信协议。

ofxDirList:用于支持OpenFrameworks Library。openFrameworks 是为创造性编码提供的一个开源的C++工具箱。

ofxDSVL:DirectShow Video Processing Library一个对directshow的简单封装的库,使用起来比较方便,比较容易实现视频编程的应用

ofxFFMV:用于支持多个摄像头的使用和切换

其中 pgrflycapture.h:提供PGR FlyCapture library的API

ofxNCore:CCV的主体部分,实现了CCV的主要功能,包括:

    Calibration:进行触摸屏的标定

    Camera:摄像机控制

    Communication:TUIO协议的通信

    Controls:CCV的用户界面部分及组件控制

    Events:触摸事件的捕获与处理

    Filters:对视频的处理

    Modules:CCV运行时的后台数据运算部分,包括处理鼠标信息、触点检测、窗口绘制、视频显示、更改和保存参数设置、读取XML等等

    Tracking:触点跟踪

    ofxNCore.h:

Libs

Openframeworks框架库

SRC  

CCV运行时的入口,main()主程序

Dll

cv100.dll

cxcore100.dll

cv100.dll、cxcore100.dllOpenCVIntel公司支持的开源计算机视觉库)的组成部分

dsvl.dll

fmodex.dll

FreeImage.dll

FreeType-6.dll

glut32.dll

ippipx-5.3.dll  

   ippipx-5.3.dll是一个win32的应用库

PGRFlyCapture.dll

PS3EyeMulticam.dll

winusb.dll

2CCV中触点提取算法流程

2.1 滤波部分相应的代码

/****************************************************************

 * CPU Filters

 ****************************************************************/

 void applyCPUFilters(CPUImageFilter& img){

        //Set Mirroring Horizontal/Vertical//横竖镜像

        if(bVerticalMirror || bHorizontalMirror) img.mirror(bVerticalMirror, bHorizontalMirror);

        if(!bMiniMode) grayImg = img; //for drawing小窗口模式

        //Dynamic background with learn rate

        if(bDynamicBG){//动态背景滤图

            floatBgImg.addWeighted( img, fLearnRate);

//grayBg = floatBgImg;  // not yet implemented

 cvConvertScale( floatBgImg.getCvImage(), grayBg.getCvImage(), 255.0f/65535.0f, 0 ); //图像缩放       

 grayBg.flagImageChanged();

        }

        //recapature the background until image/camera is fully exposed//动态背景滤除时间

//在相机充分曝光以前,不断地获取背景信息

        if((ofGetElapsedTimeMillis() - exposureStartTime) < CAMERA_EXPOSURE_TIME) bLearnBakground = true;

        

        //Capture full background重新获取参照背景

        if (bLearnBakground == true){

            floatBgImg = img;

//grayBg = floatBgImg;  // not yet implemented

cvConvertScale( floatBgImg.getCvImage(), grayBg.getCvImage(), 255.0f/65535.0f, 0 ); //图像缩放      

grayBg.flagImageChanged();//设置参照图被改变

            bLearnBakground = false;

        }

//Background Subtraction  背景提取

        //img.absDiff(grayBg, img); 

if(bTrackDark) //bTrackDark的值在配置文件data\config.xml中设置 

cvSub(grayBg.getCvImage(), img.getCvImage(), img.getCvImage());//图形差值处理

else

cvSub(img.getCvImage(), grayBg.getCvImage(), img.getCvImage());

img.flagImageChanged();//    

if(bSmooth){//Smooth 平滑

            img.blur((smooth * 2) + 1); //needs to be an odd number

            if(!bMiniMode)

            subtractBg = img; //for drawing . subtractBg用于存储分离出来的背景

        }

        if(bHighpass){//HighPass 高通滤波

            img.highpass(highpassBlur, highpassNoise);

            if(!bMiniMode)

            highpassImg = img; //for drawing

        }

        if(bAmplify){//Amplify  图像增强

            img.amplify(img, highpassAmp);

            if(!bMiniMode)

            ampImg = img; //for drawing

        }

        img.threshold(threshold); //Threshold  实际上是二值化处理

//img.adaptiveThreshold(threshold, -3);

        if(!bMiniMode)

        grayDiff = img; //for drawing

    }

  摘自addons\ofxNCore\src\Filters\ProcessFilters.h

2.2 平滑处理的流程

平滑处理调用的函数如下

--------------------------------------------------------------------------

void ofxCvImage::blur( int value ) {

    if( value % 2 == 0 ) {

        ofLog(OF_LOG_NOTICE, "in blur, value not odd -> will add 1 to cover your back");

        value++;

    }  //blur的参数要求是奇数!

cvSmooth( cvImage, cvImageTemp, CV_BLUR , value);

swapTemp();

    flagImageChanged();

cfxcvimage.cpp

--------------------------------------------------------------------------

具体在实现滤波的时候,blur的参数是由CCV运行的用户界面(附录二)中smooth窗口中的进度条值smooth 乘以2加1得到。

--------------------------------------------------------------------------

if(bSmooth){//Smooth 平滑处理

            img.blur((smooth * 2) + 1); //needs to be an odd number

            if(!bMiniMode)

            subtractBg = img; //for drawing

        }

   摘自addons\ofxNCore\src\Filters\ProcessFilters.h

这里的cvSmooth是opencv中的一个平滑函数

关于CVSmooth的介绍

void cvSmooth( const CvArr* src, CvArr* dst,

int smoothtype=CV_GAUSSIAN,

int param1=3, int param2=0, double param3=0, double param4=0 );

src 

输入图像. 

dst 

输出图像. 

smoothtype 

平滑方法: 

CV_BLUR_NO_SCALE (简单不带尺度变换的模糊) - 对每个象素的 param1×param2 领域求和。如果邻域大小是变化的,可以事先利用函数 cvIntegral 计算积分图像。 

CV_BLUR (simple blur) - 对每个象素param1×param2邻域 求和并做尺度变换 1/(param1?param2). 

CV_GAUSSIAN (gaussian blur) - 对图像进行核大小为 param1×param2 的高斯卷积 

CV_MEDIAN (median blur) - 对图像进行核大小为param1×param1 的中值滤波 (i.e. 邻域是方的). 

CV_BILATERAL (双向滤波) - 应用双向 3x3 滤波,彩色 sigma=param1,空间 sigma=param2.

 param1 

平滑操作的第一个参数. 

param2 

平滑操作的第二个参数. 对于简单/非尺度变换的高斯模糊的情况,如果param2的值 为零,则表示其被设定为param1。 

param3 

对应高斯参数的 Gaussian sigma (标准差). 如果为零,则标准差由下面的核尺寸计算: 

sigma = (n/2 - 1)*0.3 + 0.8, 其中 n=param1 对应水平核,

n=param2 对应垂直核.

对小的卷积核 (3×3 to 7×7) 使用如上公式所示的标准 sigma 速度会快。如果 param3 不为零,而 param1 和 param2 为零,则核大小有 sigma 计算 (以保证足够精确的操作). 

函数 cvSmooth 可使用上面任何一种方法平滑图像。每一种方法都有自己的特点以及局限。 

没有缩放的图像平滑仅支持单通道图像,并且支持8位到16位的转换(与cvSobel和cvaplace相似)和32位浮点数到32位浮点数的变换格式。 

简单模糊和高斯模糊支持 1- 或 3-通道, 8-比特 和 32-比特 浮点图像。这两种方法可以(in-place)方式处理图像。 

中值和双向滤波工作于 1- 或 3-通道, 8-位图像,但是不能以 in-place 方式处理图像.

2.3关于高通滤波

高通滤波的函数如下

--------------------------------------------------------------------------

void CPUImageFilter::highpass ( float blur1, float blur2 ) {

//Blur Original Image

if(blur1 > 0)

cvSmooth( cvImage, cvImageTemp, CV_BLUR , (blur1 * 2) + 1);

//Original Image - Blur Image = Highpass Image

cvSub( cvImage, cvImageTemp, cvImageTemp );

//Blur Highpass to remove noise

if(blur2 > 0)

cvSmooth( cvImageTemp, cvImageTemp, CV_BLUR , (blur2 * 2) + 1);

swapTemp();

flagImageChanged();

}

 CPUImageFilter.cpp

--------------------------------------------------------------------------

cvSub

矩阵减法运算,适用于IplImage及CvMat资料结构,输入跟输出资料结构必须同类型,同大小,同型别,且具有遮罩的功能.

编辑本段格式

  void cvSub(const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL);

编辑本段参数

  src1: 第一个输入数组   src2: 第二个输入数组   dst: 输出数组   mask: 操作掩码(8位单通道数组)。只有掩码指定的输出数组被修改。

编辑本段说明

  函数cvSub用一个数组减另一个数组。如果mask(i)≠NULL,则:   dst(i) = src1(i) - src2(i)   除掩码外,所有数组都必须具有相同的类型和大小,或者相同的ROI大小。

--------------------------------------------------------------------------

if(bHighpass){//HighPass  高通滤波

            img.highpass(highpassBlur, highpassNoise);

            if(!bMiniMode)

            highpassImg = img; //for drawing

        }

  摘自addons\ofxNCore\src\Filters\ProcessFilters.h

--------------------------------------------------------------------------

2.4关于幅值增强

--------------------------------------------------------------------------

void CPUImageFilter::amplify ( CPUImageFilter& mom, float level ) {

float scalef = level / 128.0f;

cvMul( mom.getCvImage(), mom.getCvImage(), cvImageTemp, scalef );

swapTemp();

flagImageChanged();

}

 CPUImageFilter.cpp

cvMul

1. void cvMul(  

2.     const CvArr* src1,  

3.     const CvArr* src2,  

4.     CvArr* dst,  

5.     double scale=1 

6. ); 

cvMul()是一个简单的乘法函数。它将src1中的元素与src2中相对应的元素相乘,然后把结果赋给dst。如果mask是空,那么与其中0元素相对应的dst元素都不会因此操作而改变。OpenCV中没有函数cvMulS(),因为该功能已经由函数cvScale()或cvCvtScale()提供。

除此之外,有一件事情要记住:cvMul()执行的是元素之间的乘法。有时候,在进行矩阵相乘时,可能会错误使用cvMul(),但这无法奏效;记住,cvGEMM()才是处理矩阵乘法的函数,而不是cvMul()。

http://book.51cto.com/art/200912/172604.htm

--------------------------------------------------------------------------

if(bAmplify){//Amplify  幅值增强

            img.amplify(img, highpassAmp);

            if(!bMiniMode)

            ampImg = img; //for drawing

        }

  摘自addons\ofxNCore\src\Filters\ProcessFilters.h

--------------------------------------------------------------------------

2.5关于二值化处理 Threshold

    img.threshold(threshold); //Threshold  阀值

//img.adaptiveThreshold(threshold, -3);

     摘自addons\ofxNCore\src\Filters\ProcessFilters.h

--------------------------------------------------------------------------

void ofxCvGrayscaleImage::threshold( int value, bool invert) {

//http://lush.sourceforge.net/lush-manual/01a8321b.html

if(invert) cvThreshold( cvImage, cvImageTemp, value, 255, CV_THRESH_BINARY_INV );

else cvThreshold( cvImage, cvImageTemp, value, 255, CV_THRESH_BINARY );

swapTemp();

    flagImageChanged();

}

//\addons\ofxOpenCv\src\ofxCvGrayscaleImage.cpp

--------------------------------------------------------------------------

cvThreshold是opencv库中的一个函数 

  作用:函数 cvThreshold 对单通道数组应用固定阈值操作。该函数的典型应用是对灰度图像进行阈值操作得到二值图像。(cvCmpS 也可以达到此目的) 或者是去掉噪声,例如过滤很小或很大象素值的图像点。本函数支持的对图像取阈值的方法由 threshold_type 确定。 

  形式:void cvThreshold( const CvArr* src, CvArr* dst, double threshold, double max_value, int threshold_type ); 

  src:原始数组 (单通道 , 8-bit of 32-bit 浮点数)。dst:输出数组,必须与 src 的类型一致,或者为 8-bit。 

  threshold:阈值 

  max_value:使用 CV_THRESH_BINARY 和 CV_THRESH_BINARY_INV 的最大值。 

  threshold_type:阈值类型 threshold_type=CV_THRESH_BINARY: 

  如果 src(x,y)>threshold ,dst(x,y) = max_value; 否则,des(x,y)=0; 

  threshold_type=CV_THRESH_BINARY_INV: 

  如果 src(x,y)>threshold,dst(x,y) = 0; 否则,dst(x,y) = max_value. 

  threshold_typ

3、CCV视频处理过程的分析

3.1 ProcessFilters.h文件的进一步理解

文件ProcessFilters.h 对于理解CCV的触点检测和提取流程具有关键作用。

注意CCV在处理视频时,平滑、高通滤波、图像增强等操作都是由CPU和GPU配合完成的。

这里是几点批注:

//这个函数获得的是从开始采集视频到当前所经历的时间

//以 毫秒(millisecond)为单位

int ofGetElapsedTimeMillis(){

return (int)(ofGetSystemTime() - startTime);

}

\apps\addonsExamples\VS2008\bin\data\config.xml

和 apps\addonsExamples\VS2008\data\config.xml两个文件可以进行bTrackDark的设置

void ofxCvFloatImage::flagImageChanged() {

    bFloatPixelsDirty = true;

    ofxCvImage::flagImageChanged();

}

void ofxCvImage::flagImageChanged() {

    bTextureDirty = true;

    bPixelsDirty = true;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值