📄 abs.c
字号:
/**
@file abs.c
@brief xDM Codec Engine for Adaptive Backgound Subtraction.
This file contains an implementation of the IVIDENC interface
@author Yongseok Yoo
*/
#include <time.h>
#include <xdc/std.h>
#include <stdlib.h> // for malloc and free
#include <string.h>
#include <ti/xdais/dm/ividenc.h>
#include <stdio.h>
#include "../include/ema.h" // size definition is here
#include "abs.h"
#include "blobDetection_CC.h"
#include "backgroundSubtraction.h"
/** Min number of input buffers */
#define MININBUFS 2
/** Min number of output buffers */
#define MINOUTBUFS 1
/* ialg and xdm function prototypes */
static Int ABS_TTO_numAlloc(void);
static Int ABS_TTO_alloc(const IALG_Params *algParams,
IALG_Fxns **pf, IALG_MemRec memTab[]);
static Int ABS_TTO_free(IALG_Handle handle, IALG_MemRec memTab[]);
static Int ABS_TTO_initObj(IALG_Handle handle,
const IALG_MemRec memTab[], IALG_Handle p,
const IALG_Params *params);
static XDAS_Int32 ABS_TTO_process(IVIDENC_Handle h, XDM_BufDesc *inBufs,
XDM_BufDesc *outBufs, IVIDENC_InArgs *inArgs, IVIDENC_OutArgs *outArgs);
static XDAS_Int32 ABS_TTO_control(IVIDENC_Handle handle, IVIDENC_Cmd id,
IVIDENC_DynamicParams *params, IVIDENC_Status *status);
/** Pointer to difference image*/
BYTE* absDiffImg=NULL;
/** Pointer to constancy image*/
BYTE* absConstancy;
/** Pointer to label image*/
BYTE* absLabelImg;
/** Pointer to Sharpend image*/
BYTE* absSharpImg;
/** Pointer to edge image*/
BYTE* absBMEdgeImg;
/** Pointer to temporarly image*/
BYTE* absTempImg;
/** frame counter*/
UINT absFrameID = 0;
/**
* This structure defines TI's implementation of the IVIDENC interface
* for the ABS_TTO module.
*/
IVIDENC_Fxns ABS_TTO_ABS = { /* module_vendor_interface */
{ /* begin ialg functions */
&ABS_TTO_ABS, /* module ID */
NULL, /* activate */
ABS_TTO_alloc, /* alloc */
NULL, /* control (NULL => no control ops) */
NULL, /* deactivate */
ABS_TTO_free, /* free */
ABS_TTO_initObj, /* init */
NULL, /* moved */
ABS_TTO_numAlloc /* numAlloc */
}, /* end ialg functions */
ABS_TTO_process, /* process, xdm extension to ialg */
ABS_TTO_control /* control, xdm extension to ialg */
};
/**
* Number of allocate memory for codec engine
*/
static Int ABS_TTO_numAlloc(void)
{
return (1);
}
/**
* Allocate memory for codec engine
*/
static Int ABS_TTO_alloc(const IALG_Params *algParams,
IALG_Fxns **pf, IALG_MemRec memTab[])
{
/* Request memory for my object */
memTab[0].size = sizeof(ABS_TTO_Obj);
memTab[0].alignment = 0;
memTab[0].space = IALG_EXTERNAL;
memTab[0].attrs = IALG_PERSIST;
return (1);
}
/**
* Free memory for codec engine
*/
static Int ABS_TTO_free(IALG_Handle handle, IALG_MemRec memTab[])
{
ABS_TTO_alloc(NULL, NULL, memTab);
ABS_Release();
Blob_Release();
free(absDiffImg);
return (1);
}
/**
* Initialize codec engine
*/
static Int ABS_TTO_initObj(IALG_Handle handle,
const IALG_MemRec memTab[], IALG_Handle p,
const IALG_Params *params)
{
int width, height;
int pixnum;
/* handle and parameters inherit from IALG_Handle and IALG_Params */
ABS_TTO_Handle algHandle = (ABS_TTO_Handle) handle;
IVIDENC_Params *algParams = (IVIDENC_Params *) params;
/* Check size of params to make sure we got what we were expecting */
if(algParams->size != sizeof(IVIDENC_Params)){
return (IALG_EFAIL);
}
algHandle->maxWidth = algParams->maxWidth;
algHandle->maxHeight = algParams->maxHeight;
algHandle->preset = algParams->encodingPreset;
width = algHandle->maxWidth;
height = algHandle->maxHeight;
pixnum = width*height;
// allocate memeory for Ma 20070809
ABS_Create(width, height);
Blob_Create(width, height);
absDiffImg = (BYTE*)malloc(pixnum*6);
if (absDiffImg==NULL)
return (IALG_EFAIL);
absConstancy = absDiffImg + pixnum;
absLabelImg = absConstancy + pixnum;
absSharpImg = absLabelImg + pixnum;
absBMEdgeImg = absSharpImg + pixnum;
absTempImg = absBMEdgeImg + pixnum;
return (IALG_EOK);
}
/**
* Process function of codec engine
*/
static XDAS_Int32 ABS_TTO_process(IVIDENC_Handle h, XDM_BufDesc *inBufs,
XDM_BufDesc *outBufs, IVIDENC_InArgs *inArgs, IVIDENC_OutArgs *outArgs)
{
ABS_TTO_Handle algHandle = (ABS_TTO_Handle) h;
XDAS_Int32 width = algHandle->maxWidth;
XDAS_Int32 height = algHandle->maxHeight;
//XDAS_Int32 size = width*height;
BYTE* grayImg, *diffImg;
BYTE* swap;
INT i;
INT forenum, noisenum;
EmaRect* absBlobs;
INT* absBlobNum;
INT* others;
INT updatefactor;
// validate arguments - this codec only supports "base" xDM.
if ((inArgs->size != sizeof(*inArgs)) ||
(outArgs->size != sizeof(*outArgs))) {
return (IVIDENC_EFAIL);
}
// addressing input buffers
grayImg = (BYTE*)inBufs->bufs[0];
diffImg = (BYTE*) inBufs->bufs[1];
absBlobNum = (INT*)(outBufs->bufs[0]);
absBlobs = (EmaRect*)(absBlobNum + 1);
others = (INT*)(absBlobs + EMA_MAX_NUM_BLOB);
// abs routines here
memset(others, 0, 64);
// ABS processing
if (absFrameID==0)
{
ABS_InitBackGround(grayImg);
(*absBlobNum) = 0;
}
else if (absFrameID<16) // still in initial process
{
// We need at least 16 frames for building a stable background model.
int updatefactor = 256 - absFrameID*16;
ABS_BackgroundModeling(grayImg, updatefactor);
(*absBlobNum) = 0;
}
else if (absFrameID==16)
{
ABS_SceneAnalyze(absBMEdgeImg);
smoothUp(absBMEdgeImg, absTempImg);
smoothUp(absTempImg, absBMEdgeImg);
}
else
{
// 64 = a period of updating a gradient of background model
if ( !(absFrameID & 0x0000003f))
{
ABS_SceneAnalyze(absBMEdgeImg);
smoothUp(absBMEdgeImg, absTempImg);
smoothUp(absTempImg, absBMEdgeImg);
}
// Background subtraction
updatefactor = 1;
if (absFrameID<64) updatefactor = 8;
else if (absFrameID<128) updatefactor = 5;
else if (absFrameID<256) updatefactor = 3;
ABS_ExtractForeground(grayImg, absLabelImg, absDiffImg, updatefactor); // Slowest part.
smoothByMedian(absLabelImg, absTempImg); // essential. Don't delete it.
swap = absLabelImg;
absLabelImg = absTempImg;
absTempImg = swap;
/* // post processing for difference image
smoothByMedian(absDiffImg, absTempImg); // Fast version: applied to only foreground pixels.
swap = absDiffImg;
absDiffImg = absTempImg;
absTempImg = swap;
// Background extraction end
*/
/* // additional verification
// [start]
// Option1: remove shadow
ABS_Sharpness(absDiffImg, absSharpImg);
ABS_RemoveShadow(absLabelImg, absDiffImg, absSharpImg);
// Option2: image constancy for theft detection
// This part is optional: it works for reducing false alarms in theft detection
smoothUp(absConstancy, absTempImg);
smoothUp(absTempImg, absConstancy);
ABS_ComputeConstancy(diffImg, absConstancy);
ABS_VerifyTheftByConstancy(absLabelImg, absConstancy);
// [end]
*/
// blob detection
Blob_Dilate_Fore_into_Shadow(absLabelImg);
Blob_Detection(absLabelImg, absBlobs, absBlobNum, &forenum, &noisenum);
others[0] = forenum;
others[1] = noisenum;
// watch dog
if (forenum>16000) // global change
{
ABS_InitBackGround(grayImg);
absFrameID = 0;
(*absBlobNum) = 0;
others[2] = 1; // camera tampering
}
else if (noisenum>=200) // potential camera shaking
{
// update pixels at the edge
Blob_ResetLabelImage(absLabelImg);
ABS_ExtractWithMask(grayImg, absLabelImg, absBMEdgeImg);
Blob_Dilate_Fore_into_Shadow(absLabelImg);
Blob_Detection_Again(absLabelImg, absBlobs, absBlobNum);
}
// remove shadow
if (algHandle->preset & EMA_ARG_ABS_SHADOW_REMOVAL) {
for (i=0; i<(*absBlobNum); i++)
Blob_RemoveShadow(absLabelImg, absDiffImg, &absBlobs[i]);
}
// theft left
for (i=0; i<(*absBlobNum); i++)
if (absBlobs[i].evt==EMA_THEFT)
Blob_Theft_or_LeftBag(grayImg, absLabelImg, &absBlobs[i]);
}
absFrameID ++;
// outArgs->bytesGenerated reports the total number of bytes generated
outArgs->bytesGenerated = sizeof(INT) // absBlobNum
+ *absBlobNum * (sizeof(EmaRect)+sizeof(BYTE)+sizeof(INT));
// Fill out the rest of the outArgs struct
outArgs->extendedError = 0;
outArgs->encodedFrameType = 0;
outArgs->inputFrameSkip = IVIDEO_FRAME_ENCODED;
outArgs->reconBufs.numBufs = 0;
return (IVIDENC_EOK);
}
/**
* Control function of codec engine
*/
static XDAS_Int32 ABS_TTO_control(IVIDENC_Handle handle, IVIDENC_Cmd id,
IVIDENC_DynamicParams *params, IVIDENC_Status *status)
{
XDAS_Int32 retVal;
ABS_TTO_Handle algHandle = (ABS_TTO_Handle) handle;
/* validate arguments - this codec only supports "base" xDM. */
if ((params->size != sizeof(*params)) ||
(status->size != sizeof(*status))) {
return (IVIDENC_EFAIL);
}
switch (id) {
case XDM_GETSTATUS:
status->extendedError = 0;
status->bufInfo.minNumInBufs = MININBUFS;
status->bufInfo.minNumOutBufs = MINOUTBUFS;
status->bufInfo.minInBufSize[0] =
(algHandle->maxWidth * algHandle->maxHeight);
status->bufInfo.minOutBufSize[0] =
(algHandle->maxWidth * algHandle->maxHeight);
retVal = IVIDENC_EOK;
break;
case XDM_GETBUFINFO:
status->extendedError = 0;
status->bufInfo.minNumInBufs = MININBUFS;
status->bufInfo.minNumOutBufs = MINOUTBUFS;
status->bufInfo.minInBufSize[0] =
(algHandle->maxWidth * algHandle->maxHeight);
status->bufInfo.minOutBufSize[0] =
(algHandle->maxWidth * algHandle->maxHeight);
retVal = IVIDENC_EOK;
break;
case XDM_SETPARAMS:
retVal = IVIDENC_EOK;
break; // don't need run-time params for copy codec
default:
/* unsupported cmd */
retVal = IVIDENC_EFAIL;
break;
}
return (retVal);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -