热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

opencv学习记录【6】(codebook

9.2-9.16:codebook【一】基本原理CodeBook算法的基本思想是为每一个像素点建立一个codebook,每个codebook包含一个或者

9.2-9.16:codebook
【一】 基本原理
CodeBook算法的基本思想是为每一个像素点建立一个codebook,每个codebook包含一个或者多个码元code_elements,并且随着背景像素值波动情况的不同,不同像素点所包含的码元数目不一定相同。
CodeBook算法为当前图像的每一个像素建立一个码本CodeBook(CB)结构,每个CodeBook由多个码元code_element(ce)组成。CB和ce的形式如下:
CB={**cb,numEntries,t }
ce={learnHigh, learnLow,max,min,t_last_update,stale}
其中numEntries为一个CB中所包含的ce的数目,当n太小时,退化为简单背景,当n较大时可以对复杂背景进行建模;t为CB更新的次数。ce中learnHigh和learnLow作为更新时的学习上下界,max和min记录当前像素的最大值和最小值。t_last_update表示此码元最后一次更新的时间,stale表示此码元最长不更新时间(即该ce多久未被访问),用来删除很少使用的码元,精简码本。
【二】 步骤
1 模型训练
假设当前训练图像I中某一像素 (x,y),该像素的CB的更新算法如下,另外记背景阈值的增长判定阈值为Bounds:
(1) CB的访问次数加1;
(2) 遍历CB中的每个ce,如果存在一个ce中的learnHigh,learnLow满足learnLow≤I(x,y)≤learnHigh,则转(4);
(3) 创建一个新的码字new ce加入到CB中, new ce的max与min赋值为I(x,y)&#xff0c;learnHigh <- I(x,y) &#43; Bounds&#xff0c;learnLow <- I(x,y) – Bounds&#xff0c;并且转(6)&#xff1b;
(4) 更新该码字的t_last_update&#xff0c;若当前像素值I(x,y)大于该码字的max&#xff0c;则max <- I(x,y)&#xff0c;若I(x,y)小于该码字的min&#xff0c;则min <- I(x,y)&#xff1b;
(5) 更新该码字的学习上下界&#xff0c;以增加背景模型对于复杂背景的适应能力&#xff0c;具体做法是&#xff1a;若learnHigh I(x,y) – Bounds&#xff0c;则learnLow减少1&#xff1b;
(6) 更新CB中每个ce的stale。设定刷新时间&#xff0c;遍历每个码元&#xff0c;若码元中的不更新时间大于设定的刷新时间&#xff0c;则删除&#xff1b;在刷新时间内则保持。
2 背景检测
使用已建立好的CB进行运动目标检测&#xff0c;记判断前景的范围上下界为minMod和maxMod&#xff0c;对于当前待检测图像上的某一像素I(x,y)&#xff0c;遍历它对应像素背景模型CB中的每一个码字ce&#xff0c;若存在一个ce&#xff0c;使得I(x,y) min – minMod&#xff0c;则I(x,y)被判断为背景&#xff0c;否则被判断为前景。
【三】 实验程序
个人认为《Learning opencv3》中codebook示例程序可读性差&#xff0c;网上的大多数示例程序是基于较低版本opencv的&#xff0c;找了很久找到适合的示例程序&#xff0c;做了少许修改。

#include
#include
using namespace cv;
using namespace std;
#define CHANNELS 3//码元
typedef struct ce {uchar learnHigh[CHANNELS];uchar learnLow[CHANNELS];uchar max[CHANNELS];uchar min[CHANNELS];int t_last_update;int stale;
}code_element;//码本
typedef struct code_book {code_element **cb;int numEntries;int t;
}codeBook;//每一帧每个像素调用以更新码本
int updateCodeBook(uchar *p, codeBook&c, unsigned*cbBounds, int numChannels)
{if (c.numEntries &#61;&#61; 0)c.t &#61; 0;//初始化时间c.t &#43;&#61; 1;int n;unsigned int high[3], low[3];for (n &#61; 0; n 255){high[n] &#61; 255;}low[n]&#61; *(p &#43; n) - *(cbBounds &#43; n);if (low[n]<0){low[n] &#61; 0;}}//该像素是否在码本范围之内&#xff0c;是的话更新选中码元int matchChannel;int i;for ( i &#61; 0; i learnLow[n]<&#61;*(p&#43;n)&&(*(p &#43; n)<&#61;c.cb[i]->learnHigh[n])){matchChannel&#43;&#43;;}}if (matchChannel&#61;&#61;numChannels){c.cb[i]->t_last_update &#61; c.t;for (n &#61; 0; n max[n] <*(p &#43; n)){c.cb[i]->max[n] &#61; *(p &#43; n);}else if (c.cb[i]->min[n] > *(p &#43; n)){c.cb[i]->min[n] &#61; *(p &#43; n);}}break;}}//该像素不满足任何一码元&#xff0c;创建一个新码元if (i&#61;&#61;c.numEntries){code_element **foo &#61; new code_element*[c.numEntries &#43; 1];for (int j &#61; 0; j learnHigh[n] &#61; high[n];c.cb[c.numEntries]->learnLow[n] &#61; low[n]; c.cb[c.numEntries]->max[n] &#61; *(p &#43; n);c.cb[c.numEntries]->min[n] &#61; *(p &#43; n);}c.cb[c.numEntries]->t_last_update &#61; c.t;c.cb[c.numEntries]->stale &#61; 0;c.numEntries &#43;&#61; 1;}//更新码元中不更新时间for (int j &#61; 0; j t_last_update;if (tmp>c.cb[j]->stale){c.cb[j]->stale &#61; tmp;}}//调整学习域for ( n &#61; 0; n learnHigh[n] learnHigh[n] &#43;&#61; 1;if (c.cb[i]->learnLow[n] > low[n])c.cb[i]->learnLow[n] -&#61; 1;}return (i);
}//区分背景
uchar backgroundDiff(uchar *p, codeBook&c, int numChannels, int *minMod, int *maxMod)
{int matchChannel;int i;for ( i &#61; 0; i min[n]-minMod[n]<&#61;*(p&#43;n))&&(*(p&#43;n)<&#61;c.cb[i]->max[n]&#43;maxMod[n])){matchChannel&#43;&#43;;}else break;}if (matchChannel &#61;&#61; numChannels)break;}//无码元匹配&#xff0c;则判断为前景&#xff0c;返回255白色&#xff0c;否则返回0黑色if (i &#61;&#61; c.numEntries)return(255);return (0);
}//清除长时间未更新码元
int clearStaleEntries(codeBook&c)
{int staleThresh &#61; c.t >> 1;int *keep &#61; new int[c.numEntries];int keepCnt &#61; 0;for (int i &#61; 0; i stale>staleThresh){keep[i] &#61; 0;}else{keep[i] &#61; 1;keepCnt&#43;&#43;;}}c.t &#61; 0;code_element **foo &#61; new code_element*[keepCnt];int k &#61; 0;for (int j &#61; 0; j stale &#61; 0;foo[k]->t_last_update &#61; 0;k&#43;&#43;;}}delete[]keep;delete[]c.cb;c.cb &#61; foo;int numCleared &#61; c.numEntries - keepCnt;c.numEntries &#61; keepCnt;return(numCleared);
}int main()
{VideoCapture capture;capture.open("tree.avi");Mat rawImage;capture >> rawImage;Mat yuvImage(rawImage.rows, rawImage.cols, CV_8UC3);Mat ImaskCodeBook(rawImage.rows, rawImage.cols, CV_8UC1, Scalar(255));uchar *pColor;int imageLen&#61;rawImage.rows*rawImage.cols;codeBook*cB&#61;new codeBook[imageLen];int nChannel &#61; CHANNELS;unsigned cbBound[CHANNELS];int minMod[CHANNELS];int maxMod[CHANNELS];//定义像素个码本for (int i &#61; 0; i > rawImage;if (rawImage.empty()){break;}cvtColor(rawImage, yuvImage, COLOR_BGR2YCrCb);if (i <&#61; 30){pColor &#61; (uchar *)(yuvImage.ptr(0));for (int c &#61; 0; c (0));uchar *pMask &#61; (uchar*)(ImaskCodeBook.ptr(0));for (int c &#61; 0; c }

小博客现在只有FLAG和油炸火同学在看。还是附上微信&#xff0c;万一以后有人看呢。hh
欢迎交流&#xff1a;wechat&#xff1a;l18090123402


推荐阅读
  • 第二十五天接口、多态
    1.java是面向对象的语言。设计模式:接口接口类是从java里衍生出来的,不是python原生支持的主要用于继承里多继承抽象类是python原生支持的主要用于继承里的单继承但是接 ... [详细]
  • 本文介绍了几种常用的图像相似度对比方法,包括直方图方法、图像模板匹配、PSNR峰值信噪比、SSIM结构相似性和感知哈希算法。每种方法都有其优缺点,适用于不同的应用场景。 ... [详细]
  • 在 Linux 环境下,多线程编程是实现高效并发处理的重要技术。本文通过具体的实战案例,详细分析了多线程编程的关键技术和常见问题。文章首先介绍了多线程的基本概念和创建方法,然后通过实例代码展示了如何使用 pthreads 库进行线程同步和通信。此外,还探讨了多线程程序中的性能优化技巧和调试方法,为开发者提供了宝贵的实践经验。 ... [详细]
  • 探讨CUDA代码中的内联汇编指令‘ld’和‘add’为何出现参数不匹配的编译错误,并提供解决方案。 ... [详细]
  • 本文回顾了作者初次接触Unicode编码时的经历,并详细探讨了ASCII、ANSI、GB2312、UNICODE以及UTF-8和UTF-16编码的区别和应用场景。通过实例分析,帮助读者更好地理解和使用这些编码。 ... [详细]
  • 单片微机原理P3:80C51外部拓展系统
      外部拓展其实是个相对来说很好玩的章节,可以真正开始用单片机写程序了,比较重要的是外部存储器拓展,81C55拓展,矩阵键盘,动态显示,DAC和ADC。0.IO接口电路概念与存 ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 在Delphi7下要制作系统托盘,只能制作一个比较简单的系统托盘,因为ShellAPI文件定义的TNotifyIconData结构体是比较早的版本。定义如下:1234 ... [详细]
  • 题目《BZOJ2654: Tree》的时间限制为30秒,内存限制为512MB。该问题通过结合二分查找和Kruskal算法,提供了一种高效的优化解决方案。具体而言,利用二分查找缩小解的范围,再通过Kruskal算法构建最小生成树,从而在复杂度上实现了显著的优化。此方法不仅提高了算法的效率,还确保了在大规模数据集上的稳定性能。 ... [详细]
  • 本文提出了一种基于栈结构的高效四则运算表达式求值方法。该方法能够处理包含加、减、乘、除运算符以及十进制整数和小括号的算术表达式。通过定义和实现栈的基本操作,如入栈、出栈和判空等,算法能够准确地解析并计算输入的表达式,最终输出其计算结果。此方法不仅提高了计算效率,还增强了对复杂表达式的处理能力。 ... [详细]
  • 深入解析C语言中结构体的内存对齐机制及其优化方法
    为了提高CPU访问效率,C语言中的结构体成员在内存中遵循特定的对齐规则。本文详细解析了这些对齐机制,并探讨了如何通过合理的布局和编译器选项来优化结构体的内存使用,从而提升程序性能。 ... [详细]
  • 在深入探讨进程间通信技术时,本文重点解析了描述符传递的方法。通过详细分析发送和接收描述符的过程,文章首先介绍了发送描述符的具体步骤,并提供了相关函数原型。此外,还讨论了如何高效地在不同进程之间传输文件描述符,以实现资源的共享和同步。这一技术在多进程应用中具有重要意义,能够显著提升系统的性能和可靠性。 ... [详细]
  • 在2019年寒假强化训练中,我们深入探讨了二分算法的理论与实践应用。问题A聚焦于使用递归方法实现二分查找。具体而言,给定一个已按升序排列且无重复元素的数组,用户需从键盘输入一个数值X,通过二分查找法判断该数值是否存在于数组中。输入的第一行为一个正整数,表示数组的长度。这一训练不仅强化了对递归算法的理解,还提升了实际编程能力。 ... [详细]
  • 计算机视觉领域介绍 | 自然语言驱动的跨模态行人重识别前沿技术综述(上篇)
    本文介绍了计算机视觉领域的最新进展,特别是自然语言驱动的跨模态行人重识别技术。上篇内容详细探讨了该领域的基础理论、关键技术及当前的研究热点,为读者提供了全面的概述。 ... [详细]
  • 虚拟机网络设置与数据库远程连接优化指南
    本文针对个人计算机上虚拟机网络配置与数据库远程连接的问题,提供了一套详细的优化指南。在探讨远程数据库访问前,需确保网络配置正确,特别是桥接模式的设置。通过合理的网络配置,可以有效解决因虚拟机或网络问题导致的连接失败,提升远程访问的稳定性和效率。 ... [详细]
author-avatar
封鹏
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有