鱼C论坛

 找回密码
 立即注册
查看: 2751|回复: 2

求参考程序进行研究

[复制链接]
发表于 2015-6-17 16:30:11 | 显示全部楼层 |阅读模式
20鱼币
求一个应用opencv进行视频运动目标跟踪的程序,最好使用混合高斯模型

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2015-6-19 10:19:32 | 显示全部楼层
这是程序代码
typedef struct _IplImage
{
int nSize;// IplImage 大小
int ID;// 版本(=0)
int nChannels;// 图像通道数
int alphaChannel;// 被OpenCV 忽略
int depth;// 像素的位深度
char colorModel[4];// 被OpenCV 忽略
char channelSeq[4];// 同上
int dataOrder;// 0 - 交叉存取颜色通道,- 分开的颜色通道
int origin;// 图像原点位置
int align;// 图像行排列方式,在OpenCV 被忽略
int width;// 图像宽像素数
int height;// 图像高像素数
struct _IplROI *roi;// 图像感兴趣区域,非空时只对该区域进行处理
struct _IplImage *maskROI;// 在OpenCV 中必须为NULL
void * imageId;// 同上
struct _IplTileInfo *tileInfo;// 同上
int imageSize;// 图像数据大小单位字节
char *imageData;// 指向排列的图像数据
int widthStep;// 排列的图像行大小,以字节为单位
int BorderMode[4];// 边际结束模式,在OpenCV 被忽略
int BorderConst[4];// 同上
char * imageDataOrigin;// 指针指向一个不同的图像数据结构
} IplImage;
OpenCV 支持从摄像头或视频文件(AVI 格式)中捕捉视频帧图像,以下是一些关键代码:
(4) 初始化一个摄像头捕捉器:
CvCapture * capture = cvCaptureFromCAM(0);
(5) 初始化一个视频文件捕捉器:
CvCapture * capture = cvCaptureFromFile("filename.avi");
(6) 读取视频文件:
IplImage * pFrame = NULL;// 声明IplImage 指针
cvNamedWindow("Frame", 1);// 创建窗口
// 循环读取每帧视频图像
while( pFrame = cvQueryFrame (capture) )
{
cvShowImage("Frame", pFrame);// 显示图像
// 如果有按键事件,则跳出循环
// 此等待也为cvShowImage 函数提供时间完成显示
// 等待时间可以根据CPU 速度调整
if( cvWaitKey(20) >=0 )
break;
}
CvGaussBGModel* bg_model=NULL;//初始化高斯混合模型参数
while(pFrame = cvQueryFrame( pCapture ))
{
nFrmNum++;
// 如果是第一帧,需要申请内存,并初始化
if(nFrmNum == 1)
{
pBkImg = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 3);
pFrImg = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U,1);
pNextImg = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U,1);
// 高斯背景建模,pFrame 可以是多通道图像也可以是单通道图像
// cvCreateGaussianBGModel 函数返回值为CvBGStatModel*,
// 需要强制转换成CvGaussBGModel*
bg_model = (CvGaussBGModel*)cvCreateGaussianBGModel(pFrame, 0);
}
else
{
//更新高斯模型
cvUpdateBGStatModel(pFrame, (CvBGStatModel *)bg_model );
// pFrImg 为前景图像,只能为单通道
// pBkImg 为背景图像,可以为单通道或与pFrame 通道数相同
cvCopy(bg_model->foreground,pFrImg,0);
cvCopy(bg_model->background,pBkImg,0);
// 把图像正过来
pBkImg->origin=1;
pFrImg->origin=1;
cvSmooth(pFrImg, pFrImg, CV_GAUSSIAN, 5, 0, 0); // 图像平滑操作
cvErode(pFrImg, pFrImg, 0, 1); // 图像腐蚀操作
cvDilate(pFrImg, pFrImg, 0, 1); // 图像膨胀操作
// 用矩形框在原图上画出运动目标
SignID(pFrame,pFrImg);
// 提取SIFT 特征并判断相同运动目标,并描绘其运动目标轨迹
PreObject=Path(pNextImg,pFrame,PreObject);
// 显示图像
cvShowImage("video", pFrame);
cvShowImage("background", pBkImg);
cvShowImage("foreground", pFrImg);
if( cvWaitKey(20) >=0 )
break;
}
}
static int CompareContour(const void* a, const void* b, void* )
{
float dx,dy;
float h,w,ht,wt;
CvPoint2D32f pa,pb;
CvRect ra,rb;
CvSeq* pCA = *(CvSeq**)a;
CvSeq* pCB = *(CvSeq**)b;
ra = ((CvContour*)pCA)->rect;
rb = ((CvContour*)pCB)->rect;
pa.x = ra.x + ra.width*0.5f;
pa.y = ra.y + ra.height*0.5f;
pb.x = rb.x + rb.width*0.5f;
pb.y = rb.y + rb.height*0.5f;
w = (ra.width+rb.width)*0.5f;
h = (ra.height+rb.height)*0.5f;
dx = (float)(fabs(pa.x - pb.x)-w);
dy = (float)(fabs(pa.y - pb.y)-h);
wt = MAX(ra.width, rb.width)*0.3f; // 宽度距离限制
ht = MAX(ra.height, rb.height)*0.3f; // 高度距离限制
return (dx < wt && dy < ht);
}
BlobDetector::BlobDetector(void)
: m_HMin(0.05)
, m_HMax(0.95)
, m_WMin(0.05)
, m_WMax(0.95)
{
AddParam("HMin", &m_HMin);
AddParam("HMax", &m_HMax);
AddParam("WMin", &m_WMin);
AddParam("WMax", &m_WMax);
SetParam("DebugWnd",0);
SetModuleName("BD Detector");
}
BlobDetector::~BlobDetector(void)
{
}
void BlobDetector::cvFindBlobsByCCClasters(IplImage* pFG, CvBlobSeq* pBlobs, CvMemStorage* storage)
{
IplImage* pIB = NULL;
CvSeq* cnt = NULL;
CvSeq* cnt_list = cvCreateSeq(0, sizeof(CvSeq), sizeof(CvSeq*), storage);
CvSeq* clasters = NULL;
int claster_cur, claster_num;
pIB = cvCloneImage(pFG);
cvThreshold(pIB, pIB, 128, 255, CV_THRESH_BINARY);
cvFindContours(pIB, storage, &cnt, sizeof(CvContour), CV_RETR_EXTERNAL);
cvReleaseImage(&pIB);
for(; cnt; cnt=cnt->h_next)
{
cvSeqPush(cnt_list, &cnt);
}
claster_num = cvSeqPartition(cnt_list, storage, &clasters, CompareContour, NULL);
for(claster_cur=0; claster_cur<claster_num; claster_cur++)
{
CvBlob NewBlob;
double M00,X,Y,XX,YY;
CvMoments m;
CvRect rect_res = cvRect(-1,-1,-1,-1);
CvMat mat;
for(int cnt_cur=0; cnt_cur<clasters->total; ++cnt_cur)
{
CvRect rect;
CvSeq* cnt;
int k = *(int*)cvGetSeqElem(clasters, cnt_cur);
if(k!=claster_cur) continue;
cnt = *(CvSeq**)cvGetSeqElem(cnt_list, cnt_cur);
rect = ((CvContour*)cnt)->rect;
if(rect_res.height<0)
{
rect_res = rect;
}
else
{
int x0,x1,y0,y1;
x0 = MIN(rect_res.x, rect.x);
y0 = MIN(rect_res.y, rect.y);
x1 = MAX(rect_res.x+rect_res.width, rect.x+rect.width);
y1 = MAX(rect_res.y+rect_res.height, rect.y+rect.height);
rect_res.x = x0;
rect_res.y = y0;
rect_res.width = x1-x0;
rect_res.height = y1-y0;
}
}
if(rect_res.height < 1 || rect_res.width < 1)
{
X = 0;
Y = 0;
XX = 0;
YY = 0;
}
else
{
cvMoments(cvGetSubRect(pFG,&mat,rect_res), &m, 0);
M00 = cvGetSpatialMoment(&m, 0, 0);
if(M00 <= 0 ) continue;
X = cvGetSpatialMoment(&m, 1, 0)/M00;
Y = cvGetSpatialMoment(&m, 0, 1)/M00;
XX = (cvGetSpatialMoment(&m, 2, 0)/M00) - X*X;
YY = (cvGetSpatialMoment(&m, 0, 2)/M00) - Y*Y;
}
NewBlob = cvBlob(rect_res.x+(float)X, rect_res.y+(float)Y, (float)(4*sqrt(XX)), (float)(4*sqrt(YY)));
pBlobs->AddBlob(&NewBlob);
}
if(m_Wnd)
{ // Debug info:
IplImage* pI = cvCreateImage(cvSize(pFG->width,pFG->height),IPL_DEPTH_8U,3);
cvZero(pI);
for(claster_cur=0; claster_cur<claster_num; ++claster_cur)
{
int cnt_cur;
CvScalar color = CV_RGB(rand()%256,rand()%256,rand()%256);
for(cnt_cur=0; cnt_cur<clasters->total; ++cnt_cur)
{
CvSeq* cnt;
int k = *(int*)cvGetSeqElem( clasters, cnt_cur );
if(k!=claster_cur) continue;
cnt = *(CvSeq**)cvGetSeqElem( cnt_list, cnt_cur );
cvDrawContours( pI, cnt, color, color, 0, CV_FILLED, 8);
}
CvBlob* pB = pBlobs->GetBlob(claster_cur);
int x = cvRound(CV_BLOB_RX(pB)), y = cvRound(CV_BLOB_RY(pB));
cvEllipse( pI, cvPointFrom32f(CV_BLOB_CENTER(pB)), cvSize(MAX(1,x), MAX(1,y)), 0, 0, 360, color, 1 );
}
cvNamedWindow( "Clusters", 0);
cvResizeWindow( "Clusters", pI->width, pI->height) ;
cvShowImage( "Clusters",pI );
cvReleaseImage(&pI);
} /* Debug info. */
}
int BlobDetector::DetectNewBlob(IplImage* pImg, IplImage* pFGMask, CvBlobSeq* pNewBlobList, CvBlobSeq* pOldBlobList)
{
int result = 0;
CvSize S = cvSize(pFGMask->width,pFGMask->height);
CvBlobSeq Blobs;
CvMemStorage* storage = cvCreateMemStorage();
cvFindBlobsByCCClasters(pFGMask, &Blobs, storage );
for(int i=Blobs.GetBlobNum(); i>0; i--)
{
CvBlob* pB = Blobs.GetBlob(i-1);
if(pB->h < pFGMask->height*m_HMin || pB->w < pFGMask->width*m_WMin)
{
Blobs.DelBlob(i-1); continue;
}
if(pB->h > pFGMask->height*m_HMax || pB->w > pFGMask->width*m_WMax)
{
Blobs.DelBlob(i-1); continue;
}
if(MIN(pB->x,pFGMask->width-pB->x) < CV_BLOB_RX(pB) || MIN(pB->y,pFGMask->height-pB->y) < CV_BLOB_RY(pB))
{
Blobs.DelBlob(i-1); continue;
}
if(pOldBlobList)
{
for(int j=pOldBlobList->GetBlobNum(); j>0; j--)
{
CvBlob* pBOld = pOldBlobList->GetBlob(j-1);
if((fabs(pBOld->x-pB->x) < (CV_BLOB_RX(pBOld)+CV_BLOB_RX(pB))) && (fabs(pBOld->y-pB->y) < (CV_BLOB_RY(pBOld)+CV_BLOB_RY(pB))))
{
Blobs.DelBlob(i-1);
break;
}
}
}
}
{
int N = Blobs.GetBlobNum();
for(int i=1; i<N; i++)
{
for(int j=i; j>0; j--)
{
CvBlob temp;
float AreaP, AreaN;
CvBlob* pP = Blobs.GetBlob(j-1);
CvBlob* pN = Blobs.GetBlob(j);
AreaP = CV_BLOB_WX(pP)*CV_BLOB_WY(pP);
AreaN = CV_BLOB_WX(pN)*CV_BLOB_WY(pN);
if(AreaN < AreaP)break;
temp = pN[0];
pN[0] = pP[0];
pP[0] = temp;
}
}
for(int i=0; i<MIN(N,10); i++)
{
pNewBlobList->AddBlob(Blobs.GetBlob(i));
result = 1;
}
}
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-6-20 18:03:17 | 显示全部楼层
谢谢!
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2026-2-16 12:31

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表