当前位置:  编程技术>综合
本页文章导读:
    ▪我的OpenCV学习笔记(25):c++版本的高斯混合模型的源代码完全注释      之前看到过C版本的,感觉写的很长,没有仔细看,但是C++版本的写的还是很不错的。我仔细看了一下,并对内容进行了仔细的注释,如果有人没有看懂,欢迎留言讨论。 先看一眼头.........
    ▪linux下部分头文件的作用      除去内核源码下的include目录外,在arch/arm/mach-s3c2410/和arch/arm/plat-s3c24xx/目录下都有include目录的。 #include <linux/kernel.h>        /* printk() */ #include <linux/slab.h>       .........
    ▪操作系统大型实验进展(1)-----c++ 初始化文件      #include <iostream> #include <crtdbg.h> using namespace std; FILE *fp; char SP_NAME[]="cq.dat"; int BLOCK_NUM=65536;//64*1024 int BLOCK_SIZE=512; #define biteNum 33554432//64*1024*512 void init() { int i,j; fp = fopen(SP_NAME.........

[1]我的OpenCV学习笔记(25):c++版本的高斯混合模型的源代码完全注释
    来源: 互联网  发布时间: 2013-11-10

之前看到过C版本的,感觉写的很长,没有仔细看,但是C++版本的写的还是很不错的。我仔细看了一下,并对内容进行了仔细的注释,如果有人没有看懂,欢迎留言讨论。

先看一眼头文件,在background_segm.hpp中

class CV_EXPORTS_W BackgroundSubtractorMOG : public BackgroundSubtractor
{
public:
    //! the default constructor
    CV_WRAP BackgroundSubtractorMOG();
    //! the full constructor that takes the length of the history, the number of gaussian mixtures, the background ratio parameter and the noise strength
    CV_WRAP BackgroundSubtractorMOG(int history, int nmixtures, double backgroundRatio, double noiseSigma=0);
    //! the destructor
    virtual ~BackgroundSubtractorMOG();
    //! the update operator
    virtual void operator()(InputArray image, OutputArray fgmask, double learningRate=0);
    
    //! re-initiaization method
    virtual void initialize(Size frameSize, int frameType);
    
    virtual AlgorithmInfo* info() const;

protected:    
    Size frameSize;
    int frameType;
    Mat bgmodel;
    int nframes;
    int history;//利用历史帧数计算学习速率,不是主要参数
    int nmixtures;//高斯模型的个数
    double varThreshold;//方差门限
    double backgroundRatio;//背景门限
    double noiseSigma;//噪声方差
};	

再看一眼源文件,在bgfg_gaussmix.cpp中:

static const int defaultNMixtures = 5;//默认混合模型个数
static const int defaultHistory = 200;//默认历史帧数
static const double defaultBackgroundRatio = 0.7;//默认背景门限
static const double defaultVarThreshold = 2.5*2.5;//默认方差门限
static const double defaultNoiseSigma = 30*0.5;//默认噪声方差
static const double defaultInitialWeight = 0.05;//默认初始权值
 //不带参数的构造函数,使用默认值  
BackgroundSubtractorMOG::BackgroundSubtractorMOG()
{
    frameSize = Size(0,0);
    frameType = 0;
    
    nframes = 0;
    nmixtures = defaultNMixtures;
    history = defaultHistory;
    varThreshold = defaultVarThreshold;
    backgroundRatio = defaultBackgroundRatio;
    noiseSigma = defaultNoiseSigma;
}
//带参数的构造函数,使用参数传进来的值    
BackgroundSubtractorMOG::BackgroundSubtractorMOG(int _history, int _nmixtures,
                                                 double _backgroundRatio,
                                                 double _noiseSigma)
{
    frameSize = Size(0,0);
    frameType = 0;
    
    nframes = 0;
    nmixtures = min(_nmixtures > 0 ? _nmixtures : defaultNMixtures, 8);//不能超过8个,否则就用默认的
    history = _history > 0 ? _history : defaultHistory;//不能小于0,否则就用默认的
    varThreshold = defaultVarThreshold;//门限使用默认的
    backgroundRatio = min(_backgroundRatio > 0 ? _backgroundRatio : 0.95, 1.);//背景门限必须大于0,小于1,否则使用0.95
    noiseSigma = _noiseSigma <= 0 ? defaultNoiseSigma : _noiseSigma;//噪声门限大于0
}
    
BackgroundSubtractorMOG::~BackgroundSubtractorMOG()
{
}


void BackgroundSubtractorMOG::initialize(Size _frameSize, int _frameType)
{
    frameSize = _frameSize;
    frameType = _frameType;
    nframes = 0;
    
    int nchannels = CV_MAT_CN(frameType);
    CV_Assert( CV_MAT_DEPTH(frameType) == CV_8U );
    
    // for each gaussian mixture of each pixel bg model we store ...
    // the mixture sort key (w/sum_of_variances), the mixture weight (w),
    // the mean (nchannels values) and
    // the diagonal covariance matrix (another nchannels values)
    bgmodel.create( 1, frameSize.height*frameSize.width*nmixtures*(2 + 2*nchannels), CV_32F );//初始化一个1行*XX列的矩阵
	//XX是这样计算的:图像的行*列*混合模型的个数*(1(优先级) + 1(权值) + 2(均值 + 方差) * 通道数)
    bgmodel = Scalar::all(0);//清零
}

//设为模版,就是考虑到了彩色图像与灰度图像两种情况    
template<typename VT> struct MixData
{
    float sortKey;
    float weight;
    VT mean;
    VT var;
};

    
static void process8uC1( const Mat& image, Mat& fgmask, double learningRate,
                         Mat& bgmodel, int nmixtures, double backgroundRatio,
                         double varThreshold, double noiseSigma )
{
    int x, y, k, k1, rows = image.rows, cols = image.cols;
    float alpha = (float)learningRate, T = (float)backgroundRatio, vT = (float)varThreshold;//学习速率、背景门限、方差门限
    int K = nmixtures;//混合模型个数
    MixData<float>* mptr = (MixData<float>*)bgmodel.data;
    
    const float w0 = (float)defaultInitialWeight;//初始权值
    const float sk0 = (float)(w0/(defaultNoiseSigma*2));//初始优先级
    const float var0 = (float)(defaultNoiseSigma*defaultNoiseSigma*4);//初始方差
    const float minVar = (float)(noiseSigma*noiseSigma);//最小方差
    
    for( y = 0; y < rows; y++ )
    {
        const uchar* src = image.ptr<uchar>(y);
        uchar* dst = fgmask.ptr<uchar>(y);
        
        if( alpha > 0 )//如果学习速率为0,则退化为背景相减
        {
            for( x = 0; x < cols; x++, mptr += K )
            {
                float wsum = 0;
                float pix = src[x];//每个像素
                int kHit = -1, kForeground = -1;//是否属于模型,是否属于前景
                
                for( k = 0; k < K; k++ )//每个高斯模型
                {
                    float w = mptr[k].weight;//当前模型的权值
                    wsum += w;//权值累加
                    if( w < FLT_EPSILON )
                        break;
                    float mu = mptr[k].mean;//当前模型的均值
                    float var = mptr[k].var;//当前模型的方差
                    float diff = pix - mu;//当前像素与模型均值之差
                    float d2 = diff*diff;//平方
                    if( d2 < vT*var )//是否小于方门限,即是否属于该模型
                    {
                        wsum -= w;//如果匹配,则把它减去,因为之后会更新它
                        float dw = alpha*(1.f - w);
                        mptr[k].weight = w + dw;//增加权值
						//注意源文章中涉及概率的部分多进行了简化,将概率变为1
                        mptr[k].mean = mu + alpha*diff;//修正均值		
                        var = max(var + alpha*(d2 - var), minVar);//开始时方差清零0,所以这里使用噪声方差作为默认方差,否则使用上一次方差
                        mptr[k].var = var;//修正方差
                        mptr[k].sortKey = w/sqrt(var);//重新计算优先级,貌似这里不对,应该使用更新后的mptr[k].weight而不是w
                        
                        for( k1 = k-1; k1 >= 0; k1-- )//从匹配的第k个模型开始向前比较,如果更新后的单高斯模型优先级超过他前面的那个,则交换顺序
                        {
                            if( mptr[k1].sortKey >= mptr[k1+1].sortKey )//如果优先级没有发生改变,则停止比较
                                break;
                            std::swap( mptr[k1], mptr[k1+1] );//交换它们的顺序,始终保证优先级最大的在前面
                        }
                        
                        kHit = k1+1;//记录属于哪个模型
                        break;
                    }
                }
                
                if( kHit < 0 ) // no appropriate gaussian mixture found at all, remove the weakest mixture and create a new one
								//当前像素不属于任何一个模型
                {
					//初始化一个新模型
                    kHit = k = min(k, K-1);//有两种情况,当最开始的初始化时,k并不是等于K-1的
                    wsum += w0 - mptr[k].weight;//从权值总和中减去原来的那个模型,并加上默认权值
                    mptr[k].weight = w0;//初始化权值
                    mptr[k].mean = pix;//初始化均值
                    mptr[k].var = var0;	//初始化方差
                    mptr[k].sortKey = sk0;//初始化权值
                }
                else
                    for( ; k < K; k++ )
                        wsum += mptr[k].weight;//求出剩下的总权值
                
                float wscale = 1.f/wsum;//归一化
                wsum = 0;
                for( k = 0; k < K; k++ )
                {
                    wsum += mptr[k].weight *= wscale;
                    mptr[k].sortKey *= wscale;//计算归一化权值
                    if( wsum > T && kForeground < 0 )
                        kForeground = k+1;//第几个模型之后就判为前景了
                }
                
                dst[x] = (uchar)(-(kHit >= kForeground));//判决:(ucahr)(-true) = 255;(uchar)(-(false)) = 0;
            }
        }
        else//如果学习速率小于等于0,则没有背景更新过程,其他过程类似
        {
            for( x = 0; x < cols; x++, mptr += K )
            {
                float pix = src[x];
                int kHit = -1, kForeground = -1;
                
                for( k = 0; k < K; k++ )
                {
                    if( mptr[k].weight < FLT_EPSILON )
                        break;
                    float mu = mptr[k].mean;
                    float var = mptr[k].var;
                    float diff = pix - mu;
                    float d2 = diff*diff;
                    if( d2 < vT*var )
                    {
                        kHit = k;
                        break;
                    }
                }
                
                if( kHit >= 0 )
                {
       
    
[2]linux下部分头文件的作用
    来源: 互联网  发布时间: 2013-11-10

除去内核源码下的include目录外,在arch/arm/mach-s3c2410/和arch/arm/plat-s3c24xx/目录下都有include目录的。


#include <linux/kernel.h>        /* printk() */
#include <linux/slab.h>        /* kmalloc() */
#include <linux/fs.h>        /* file_operations、inode_operations、super_operations结构体*/
#include <linux/errno.h>        /* error codes */
#include <linux/types.h>        /* size_t等各种系统typedef的数据类型 */
#include <linux/fcntl.h>        /* O_ACCMODE */
#include <linux/poll.h>        /* COPY_TO_USER */
#include <linux/module.h>          /*MODULE_LICENSE("GPL");内核认识的特定许可有, 
                          "GPL"( 适用 GNU 通用公共许可的任何版本 ), 
                          "GPL v2"( 只适用 GPL 版本 2 ), 
                          "GPL and additional rights", 
                          "Dual BSD/GPL", 
                          "Dual MPL/GPL", 
                          "Proprietary".
                          除非你的模块明确标识是在内核认识的一个自由许可下, 
                          否则就假定它是私有的,
                          内核在模块加载时被"弄污浊"了. 
                          象我们在第 1 章"许可条款"中提到的, 
                          内核开发者不会热心帮助在加载了私有模块后遇到问题的用户.
                           MODULE_AUTHOR ( 声明谁编写了模块 ), 
                           MODULE_DESCRIPION( 一个人可读的关于模块做什么的声明 ), 
                           MODULE_VERSION ( 一个代码修订版本号; 看 <linux/module.h> 的注释以便知道创建版本字串使用的惯例), 
                           MODULE_ALIAS ( 模块为人所知的另一个名子 ), 
                           MODULE_DEVICE_TABLE ( 来告知用户空间, 模块支持那些设备 ).
                           */
#include <linux/init.h>        /* #define module_init(x)    __initcall(x);  driver initialization entry point
                       #define module_exit(x)    __exitcall(x);  driver exit entry point
                       */
#include <linux/miscdevice.h>        /* extern int misc_register(struct miscdevice * misc);  注册miscdevice结构体成员变量设备
                         extern int misc_deregister(struct miscdevice *misc);  注销miscdevice结构体成员变量设备
                         */
#include <linux/cdev.h>        /* void cdev_init(struct cdev *, const struct file_operations *);
                      struct cdev *cdev_alloc(void);
                      void cdev_put(struct cdev *p);
                      int cdev_add(struct cdev *, dev_t, unsigned);
                      void cdev_del(struct cdev *);
                      void cd_forget(struct inode *); */
#include <mach/hardware.h>                 /* 和GPIO口操作相关的函数定义的头文件
                                对应的源文件在/linux-2.6.32.2/arch/arm/plat-s3c24xx/gpio.c
                                void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function);
                                unsigned int s3c2410_gpio_getcfg(unsigned int pin);
                                void s3c2410_gpio_pullup(unsigned int pin, unsigned int to);
                                int s3c2410_gpio_getpull(unsigned int pin);
                                void s3c2410_gpio_setpin(unsigned int pin, unsigned int to);
                                unsigned int s3c2410_gpio_getpin(unsigned int pin);
                                unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change);
                                int s3c2410_gpio_getirq(unsigned int pin);
                                int s3c2410_gpio_irq2pin(unsigned int irq);*/
#include <mach/regs-gpio.h>        /* 和GPIO口相关的一些宏定义(在arch/arm/mach-s3c2410/mach) */
#include <linux/platform_device.h>        /*  */
#include <linux/interrupt.h>        /* typedef irqreturn_t (*irq_handler_t)(int, void *);
                         extern void free_irq(unsigned int, void *);extern void disable_irq(unsigned int irq);
                         extern void enable_irq(unsigned int irq);等和中断相关函数的声明 */
#include <linux/wait.h>        /* wake_up_interruptible   唤醒 q 指定的注册在等待队列上的进程。该函数不能直接的立即唤醒进程,而是由调度程序转换上下文,调整为可运行状态。  
                    static DECLARE_WAIT_QUEUE_HEAD(button_waitq);声明等待队列为全局变量
                      wait_event_interruptible该函数修改task的状态为TASK_INTERRUPTIBLE,意味着改进程将不会继续运行直到被唤醒,然后被添加到等待队列wq中*/
#include <linux/poll.h>        /* poll_wait */
#include <asm/uaccess.h>        /* copy_to_user和copy_from_user */
#include <asm/io.h>              /* __raw_readl  __raw_writel*/
#include <linux/clk.h>        /* struct clk *clk_get(struct device *dev, const char *id);
                      unsigned long clk_get_rate(struct clk *clk); */
#include <plat/clock.h>        /* struct clk;结构体的定义 (在arch/arm/plat-s3c/plat/include/clock.arch中,对应的源文件在/arm/plat-s3c/clock.c)*/
#include <linux/device.h>           //包含了device、class 、device_driver等结构的定义
#include <mach/regs-mem.h>        /* 和bank相关的寄存器的宏定义 */
#include <asm/div64.h>          /* Linux内核中64位除法函数do_div */
#include <linux/fb.h>        /* struct fb_info 结构体的定义 */
#include <mach/fb.h>        /* struct s3c2410fb_display(在arch/arm/mach-s3c2410/include/mach/fb.h) */

作者:taozi343805436 发表于2013-1-8 15:25:31 原文链接
阅读:0 评论:0 查看评论

    
[3]操作系统大型实验进展(1)-----c++ 初始化文件
    来源: 互联网  发布时间: 2013-11-10
#include <iostream>
#include <crtdbg.h>
using namespace std;

FILE *fp;
char SP_NAME[]="cq.dat";
int BLOCK_NUM=65536;//64*1024
int BLOCK_SIZE=512;
#define biteNum 33554432//64*1024*512
void init() { 

int i,j; 

fp = fopen(SP_NAME,"w"); 
//文件写入方法一
/*for(i=0;i<BLOCK_NUM;i++) { 

  for(j=0;j<BLOCK_SIZE;j++) { 

   fprintf(fp,"%c",'\0'); 
  } 
}  */

//文件写入方法二
char *memory=(char*)malloc(biteNum);//http://baike.baidu.com/view/736228.htm
memset(memory,0,biteNum);
fwrite(memory,1,biteNum,fp);//http://baike.baidu.com/view/656700.htm
fclose(fp);
free(memory);
} 

int main()
{

init();

return 0;
}

作者:chenqiai0 发表于2013-1-8 15:24:25 原文链接
阅读:12 评论:0 查看评论

    
最新技术文章:
▪error while loading shared libraries的解決方法    ▪版本控制的极佳实践    ▪安装多个jdk,多个tomcat版本的冲突问题
▪简单选择排序算法    ▪国外 Android资源大集合 和个人学习android收藏    ▪.NET MVC 给loading数据加 ajax 等待loading效果
▪http代理工作原理(3)    ▪关注细节-TWaver Android    ▪Spring怎样把Bean实例暴露出来?
▪java写入excel2007的操作    ▪http代理工作原理(1)    ▪浅谈三层架构
▪http代理工作原理(2)    ▪解析三层架构……如何分层?    ▪linux PS命令
▪secureMRT Linux命令汉字出现乱码    ▪把C++类成员方法直接作为线程回调函数    ▪weak-and算法原理演示(wand)
▪53个要点提高PHP编程效率    ▪linux僵尸进程    ▪java 序列化到mysql数据库中
▪利用ndk编译ffmpeg    ▪活用CSS巧妙解决超长文本内容显示问题    ▪通过DBMS_RANDOM得到随机
▪CodeSmith 使用教程(8): CodeTemplate对象    ▪android4.0 进程回收机制    ▪仿天猫首页-产品分类
▪从Samples中入门IOS开发(四)------ 基于socket的...    ▪工作趣事 之 重装服务器后的网站不能正常访...    ▪java序列化学习笔记
▪Office 2010下VBA Addressof的应用    ▪一起来学ASP.NET Ajax(二)之初识ASP.NET Ajax    ▪更改CentOS yum 源为163的源
▪ORACLE 常用表达式    ▪记录一下,AS3反射功能的实现方法    ▪u盘文件系统问题
▪java设计模式-观察者模式初探    ▪MANIFEST.MF格式总结    ▪Android 4.2 Wifi Display核心分析 (一)
▪Perl 正则表达式 记忆方法    ▪.NET MVC 给loading数据加 ajax 等待laoding效果    ▪java 类之访问权限
▪extjs在myeclipse提示    ▪xml不提示问题    ▪Android应用程序运行的性能设计
▪sharepoint 2010 自定义列表启用版本记录控制 如...    ▪解决UIScrollView截获touch事件的一个极其简单有...    ▪Chain of Responsibility -- 责任链模式
▪运行skyeye缺少libbfd-2.18.50.0.2.20071001.so问题    ▪sharepoint 2010 使用sharepoint脚本STSNavigate方法实...    ▪让javascript显原型!
▪kohana基本安装配置    ▪MVVM开发模式实例解析    ▪sharepoint 2010 设置pdf文件在浏览器中访问
▪spring+hibernate+事务    ▪MyEclipse中文乱码,编码格式设置,文件编码格...    ▪struts+spring+hibernate用jquery实现数据分页异步加...
▪windows平台c++开发"麻烦"总结    ▪Android Wifi几点    ▪Myeclipse中JDBC连接池的配置
▪优化后的冒泡排序算法    ▪elasticsearch RESTful搜索引擎-(java jest 使用[入门])...    ▪MyEclipse下安装SVN插件SubEclipse的方法
▪100个windows平台C++开发错误之七编程    ▪串口转以太网模块WIZ140SR/WIZ145SR 数据手册(版...    ▪初识XML(三)Schema
▪Deep Copy VS Shallow Copy    ▪iphone游戏开发之cocos2d (七) 自定义精灵类,实...    ▪100个windows平台C++开发错误之八编程
▪C++程序的内存布局    ▪将不确定变为确定系列~Linq的批量操作靠的住...    ▪DIV始终保持在浏览器中央,兼容各浏览器版本
▪Activity生命周期管理之三——Stopping或者Restarti...    ▪《C语言参悟之旅》-读书笔记(八)    ▪C++函数参数小结
▪android Content Provider详解九    ▪简单的图片无缝滚动效果    ▪required artifact is missing.
▪c++编程风格----读书笔记(1)    ▪codeforces round 160    ▪【Visual C++】游戏开发笔记四十 浅墨DirectX教程...
▪【D3D11游戏编程】学习笔记十八:模板缓冲区...    ▪codeforces 70D 动态凸包    ▪c++编程风格----读书笔记(2)
▪Android窗口管理服务WindowManagerService计算Activity...    ▪keytool 错误: java.io.FileNotFoundException: MyAndroidKey....    ▪《HTTP权威指南》读书笔记---缓存
▪markdown    ▪[设计模式]总结    ▪网站用户行为分析在用户市场领域的应用
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3