//codebook BGS method
//adapt from book of learning opencv by mikewolf
//2008-11-25
#include "stdafx.h"
#include <cv.h>
#include <highgui.h>
#define CHANNELS 3
typedef struct ce {
uchar learnHigh[CHANNELS]; //High side threshold for learning
uchar learnLow[CHANNELS]; //Low side threshold for learning
uchar max[CHANNELS]; //High side of box boundary
uchar min[CHANNELS]; //Low side of box boundary
int t_last_update; //Allow us to kill stale entries
int stale; //max negative run (longest period of inactivity)
} code_element;
//码书结构
typedef struct code_book {
code_element **cb; //指向码字的指针
int numEntries; //码书包含的码字数量
int t; //count every access
} codeBook;
codeBook* TcodeBook;//包括所有像素的码书集合
//////////////////////////////////////////////////////////////
// int update_codebook(uchar *p, codeBook &c, unsigned cbBounds)
// Updates the codebook entry with a new data point
//
// p Pointer to a YUV or HSI pixel
// c Codebook for this pixel
// cbBounds Learning bounds for codebook (Rule of thumb: 10)
// numChannels Number of color channels we’re learning
//
// NOTES:
// cvBounds must be of length equal to numChannels
//
// RETURN
// codebook index
//
int update_codebook(
uchar* p,
codeBook& c,
unsigned* cbBounds,
int numChannels
)
{
unsigned int high[3],low[3];
int n;
for(n=0; n<numChannels; n++)
{
high[n] = *(p+n)+*(cbBounds+n);
if(high[n] > 255) high[n] = 255;
low[n] = *(p+n)-*(cbBounds+n);
if(low[n] < 0) low[n] = 0;
}
int matchChannel;
// SEE IF THIS FITS AN EXISTING CODEWORD
//
for(int i=0; i<c.numEntries; i++)
{
matchChannel = 0;
for(n=0; n<numChannels; n++)
{
if((c.cb[i]->learnLow[n] <= *(p+n)) &&
//Found an entry for this channel
(*(p+n) <= c.cb[i]->learnHigh[n]))
{
matchChannel++;
}
}
if(matchChannel == numChannels) //If an entry was found
{
c.cb[i]->t_last_update = c.t;
//adjust this codeword for the first channel
for(n=0; n<numChannels; n++){
if(c.cb[i]->max[n] < *(p+n))
{
c.cb[i]->max[n] = *(p+n);
}
else if(c.cb[i]->min[n] > *(p+n))
{
c.cb[i]->min[n] = *(p+n);
}
}
break;
}
}
// OVERHEAD TO TRACK POTENTIAL STALE ENTRIES
//
for(int s=0; s<c.numEntries; s++)
{
// Track which codebook entries are going stale:
//
int negRun = c.t - c.cb[s]->t_last_update;
if(c.cb[s]->stale < negRun) c.cb[s]->stale = negRun;
}
// ENTER A NEW CODEWORD IF NEEDED
//
if(i == c.numEntries) //if no existing codeword found, make one
{
code_element **foo = new code_element* [c.numEntries+1];
for(int ii=0; ii<c.numEntries; ii++)
{
foo[ii] = c.cb[ii];
}
foo[c.numEntries] = new code_element;
if(c.numEntries) delete [] c.cb;
c.cb = foo;
for(n=0; n<numChannels; n++)
{
c.cb[c.numEntries]->learnHigh[n] = high[n];
c.cb[c.numEntries]->learnLow[n] = low[n];
c.cb[c.numEntries]->max[n] = *(p+n);
c.cb[c.numEntries]->min[n] = *(p+n);
}
c.cb[c.numEntries]->t_last_update = c.t;
c.cb[c.numEntries]->stale = 0;
c.numEntries += 1;
}
// SLOWLY ADJUST LEARNING BOUNDS
//
for(n=0; n<numChannels; n++)
{
if(c.cb[i]->learnHigh[n] < high[n]) c.cb[i]->learnHigh[n] += 1;
if(c.cb[i]->learnLow[n] > low[n]) c.cb[i]->learnLow[n] -= 1;
}
return(i);
}
///////////////////////////////////////////////////////////////////
//int clear_stale_entries(codeBook &c)
// During learning, after you’ve learned for some period of time,
// periodically call this to clear out stale codebook entries
//
// c Codebook to clean up
//
// Return
// number of entries cleared
//
int clear_stale_entries(codeBook &c){
int staleThresh = c.t>>1;
int *keep = new int [c.numEntries];
int keepCnt = 0;
// SEE WHICH CODEBOOK ENTRIES ARE TOO STALE
//
for(int i=0; i<c.numEntries; i++){
if(c.cb[i]->stale > staleThresh)
keep[i] = 0; //Mark for destruction
else
{
keep[i] = 1; //Mark to keep
keepCnt += 1;
}
}
// KEEP ONLY THE GOOD
//
c.t = 0; //Full reset on stale tracking
code_element **foo = new code_element* [keepCnt];
int k=0;
for(int ii=0; ii<c.numEntries; ii++){
if(keep[ii])
{
foo[k] = c.cb[ii];
//We have to refresh these entries for next clearStale
foo[k]->t_last_update = 0;
k++;
}
}
// CLEAN UP
//
delete [] keep;
delete [] c.cb;
c.cb = foo;
int numCleared = c.numEntries - keepCnt;
c.numEntries = keepCnt;
return(numCleared);
}
////////////////////////////////////////////////////////////
// uchar background_diff( uchar *p, codeBook &c,
// int minMod, int maxMod)
// Given a pixel and a codebook, determine if the pixel is
// covered by the codebook
//
// p Pixel pointer (YUV interleaved)
// c Codebook reference
// numChannels Number of channels we are testing
// maxMod Add this (possibly negative) number onto
// max level when determining if new pixel is foreground
// minMod Subract this (possibly negative) number from
// min level when determining if new pixel is foreground
//
// NOTES:
// minMod and maxMod must have length numChannels,
// e.g. 3 channels => minMod[3], maxMod[3]. There is one min and
// one max threshold per channel.
//
// Return
// 0 => background, 255 => foreground
//
uchar background_diff(
uchar* p,
codeBook& c,
int numChannels,
int* minMod,
int* maxMod
)
{
int matchChannel;
// SEE IF THIS FITS AN EXISTING CODEWORD
//
for(int i=0; i<c.numEntries; i++) {
matchChannel = 0;
for(int n=0; n<numChannels; n++) {
if((c.cb[i]->min[n] - minMod[n] <= *(p+n)) &&
(*(p+n) <= c.cb[i]->max[n] + maxMod[n])) {
matchChannel++; //Found an entry for this channel
} else {
break;
}
}
if(matchChannel == numChannels) {
break; //Found an entry that matched all channels
}
}
if(i >= c.numEntries) return(255);
return(0);
}
IplImage* pFrame = NULL;
IplImage* pFrameHSV = NULL;
IplImage* pFrImg = NULL;
CvCapture* pCapture = NULL;
int nFrmNum = 0;
//IplImage* pFrImg = NULL;
//IplImage* pBkImg = NULL;
unsigned cbBounds = 10;
int height,width;
int nchannels;
int minMod[3]={20,20,20}, maxMod[3]={20,20,20};
int _tmain(int argc, _TCHAR* argv[])
{
//创建窗口
cvNamedWindow("video", 1);
cvNamedWindow("HSV空间图像",1);
cvNamedWindow("foreground",1);
//使窗口有序排列
cvMoveWindow("video", 30, 0);
cvMoveWindow("HSV空间图像", 360, 0);
cvMoveWindow("foreground", 690, 0);
//打开视频文件,
if( !(pCapture = cvCaptureFromFile("3.avi")))
{
fprintf(stderr, "Can not open video file %s\n");
return -2;
}
int j;
//逐帧读取视频
while(pFrame = cvQueryFrame( pCapture ))
{
nFrmNum++;
cvShowImage("video", pFrame);
if (nFrmNum == 1)
{
height = pFrame->height;
width = pFrame->width;
nchannels = pFrame->nChannels;
pFrameHSV = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,3);
pFrImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);
//cvCvtColor(pFrame, pFrameHSV, CV_BGR2HSV);//色
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
【达摩老生出品,必属精品,亲测校正,质量保证】 资源名:基于codebook运动目标检测_matlab 资源类型:matlab项目全套源码 源码说明: 全部项目源码都是经过测试校正后百分百成功运行的,如果您下载后不能运行可联系我进行指导或者更换。 适合人群:新手及有一定经验的开发人员
资源推荐
资源详情
资源评论
收起资源包目录
基于codebook运动目标检测.rar (18个子文件)
Matlab实现无约束条件下普列姆(Prim)算法.docx 14KB
testCodeBook
cvaux100.dll 584KB
testCodeBook.plg 2KB
cxts001.dll 128KB
testCodeBook.opt 48KB
WavingTrees.avi 2.85MB
testCodeBook.dsw 549B
cv100.dll 824KB
testCodeBook.ncb 33KB
testCodeBook.dsp 4KB
滑动平均.txt 3KB
highgui100.dll 612KB
cxcore100.dll 988KB
sssss.cpp 9KB
learning opencv 一书中的codebook调试代码.txt 10KB
Thumbs.db 13KB
libguide40.dll 192KB
Debug
ml100.dll 244KB
共 18 条
- 1
资源评论
阿里matlab建模师
- 粉丝: 3510
- 资源: 2787
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功