1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
10 // Intel License Agreement
12 // Copyright (C) 2000, Intel Corporation, all rights reserved.
13 // Third party copyrights are property of their respective owners.
15 // Redistribution and use in source and binary forms, with or without modification,
16 // are permitted provided that the following conditions are met:
18 // * Redistribution's of source code must retain the above copyright notice,
19 // this list of conditions and the following disclaimer.
21 // * Redistribution's in binary form must reproduce the above copyright notice,
22 // this list of conditions and the following disclaimer in the documentation
23 // and/or other materials provided with the distribution.
25 // * The name of Intel Corporation may not be used to endorse or promote products
26 // derived from this software without specific prior written permission.
28 // This software is provided by the copyright holders and contributors "as is" and
29 // any express or implied warranties, including, but not limited to, the implied
30 // warranties of merchantability and fitness for a particular purpose are disclaimed.
31 // In no event shall the Intel Corporation or contributors be liable for any direct,
32 // indirect, incidental, special, exemplary, or consequential damages
33 // (including, but not limited to, procurement of substitute goods or services;
34 // loss of use, data, or profits; or business interruption) however caused
35 // and on any theory of liability, whether in contract, strict liability,
36 // or tort (including negligence or otherwise) arising in any way out of
37 // the use of this software, even if advised of the possibility of such damage.
42 This file contain implementation of virtual interface of CvTestSeq
45 #include "_cvaux.h" /* virtual interface if CvTestSeq */
47 #define FG_BG_THRESHOLD 3
49 #define SRC_TYPE_AVI 1
50 #define SRC_TYPE_IMAGE 0
52 /* Transformation structure */
53 typedef struct CvTSTrans
55 float T[6]; /* geometry transformation */
60 float GN; /* standart deviation of added gaussian noise */
61 float NoiseAmp; /* amplifier of noise power */
64 void SET_TRANS_0(CvTSTrans *pT)
66 memset(pT,0,sizeof(CvTSTrans));
70 pT->T[4] = pT->T[0] = 1;
74 /* ===some defenitions and function for transformation update ===*/
85 static char* param_name[] = {"angle","s","sx","sy","dx","dy","I","C","GN","NoiseAmp", NULL};
86 static float param_defval[] = { 0, 1, 1, 1, 0, 0, 0, 1, 0, 1};
87 static void icvUpdateTrans(CvTSTrans* pTrans, int param, double val, float MaxX, float MaxY)
93 double C = cos(3.1415926535897932384626433832795*val/180.0);
94 double S = sin(3.1415926535897932384626433832795*val/180.0);
98 pTrans->angle = (float)(pTrans->angle + val);
99 TR[0] = C*T[0]-S*T[3];
100 TR[1] = C*T[1]-S*T[4];
101 TR[2] = C*T[2]-S*T[5];
102 TR[3] = S*T[0]+C*T[3];
103 TR[4] = S*T[1]+C*T[4];
104 TR[5] = S*T[2]+C*T[5];
105 for(i=0;i<6;++i)T[i]=(float)TR[i];
110 for(i=0;i<6;++i)pTrans->T[i] = (float)(pTrans->T[i]*val);
111 pTrans->Scale.x = (float)(pTrans->Scale.x *val);
112 pTrans->Scale.y = (float)(pTrans->Scale.y *val);
113 pTrans->Shift.x = (float)(pTrans->Shift.x *val);
114 pTrans->Shift.y = (float)(pTrans->Shift.y *val);
119 for(i=0;i<3;++i)pTrans->T[i] = (float)(pTrans->T[i]*val);
120 pTrans->Scale.x = (float)(pTrans->Scale.x*val);
121 pTrans->Shift.x = (float)(pTrans->Shift.x*val);
126 for(i=0;i<3;++i)pTrans->T[i+3] = (float)(pTrans->T[i+3]*val);
127 pTrans->Scale.y = (float)(pTrans->Scale.y *val);
128 pTrans->Shift.y = (float)(pTrans->Shift.y *val);
132 pTrans->Shift.x = (float)(pTrans->Shift.x +val);
133 pTrans->T[2] = (float)(pTrans->T[2] +val*MaxX);
137 pTrans->Shift.y = (float)(pTrans->Shift.y +val);
138 pTrans->T[5] = (float)(pTrans->T[5] +val*MaxY);
142 pTrans->C = (float)(pTrans->C *val);
143 pTrans->I = (float)(pTrans->I *val);
145 if(param==P_I) pTrans->I = (float)(pTrans->I +val);
148 pTrans->GN = (float)sqrt(val*val+pTrans->GN*pTrans->GN);
150 if(param==P_NAmp) pTrans->NoiseAmp = (float)(pTrans->NoiseAmp *val);
151 }/* icvUpdateTrans */
152 /* === END some defenitions and function for transformation update ===*/
154 typedef struct CvTestSeqElem
156 const char* pObjName;
157 const char* pFileName;
158 int type; /* video or image */
159 CvPoint2D32f* pPos; /* positions of object in sequence */
161 CvPoint2D32f* pSize; /* sizes of object in sequence */
163 CvTSTrans* pTrans; /* transforation of image in sequence */
166 CvPoint2D32f ShiftBegin;
167 CvPoint2D32f ShiftEnd;
175 int BG; /* flag is it background (1) or foreground (0) */
176 int Mask; /* flag is it foreground mask (1) or usual video (0) */
179 CvRandState rnd_state;
182 /* test seq main structure */
183 typedef struct CvTestSeq_
186 CvFileStorage* pFileStorage;
187 CvTestSeqElem* pElemList;
205 CvSize cvTestSeqGetImageSize(CvTestSeq* pTestSeq){return cvSize(((CvTestSeq_*)(pTestSeq))->pImg->width,((CvTestSeq_*)(pTestSeq))->pImg->height);}
206 int cvTestSeqFrameNum(CvTestSeq* pTestSeq){return ((CvTestSeq_*)(pTestSeq))->FrameNum;}
207 static void icvTestSeqCreateMask(IplImage* pImg,IplImage* pImgMask, int threshold)
209 if(pImg->nChannels > 1)
211 cvCvtColor( pImg,pImgMask,CV_BGR2GRAY);
212 cvThreshold(pImgMask,pImgMask,threshold,255,CV_THRESH_BINARY);
216 cvThreshold(pImg,pImgMask,threshold,255,CV_THRESH_BINARY);
218 }/* icvTestSeqCreateMask */
221 static void icvTestSeqQureyFrameElem(CvTestSeqElem* p, int /*frame*/)
222 {/* read next frame from avi for one record */
223 if(p->type == SRC_TYPE_AVI)
226 //int frameNum = p->AVILen;
228 if(p->pAVI == NULL && p->pFileName)
229 {/* open avi file if it is necessary */
230 p->pAVI = 0;//cvCaptureFromFile(p->pFileName);
233 printf("WARNING!!! Can not open avi file %s\n",p->pFileName);
236 }/* open avi file if it is necessary */
239 //if(frame >= frameNum)
240 {/* set new position */
241 //int N = frame%frameNum;
244 N != (int)cvGetCaptureProperty(p->pAVI,CV_CAP_PROP_POS_FRAMES))
246 cvSetCaptureProperty(p->pAVI,CV_CAP_PROP_POS_FRAMES,N);
248 }/* set new position */
250 //pI = cvQueryFrame(p->pAVI);
253 if(pI->origin != p->pImg->origin)
254 cvFlip( pI, p->pImg, 0 );
256 cvCopyImage(pI, p->pImg);
261 if(p->pImgMask==NULL)
263 p->pImgMask = cvCreateImage(
264 cvSize(p->pImg->width,p->pImg->height),
267 icvTestSeqCreateMask(p->pImg,p->pImgMask,p->Mask?128:FG_BG_THRESHOLD);
271 }/* icvTestSeqQureyFrameElem */
273 /*------------- recursive function to read all images,------------------------*/
274 /*-------------------videos and objects from config file ---------------------*/
275 static CvTestSeqElem* icvTestSeqReadElemAll(CvTestSeq_* pTS, CvFileStorage* fs, const char* name);
276 static void icvTestSeqAllocTrans(CvTestSeqElem* p)
277 {/*allocate transformation array if necessary */
278 /* work with transformation */
279 if(p->pTrans == NULL/* && p->FrameNum>0*/)
280 {/* allocate transforamtion array */
281 int num = MAX(1,p->FrameNum);
282 p->pTrans = (CvTSTrans*)cvAlloc(sizeof(CvTSTrans)*num);
284 while(num--)SET_TRANS_0(p->pTrans+num);
287 if(p->FrameNum > p->TransNum)
288 {/* allocate new transforamtion array */
290 int num = p->FrameNum;
291 CvTSTrans* pNewTrans = (CvTSTrans*)cvAlloc(sizeof(CvTSTrans)*num);
295 pNewTrans[i] = p->pTrans[i%p->TransNum];
297 SET_TRANS_0(pNewTrans+i);
299 if(p->pTrans)cvFree(&p->pTrans);
300 p->pTrans = pNewTrans;
302 }/* allocate new transforamtion array */
303 }/*allocate transformation array if necessary */
305 static CvTestSeqElem* icvTestSeqReadElemOne(CvTestSeq_* pTS, CvFileStorage* fs, CvFileNode* node)
307 int noise_type = CV_NOISE_NONE;;
308 CvTestSeqElem* pElem = NULL;
309 const char* pVideoName = cvReadStringByName( fs, node,"Video", NULL);
310 const char* pVideoObjName = cvReadStringByName( fs, node,"VideoObj", NULL);
313 {/* check to noise flag */
314 if( cv_stricmp(pVideoName,"noise_gaussian") == 0 ||
315 cv_stricmp(pVideoName,"noise_normal") == 0) noise_type = CV_NOISE_GAUSSIAN;
316 if( cv_stricmp(pVideoName,"noise_uniform") == 0) noise_type = CV_NOISE_UNIFORM;
317 if( cv_stricmp(pVideoName,"noise_speckle") == 0) noise_type = CV_NOISE_SPECKLE;
318 if( cv_stricmp(pVideoName,"noise_salt_and_pepper") == 0) noise_type = CV_NOISE_SALT_AND_PEPPER;
321 if((pVideoName || pVideoObjName ) && noise_type == CV_NOISE_NONE)
322 {/* read other elements */
323 if(pVideoName) pElem = icvTestSeqReadElemAll(pTS, fs, pVideoName);
327 pElem = icvTestSeqReadElemAll(pTS, fs, pVideoObjName);
328 for(pE=pElem;pE;pE=pE->next)
330 pE->ObjID = pTS->ObjNum;
331 pE->pObjName = pVideoObjName;
335 }/* read other elements */
337 {/* create new elem */
338 CvFileNode* pPosNode = cvGetFileNodeByName( fs, node,"Pos");
339 CvFileNode* pSizeNode = cvGetFileNodeByName( fs, node,"Size");
340 int AutoSize = (pSizeNode && CV_NODE_IS_STRING(pSizeNode->tag) && cv_stricmp("auto",cvReadString(pSizeNode,""))==0);
341 int AutoPos = (pPosNode && CV_NODE_IS_STRING(pPosNode->tag) && cv_stricmp("auto",cvReadString(pPosNode,""))==0);
342 const char* pFileName = cvReadStringByName( fs, node,"File", NULL);
343 pElem = (CvTestSeqElem*)cvAlloc(sizeof(CvTestSeqElem));
344 memset(pElem,0,sizeof(CvTestSeqElem));
347 pElem->noise_type = noise_type;
348 cvRandInit( &pElem->rnd_state, 1, 0, 0,CV_RAND_NORMAL);
350 if(pFileName && pElem->noise_type == CV_NOISE_NONE)
352 size_t l = strlen(pFileName);
353 pElem->pFileName = pFileName;
355 pElem->type = SRC_TYPE_IMAGE;
356 if(cv_stricmp(".avi",pFileName+l-4) == 0)pElem->type = SRC_TYPE_AVI;
358 if(pElem->type == SRC_TYPE_IMAGE)
360 //pElem->pImg = cvLoadImage(pFileName);
364 if(pElem->pImgMask)cvReleaseImage(&(pElem->pImgMask));
366 pElem->pImgMask = cvCreateImage(
367 cvSize(pElem->pImg->width,pElem->pImg->height),
369 icvTestSeqCreateMask(pElem->pImg,pElem->pImgMask,FG_BG_THRESHOLD);
373 if(pElem->type == SRC_TYPE_AVI && pFileName)
375 //pElem->pAVI = cvCaptureFromFile(pFileName);
379 IplImage* pImg = 0;//cvQueryFrame(pElem->pAVI);
380 pElem->pImg = cvCloneImage(pImg);
381 pElem->pImg->origin = 0;
382 //cvSetCaptureProperty(pElem->pAVI,CV_CAP_PROP_POS_FRAMES,0);
383 pElem->FrameBegin = 0;
384 pElem->AVILen = pElem->FrameNum = 0;//(int)cvGetCaptureProperty(pElem->pAVI, CV_CAP_PROP_FRAME_COUNT);
385 //cvReleaseCapture(&pElem->pAVI);
390 printf("WARNING!!! Can not open avi file %s\n",pFileName);
397 {/* read positions */
398 if(CV_NODE_IS_SEQ(pPosNode->tag))
400 int num = pPosNode->data.seq->total;
401 pElem->pPos = (CvPoint2D32f*)cvAlloc(sizeof(float)*num);
402 cvReadRawData( fs, pPosNode, pElem->pPos, "f" );
403 pElem->PosNum = num/2;
404 if(pElem->FrameNum == 0) pElem->FrameNum = pElem->PosNum;
410 if(CV_NODE_IS_SEQ(pSizeNode->tag))
412 int num = pSizeNode->data.seq->total;
413 pElem->pSize = (CvPoint2D32f*)cvAlloc(sizeof(float)*num);
414 cvReadRawData( fs, pSizeNode, pElem->pSize, "f" );
415 pElem->SizeNum = num/2;
419 if(AutoPos || AutoSize)
420 {/* auto size and pos */
422 int num = (pElem->type == SRC_TYPE_AVI)?pElem->AVILen:1;
425 pElem->pSize = (CvPoint2D32f*)cvAlloc(sizeof(CvPoint2D32f)*num);
426 pElem->SizeNum = num;
430 pElem->pPos = (CvPoint2D32f*)cvAlloc(sizeof(CvPoint2D32f)*num);
436 IplImage* pFG = NULL;
437 CvPoint2D32f* pPos = AutoPos?(pElem->pPos + i):NULL;
438 CvPoint2D32f* pSize = AutoSize?(pElem->pSize + i):NULL;
440 icvTestSeqQureyFrameElem(pElem,i);
441 pFG = pElem->pImgMask;
458 cvMoments( pElem->pImgMask, &m, 0 );
459 M00 = cvGetSpatialMoment( &m, 0, 0 );
460 if(M00 > 0 && pSize )
462 double X = cvGetSpatialMoment( &m, 1, 0 )/M00;
463 double Y = cvGetSpatialMoment( &m, 0, 1 )/M00;
464 double XX = (cvGetSpatialMoment( &m, 2, 0 )/M00) - X*X;
465 double YY = (cvGetSpatialMoment( &m, 0, 2 )/M00) - Y*Y;
466 pSize->x = (float)(4*sqrt(XX))/(pElem->pImgMask->width-1);
467 pSize->y = (float)(4*sqrt(YY))/(pElem->pImgMask->height-1);
471 pPos->x = (float)(cvGetSpatialMoment( &m, 1, 0 )/(M00*(pElem->pImgMask->width-1)));
472 pPos->y = (float)(cvGetSpatialMoment( &m, 0, 1 )/(M00*(pElem->pImgMask->height-1)));
476 { /* another way to calculate y pos using object median */
477 int y0=0,y1=pFG->height-1;
478 for(y0=0;y0<pFG->height;++y0)
481 CvScalar s = cvSum(cvGetRow(pFG, &m, y0));
482 if(s.val[0] > 255*7) break;
484 for(y1=pFG->height-1;y1>0;--y1)
487 CvScalar s = cvSum(cvGetRow(pFG, &m, y1));
488 if(s.val[0] > 255*7) break;
490 pPos->y = (y0+y1)*0.5f/(pFG->height-1);
494 //if(pElem->pAVI) cvReleaseCapture(&pElem->pAVI);
496 }/* end auto pos creation */
497 }/* create new elem */
500 {/* read transfroms and */
501 int FirstFrame, LastFrame;
502 CvTestSeqElem* p=pElem;
503 CvFileNode* pTransNode = NULL;
504 CvFileNode* pS = NULL;
507 CvSeq* pTransSeq = NULL;
510 pTransNode = cvGetFileNodeByName( fs, node,"Trans");
513 CV_NODE_IS_STRING(pTransNode->tag) &&
514 cv_stricmp("auto",cvReadString(pTransNode,""))!=0)
515 {/* Trans is reference */
516 pTransNode = cvGetFileNodeByName( fs, NULL,cvReadString(pTransNode,""));
518 pS = cvGetFileNodeByName( fs, node,"Shift");
520 pTransSeq = pTransNode?(CV_NODE_IS_SEQ(pTransNode->tag)?pTransNode->data.seq:NULL):NULL;
521 KeyFrameNum = pTransSeq?pTransSeq->total:1;
523 if( (pS && CV_NODE_IS_STRING(pS->tag) && cv_stricmp("auto",cvReadString(pS,""))==0)
524 ||(pTransNode && CV_NODE_IS_STRING(pTransNode->tag) && cv_stricmp("auto",cvReadString(pTransNode,""))==0))
529 FirstFrame = pElem->FrameBegin;
530 LastFrame = pElem->FrameBegin+pElem->FrameNum-1;
531 /* calc length of video and reallocate transformation array */
532 for(p=pElem;p;p=p->next)
535 v = cvReadIntByName( fs, node, "BG", -1 );
537 v = cvReadIntByName( fs, node, "Mask", -1 );
538 if(v!=-1)p->Mask = v;
540 p->FrameBegin += cvReadIntByName( fs, node, "FrameBegin", 0 );
541 p->FrameNum = cvReadIntByName( fs, node, "FrameNum", p->FrameNum );
542 p->FrameNum = cvReadIntByName( fs, node, "Dur", p->FrameNum );
544 int LastFrame = cvReadIntByName( fs, node, "LastFrame", p->FrameBegin+p->FrameNum-1 );
545 p->FrameNum = MIN(p->FrameNum,LastFrame - p->FrameBegin+1);
548 icvTestSeqAllocTrans(p);
550 {/* new range estimation */
551 int LF = p->FrameBegin+p->FrameNum-1;
552 if(p==pElem || FirstFrame > p->FrameBegin)FirstFrame = p->FrameBegin;
553 if(p==pElem || LastFrame < LF)LastFrame = LF;
554 }/* new range estimation */
555 }/* end allocate new transfrom array */
559 for(p=pElem;p;p=p->next)
560 {/* modify transformation to make autoshift */
562 int num = p->FrameNum;
563 assert(num <= p->TransNum);
564 p->TransNum = MAX(1,num);
567 CvTSTrans* pT = p->pTrans+i;
568 //float t = (num>1)?((float)i/(num-1)):0.0f;
569 float newx = p->pPos[i%p->PosNum].x;
570 float newy = p->pPos[i%p->PosNum].y;
571 pT->Shift.x = -newx*pT->Scale.x;
572 pT->Shift.y = -newy*pT->Scale.y;
575 newx *= p->pImg->width-1;
576 newy *= p->pImg->height-1;
578 pT->T[2] = -(pT->T[0]*newx+pT->T[1]*newy);
579 pT->T[5] = -(pT->T[3]*newx+pT->T[4]*newy);
581 }/* modify transformation old*/
584 /* init frame num array */
585 KeyFrames[0] = FirstFrame;
586 if(pTransSeq&&KeyFrameNum>1)
587 {/* init frame num array */
589 for(i=0;i<KeyFrameNum;++i)
591 CvFileNode* pTN = (CvFileNode*)cvGetSeqElem(pTransSeq,i);
592 KeyFrames[i] = cvReadIntByName(fs,pTN,"frame",-1);
594 if(KeyFrames[0]<0)KeyFrames[0]=FirstFrame;
595 if(KeyFrames[KeyFrameNum-1]<0)KeyFrames[KeyFrameNum-1]=LastFrame;
596 for(i0=0,i1=1;i1<KeyFrameNum;)
599 for(i1=i0+1;i1<KeyFrameNum && KeyFrames[i1]<0;i1++);
600 assert(i1<KeyFrameNum);
604 KeyFrames[i] = cvRound(KeyFrames[i0] + (float)(i-i0)*(float)(KeyFrames[i1] - KeyFrames[i0])/(float)(i1-i0));
609 }/* init frame num array */
611 if(pTransNode || pTransSeq)
612 {/* more complex transform */
614 CvFileNode* pTN = pTransSeq?(CvFileNode*)cvGetSeqElem(pTransSeq,0):pTransNode;
616 for(p=pElem;p;p=p->next)
618 //int trans_num = p->TransNum;
619 for(param=0;param_name[param];++param)
621 char* name = param_name[param];
622 float defv = param_defval[param];
624 {/* only one transform record */
627 CvFileNode* node = cvGetFileNodeByName( fs, pTN,name);
628 if(node == NULL) continue;
629 val = cvReadReal(node,defv);
630 for(i=0;i<p->TransNum;++i)
633 p->pTrans+i, param, val,
634 p->pImg?(float)(p->pImg->width-1):1.0f,
635 p->pImg?(float)(p->pImg->height-1):1.0f);
639 { /* several transforms */
644 CvFileNode* pTN = (CvFileNode*)cvGetSeqElem(pTransSeq,0);
645 v0 = cvReadRealByName(fs, pTN,name,defv);
647 for(i1=1,i0=0;i1<KeyFrameNum;++i1)
651 CvFileNode* pTN = (CvFileNode*)cvGetSeqElem(pTransSeq,i1);
652 CvFileNode* pVN = cvGetFileNodeByName(fs,pTN,name);
653 if(pVN)v1 = cvReadReal(pVN,defv);
654 else if(pVN == NULL && i1 == KeyFrameNum-1) v1 = defv;
658 if(i1==(KeyFrameNum-1)) f1++;
662 double t = (float)(i-f0);
663 int li = i - p->FrameBegin;
665 if(li>= p->TransNum) break;
666 if(KeyFrames[i1]>KeyFrames[i0]) t /=(float)(KeyFrames[i1]-KeyFrames[i0]);
669 p->pTrans+li, param, val,
670 p->pImg?(float)(p->pImg->width-1):1.0f,
671 p->pImg?(float)(p->pImg->height-1):1.0f);
672 }/* next transform */
675 }/* next value run */
676 } /* several transforms */
677 }/* next parameters */
679 }/* more complex transform */
680 }/* read transfroms */
682 }/* icvTestSeqReadElemOne */
684 static CvTestSeqElem* icvTestSeqReadElemAll(CvTestSeq_* pTS, CvFileStorage* fs, const char* name)
686 CvTestSeqElem* pElem = NULL;
688 if(name == NULL) return NULL;
689 node = cvGetFileNodeByName( fs, NULL, name );
692 printf("WARNING!!! - Video %s does not exist!\n", name);
696 printf("Read node %s\n",name);
698 if(CV_NODE_IS_SEQ(node->tag))
699 {/* read all element in sequence */
701 CvSeq* seq = node->data.seq;
702 CvTestSeqElem* pElemLast = NULL;
703 for(i=0;i<seq->total;++i)
705 CvFileNode* next_node = (CvFileNode*)cvGetSeqElem( seq, i );
706 CvTestSeqElem* pElemNew = icvTestSeqReadElemOne(pTS, fs, next_node );
707 CvFileNode* pDurNode = cvGetFileNodeByName( fs, next_node,"Dur");
708 if(pElemNew == NULL )
710 printf("WARNING in parsing %s record!!! Can not read array element\n", name);
713 if(pElem && pElemLast)
715 pElemLast->next = pElemNew;
718 pElemNew->FrameBegin = pElemLast->FrameBegin + pElemLast->FrameNum;
727 for(pElemLast=pElemNew;pElemLast && pElemLast->next;pElemLast= pElemLast->next);
729 }/* read all element in sequence */
731 {/* read one element */
732 pElem = icvTestSeqReadElemOne(pTS, fs, node );
735 }/* icvTestSeqReadElemAll */
737 static void icvTestSeqReleaseAll(CvTestSeqElem** ppElemList)
739 CvTestSeqElem* p = ppElemList[0];
742 CvTestSeqElem* pd = p;
745 //cvReleaseCapture(&p->pAVI);
747 if(p->pImg)cvReleaseImage(&p->pImg);
748 if(p->pImgMask)cvReleaseImage(&p->pImgMask);
749 if(p->pPos)cvFree(&p->pPos);
750 if(p->pTrans)cvFree(&p->pTrans);
751 if(p->pSize)cvFree(&p->pSize);
755 ppElemList[0] = NULL;
756 }/* icvTestSeqReleaseAll */
758 CvTestSeq* cvCreateTestSeq(char* pConfigfile, char** videos, int numvideo, float Scale, int noise_type, double noise_ampl)
760 int size = sizeof(CvTestSeq_);
761 CvTestSeq_* pTS = (CvTestSeq_*)cvAlloc(size);
762 CvFileStorage* fs = cvOpenFileStorage( pConfigfile, NULL, CV_STORAGE_READ);
765 if(pTS == NULL || fs == NULL) return NULL;
768 pTS->pFileStorage = fs;
769 pTS->noise_ampl = noise_ampl;
770 pTS->noise_type = noise_type;
774 /* read all videos */
775 for(i=0;i<numvideo;++i)
777 CvTestSeqElem* pElemNew = icvTestSeqReadElemAll(pTS, fs, videos[i]);
778 if(pTS->pElemList==NULL)pTS->pElemList = pElemNew;
781 CvTestSeqElem* p = NULL;
782 for(p=pTS->pElemList;p->next;p=p->next);
785 }/* read all videos */
787 {/* Calculate elements and image size and video length */
788 CvTestSeqElem* p = pTS->pElemList;
790 CvSize MaxSize = {0,0};
792 for(p = pTS->pElemList;p;p=p->next,num++)
794 int FN = p->FrameBegin+p->FrameNum;
798 S.width = p->pImg->width;
799 S.height = p->pImg->height;
802 if(MaxSize.width < S.width) MaxSize.width = S.width;
803 if(MaxSize.height < S.height) MaxSize.height = S.height;
804 if(MaxFN < FN)MaxFN = FN;
807 if(MaxSize.width == 0)MaxSize.width = 320;
808 if(MaxSize.height == 0)MaxSize.height = 240;
809 MaxSize.width = cvRound(Scale*MaxSize.width);
810 MaxSize.height = cvRound(Scale*MaxSize.height);
811 pTS->pImg = cvCreateImage(MaxSize,IPL_DEPTH_8U,3);
812 pTS->pImgMask = cvCreateImage(MaxSize,IPL_DEPTH_8U,1);
813 pTS->FrameNum = MaxFN;
814 for(p = pTS->pElemList;p;p=p->next)
816 if(p->FrameNum<=0)p->FrameNum=MaxFN;
818 }/* Calculate elements and image size */
820 return (CvTestSeq*)pTS;
821 }/* cvCreateTestSeq */
823 void cvReleaseTestSeq(CvTestSeq** ppTestSeq)
825 CvTestSeq_* pTS = (CvTestSeq_*)ppTestSeq[0];
827 icvTestSeqReleaseAll(&pTS->pElemList);
828 if(pTS->pImg) cvReleaseImage(&pTS->pImg);
829 if(pTS->pImgMask) cvReleaseImage(&pTS->pImgMask);
830 if(pTS->pFileStorage)cvReleaseFileStorage(&pTS->pFileStorage);
833 }/* cvReleaseTestSeq */
835 void cvTestSeqSetFrame(CvTestSeq* pTestSeq, int n)
837 CvTestSeq_* pTS = (CvTestSeq_*)pTestSeq;
841 IplImage* cvTestSeqQueryFrame(CvTestSeq* pTestSeq)
843 CvTestSeq_* pTS = (CvTestSeq_*)pTestSeq;
844 CvTestSeqElem* p = pTS->pElemList;
845 IplImage* pImg = pTS->pImg;
846 IplImage* pImgAdd = cvCloneImage(pTS->pImg);
847 IplImage* pImgAddG = cvCreateImage(cvSize(pImgAdd->width,pImgAdd->height),IPL_DEPTH_8U,1);
848 IplImage* pImgMask = pTS->pImgMask;
849 IplImage* pImgMaskAdd = cvCloneImage(pTS->pImgMask);
850 CvMat* pT = cvCreateMat(2,3,CV_32F);
852 if(pTS->CurFrame >= pTS->FrameNum) return NULL;
855 for(p=pTS->pElemList;p;p=p->next)
857 int DirectCopy = FALSE;
858 int frame = pTS->CurFrame - p->FrameBegin;
859 //float t = p->FrameNum>1?((float)frame/(p->FrameNum-1)):0;
860 CvTSTrans* pTrans = p->pTrans + frame%p->TransNum;
864 if( p->FrameNum > 0 && (frame < 0 || frame >= p->FrameNum) )
865 { /* current frame is out of range */
866 //if(p->pAVI)cvReleaseCapture(&p->pAVI);
875 if(p->noise_type == CV_NOISE_NONE)
878 icvTestSeqQureyFrameElem(p, frame);
879 if(p->pImg == NULL) continue;
881 #if 1 /* transform using T filed in Trans */
882 {/* calc transform matrix */
883 float W = (float)(pImgAdd->width-1);
884 float H = (float)(pImgAdd->height-1);
885 float W0 = (float)(p->pImg->width-1);
886 float H0 = (float)(p->pImg->height-1);
888 {/* calc invert matrxi */
889 CvMat mat = cvMat(2,3,CV_32F, pTrans->T);
896 CV_MAT_ELEM(pT[0], float, 0, 2) =
897 CV_MAT_ELEM(pT[0], float, 0, 0)*(W0/2-pTrans->T[2])+
898 CV_MAT_ELEM(pT[0], float, 0, 1)*(H0/2-pTrans->T[5]);
899 CV_MAT_ELEM(pT[0], float, 1, 2) =
900 CV_MAT_ELEM(pT[0], float, 1, 0)*(W0/2-pTrans->T[2])+
901 CV_MAT_ELEM(pT[0], float, 1, 1)*(H0/2-pTrans->T[5]);
903 CV_MAT_ELEM(pT[0], float, 0, 0) *= W0/W;
904 CV_MAT_ELEM(pT[0], float, 0, 1) *= H0/H;
905 CV_MAT_ELEM(pT[0], float, 1, 0) *= W0/W;
906 CV_MAT_ELEM(pT[0], float, 1, 1) *= H0/H;
907 }/* calc transform matrix */
909 {/* calc transform matrix */
910 float SX = (float)(p->pImg->width-1)/((pImgAdd->width-1)*pTrans->Scale.x);
911 float SY = (float)(p->pImg->height-1)/((pImgAdd->height-1)*pTrans->Scale.y);
912 float DX = pTrans->Shift.x;
913 float DY = pTrans->Shift.y;;
915 ((float*)(pT->data.ptr+pT->step*0))[0]=SX;
916 ((float*)(pT->data.ptr+pT->step*1))[1]=SY;
917 ((float*)(pT->data.ptr+pT->step*0))[2]=SX*(pImgAdd->width-1)*(0.5f-DX);
918 ((float*)(pT->data.ptr+pT->step*1))[2]=SY*(pImgAdd->height-1)*(0.5f-DY);
919 }/* calc transform matrix */
923 {/* check for direct copy */
925 if( fabs(CV_MAT_ELEM(pT[0],float,0,0)-1) > 0.00001) DirectCopy = FALSE;
926 if( fabs(CV_MAT_ELEM(pT[0],float,1,0)) > 0.00001) DirectCopy = FALSE;
927 if( fabs(CV_MAT_ELEM(pT[0],float,0,1)) > 0.00001) DirectCopy = FALSE;
928 if( fabs(CV_MAT_ELEM(pT[0],float,0,1)) > 0.00001) DirectCopy = FALSE;
929 if( fabs(CV_MAT_ELEM(pT[0],float,0,2)-(pImg->width-1)*0.5) > 0.5) DirectCopy = FALSE;
930 if( fabs(CV_MAT_ELEM(pT[0],float,1,2)-(pImg->height-1)*0.5) > 0.5) DirectCopy = FALSE;
933 /* extract image and mask */
934 if(p->pImg->nChannels == 1)
938 cvCvtColor( p->pImg,pImgAdd,CV_GRAY2BGR);
942 cvGetQuadrangleSubPix( p->pImg, pImgAddG, pT);
943 cvCvtColor( pImgAddG,pImgAdd,CV_GRAY2BGR);
946 if(p->pImg->nChannels == 3)
949 cvCopyImage(p->pImg, pImgAdd);
951 cvGetQuadrangleSubPix( p->pImg, pImgAdd, pT);
957 cvCopyImage(p->pImgMask, pImgMaskAdd);
959 cvGetQuadrangleSubPix( p->pImgMask, pImgMaskAdd, pT);
960 cvThreshold(pImgMaskAdd,pImgMaskAdd,128,255,CV_THRESH_BINARY);
963 if(pTrans->C != 1 || pTrans->I != 0)
964 {/* intencity transformation */
965 cvScale(pImgAdd, pImgAdd, pTrans->C,pTrans->I);
966 }/* intencity transformation */
970 IplImage* pImgN = cvCloneImage(pImgAdd);
971 cvRandSetRange( &p->rnd_state, pTrans->GN, 0, -1 );
972 cvRand(&p->rnd_state, pImgN);
973 cvAdd(pImgN,pImgAdd,pImgAdd);
974 cvReleaseImage(&pImgN);
978 {/* update only mask */
979 cvOr(pImgMaskAdd, pImgMask, pImgMask);
982 { /* add image and mask to exist main image and mask */
984 {/* if image is background */
985 cvCopy( pImgAdd, pImg, NULL);
988 {/* if image is foreground */
989 cvCopy( pImgAdd, pImg, pImgMaskAdd);
991 cvOr(pImgMaskAdd, pImgMask, pImgMask);
996 {/* process noise video */
998 if( p->noise_type == CV_NOISE_GAUSSIAN ||
999 p->noise_type == CV_NOISE_UNIFORM)
1000 {/* gaussan and uniform additive noise */
1001 cvAddNoise(pImg,p->noise_type,pTrans->NoiseAmp * pTrans->C, &p->rnd_state);
1002 }/* gaussan and uniform additive noise */
1003 if( p->noise_type == CV_NOISE_SPECKLE)
1004 { /* speckle - multiplicative noise */
1005 if(pTrans->I != 0)cvSubS(pImg,cvScalar(pTrans->I,pTrans->I,pTrans->I),pImg);
1006 cvAddNoise(pImg,p->noise_type,pTrans->NoiseAmp, &p->rnd_state);
1007 if(pTrans->I != 0)cvAddS(pImg,cvScalar(pTrans->I,pTrans->I,pTrans->I),pImg);
1008 }/* speckle - multiplicative noise */
1009 if( p->noise_type == CV_NOISE_SALT_AND_PEPPER)
1010 { /* salt and pepper */
1011 cvAddNoise(pImg,p->noise_type,pTrans->NoiseAmp, &p->rnd_state);
1012 }/* speckle - multiplicative noise */
1013 }/* process noise video */
1018 if(pTS->noise_type != CV_NOISE_NONE)
1020 cvAddNoise(pImg,pTS->noise_type,pTS->noise_ampl);
1022 if(pTS->IVar_DI != 0)
1023 {/* change intensity */
1024 float I = MIN(pTS->IVar_CurI,pTS->IVar_MaxI);
1025 I = MAX(I,pTS->IVar_MinI);
1026 cvScale(pImg,pImg,1,I);
1028 if(pTS->IVar_CurI >= pTS->IVar_MaxI)
1029 pTS->IVar_CurDI = (float)-fabs(pTS->IVar_DI);
1030 if(pTS->IVar_CurI <= pTS->IVar_MinI)
1031 pTS->IVar_CurDI = (float)+fabs(pTS->IVar_DI);
1032 pTS->IVar_CurI += pTS->IVar_CurDI;
1038 cvReleaseImage(&pImgAdd);
1039 cvReleaseImage(&pImgAddG);
1040 cvReleaseImage(&pImgMaskAdd);
1043 }/*cvTestSeqQueryFrame*/
1045 IplImage* cvTestSeqGetFGMask(CvTestSeq* pTestSeq)
1047 return ((CvTestSeq_*)pTestSeq)->pImgMask;
1049 IplImage* cvTestSeqGetImage(CvTestSeq* pTestSeq)
1051 return ((CvTestSeq_*)pTestSeq)->pImg;
1054 int cvTestSeqGetObjectNum(CvTestSeq* pTestSeq)
1056 //return ((CvTestSeq_*)pTestSeq)->ListNum;
1057 return ((CvTestSeq_*)pTestSeq)->ObjNum;
1060 int cvTestSeqGetObjectPos(CvTestSeq* pTestSeq, int ObjIndex, CvPoint2D32f* pPos)
1062 CvTestSeq_* pTS = (CvTestSeq_*)pTestSeq;
1063 CvTestSeqElem* p = pTS->pElemList;
1064 if(pTS->CurFrame > pTS->FrameNum) return 0;
1065 for(p=pTS->pElemList;p;p=p->next)
1067 int frame = pTS->CurFrame - p->FrameBegin - 1;
1068 if(ObjIndex==p->ObjID && frame >= 0 && frame < p->FrameNum) break;
1070 if(p && p->pPos && p->PosNum>0)
1074 int frame = pTS->CurFrame - p->FrameBegin - 1;
1075 if(frame < 0 || frame >= p->FrameNum) return 0;
1076 t = (p->FrameNum>1)?((float)frame / (p->FrameNum-1)):0;
1077 pTrans = p->pTrans + frame%p->TransNum;
1078 pPos[0] = p->pPos[frame%p->PosNum];
1079 #if 1 /* transform using T filed in Trans */
1081 float x = pPos->x * (p->pImg?(p->pImg->width-1):1);
1082 float y = pPos->y * (p->pImg?(p->pImg->height-1):1);
1084 pPos->x = pTrans->T[0]*x+pTrans->T[1]*y+pTrans->T[2];
1085 pPos->y = pTrans->T[3]*x+pTrans->T[4]*y+pTrans->T[5];
1089 pPos->x /= p->pImg->width-1;
1090 pPos->y /= p->pImg->height-1;
1097 pPos->x = pPos->x * pTrans->Scale.x + pTrans->Shift.x;
1098 pPos->y = pPos->y * pTrans->Scale.y + pTrans->Shift.y;
1100 pPos->x *= pTS->pImg->width-1;
1101 pPos->y *= pTS->pImg->height-1;
1105 }/* cvTestSeqGetObjectPos */
1107 int cvTestSeqGetObjectSize(CvTestSeq* pTestSeq, int ObjIndex, CvPoint2D32f* pSize)
1109 CvTestSeq_* pTS = (CvTestSeq_*)pTestSeq;
1110 CvTestSeqElem* p = pTS->pElemList;
1111 if(pTS->CurFrame > pTS->FrameNum) return 0;
1112 for(p=pTS->pElemList;p;p=p->next)
1114 int frame = pTS->CurFrame - p->FrameBegin - 1;
1115 if(ObjIndex==p->ObjID && frame >= 0 && frame < p->FrameNum) break;
1117 if(p && p->pSize && p->SizeNum>0)
1121 int frame = pTS->CurFrame - p->FrameBegin - 1;
1122 if(frame < 0 || frame >= p->FrameNum) return 0;
1123 t = (p->FrameNum>1)?((float)frame / (p->FrameNum-1)):0;
1124 pTrans = p->pTrans + frame%p->TransNum;
1125 pSize[0] = p->pSize[frame%p->SizeNum];
1126 #if 1 /* transform using T filed in Trans */
1128 float x = pSize->x * (p->pImg?(p->pImg->width-1):1);
1129 float y = pSize->y * (p->pImg?(p->pImg->height-1):1);
1133 dx1 = (float)fabs(pTrans->T[0]*x+pTrans->T[1]*y);
1134 dy1 = (float)fabs(pTrans->T[3]*x+pTrans->T[4]*y);
1136 dx2 = (float)fabs(pTrans->T[0]*x - pTrans->T[1]*y);
1137 dy2 = (float)fabs(pTrans->T[3]*x - pTrans->T[4]*y);
1139 pSize->x = MAX(dx1,dx2);
1140 pSize->y = MAX(dy1,dy2);
1144 pSize->x /= p->pImg->width-1;
1145 pSize->y /= p->pImg->height-1;
1152 pSize->x = pSize->x * pTrans->Scale.x;
1153 pSize->y = pSize->y * pTrans->Scale.y;
1155 pSize->x *= pTS->pImg->width-1;
1156 pSize->y *= pTS->pImg->height-1;
1160 }/* cvTestSeqGetObjectSize */
1162 /* add noise to finile image */
1163 void cvTestSeqAddNoise(CvTestSeq* pTestSeq, int noise_type, double noise_ampl)
1165 CvTestSeq_* pTS = (CvTestSeq_*)pTestSeq;
1166 pTS->noise_type = noise_type;
1167 pTS->noise_ampl = noise_ampl;
1169 /* add Intensity variation */
1170 void cvTestSeqAddIntensityVariation(CvTestSeq* pTestSeq, float DI_per_frame, float MinI, float MaxI)
1172 CvTestSeq_* pTS = (CvTestSeq_*)pTestSeq;
1173 pTS->IVar_CurDI = pTS->IVar_DI = DI_per_frame;
1174 pTS->IVar_MaxI = MaxI;
1175 pTS->IVar_MinI = MinI;
1178 void cvAddNoise(IplImage* pImg, int noise_type, double Ampl, CvRandState* rnd_state)
1179 {/* add noise to image */
1180 CvSize S = cvSize(pImg->width,pImg->height);
1181 IplImage* pImgAdd = cvCreateImage(S,pImg->depth,pImg->nChannels);
1182 static CvRandState local_rnd_state;
1183 static int first = 1;
1188 cvRandInit( &local_rnd_state, 1, 0, 0,CV_RAND_NORMAL);
1190 if(rnd_state == NULL)rnd_state = &local_rnd_state;
1192 if( noise_type == CV_NOISE_GAUSSIAN ||
1193 noise_type == CV_NOISE_UNIFORM)
1194 {/* gaussan and uniform additive noise */
1196 if( noise_type == CV_NOISE_GAUSSIAN)
1198 rnd_state->disttype = CV_RAND_NORMAL;
1199 cvRandSetRange( rnd_state, Ampl, 0, -1 );
1200 if(Ampl <= 0) set_zero = 1;
1202 if( noise_type == CV_NOISE_UNIFORM)
1205 1.7320508075688772935274463415059 * Ampl;
1206 rnd_state->disttype = CV_RAND_UNI;
1207 cvRandSetRange( rnd_state, -max_val, max_val, -1 );
1208 if(max_val < 1) set_zero = 1;
1212 IplImage* pImgNoise = cvCreateImage(S,IPL_DEPTH_32F,pImg->nChannels);
1213 IplImage* pImgOrg = cvCreateImage(S,IPL_DEPTH_32F,pImg->nChannels);
1214 cvConvert(pImg, pImgOrg);
1215 cvRand(rnd_state, pImgNoise);
1216 cvAdd(pImgOrg,pImgNoise,pImgOrg);
1217 cvConvert(pImgOrg,pImg);
1218 cvReleaseImage(&pImgNoise);
1219 cvReleaseImage(&pImgOrg);
1221 }/* gaussan and uniform additive noise */
1223 if( noise_type == CV_NOISE_SPECKLE)
1224 { /* speckle - multiplicative noise */
1225 IplImage* pImgSP = cvCreateImage( S,IPL_DEPTH_32F, pImg->nChannels );
1226 IplImage* pImgTemp = cvCreateImage(S,IPL_DEPTH_32F, pImg->nChannels );
1227 rnd_state->disttype = CV_RAND_NORMAL;
1228 cvRandSetRange( rnd_state, Ampl, 0, -1 );
1229 cvRand(rnd_state, pImgSP);
1230 cvConvert(pImg,pImgTemp);
1231 cvMul(pImgSP,pImgTemp,pImgSP);
1232 cvAdd(pImgTemp,pImgSP,pImgTemp);
1233 cvConvert(pImgTemp,pImg);
1234 cvReleaseImage(&pImgSP);
1235 cvReleaseImage(&pImgTemp);
1236 }/* speckle - multiplicative noise */
1238 if( noise_type == CV_NOISE_SALT_AND_PEPPER && Ampl > 0)
1239 { /* salt and pepper */
1240 IplImage* pImgMask = cvCreateImage( S,IPL_DEPTH_32F, 1 );
1241 IplImage* pImgMaskBin = cvCreateImage( S,IPL_DEPTH_8U, 1 );
1242 IplImage* pImgVal = cvCreateImage( S,IPL_DEPTH_8U, 1 );
1243 rnd_state->disttype = CV_RAND_UNI;
1245 cvRandSetRange( rnd_state, 0, 1, -1 );
1246 cvRand(rnd_state, pImgMask);
1247 cvThreshold(pImgMask,pImgMask, Ampl, 255, CV_THRESH_BINARY_INV );
1248 cvConvert(pImgMask,pImgMaskBin);
1250 cvRandSetRange( rnd_state, 0, 255, -1 );
1251 cvRand(rnd_state, pImgVal);
1252 cvThreshold(pImgVal,pImgVal,128, 255, CV_THRESH_BINARY );
1254 pImgAdd->nChannels>0?pImgVal:NULL,
1255 pImgAdd->nChannels>1?pImgVal:NULL,
1256 pImgAdd->nChannels>2?pImgVal:NULL,
1257 pImgAdd->nChannels>3?pImgVal:NULL,
1259 cvCopy(pImgAdd, pImg, pImgMaskBin);
1260 cvReleaseImage(&pImgMask);
1261 cvReleaseImage(&pImgMaskBin);
1262 cvReleaseImage(&pImgVal);
1263 }/* speckle - multiplicative noise */
1264 cvReleaseImage(&pImgAdd);