📄 recoparms.c
字号:
/***
** libface - Library of face recognition and supporting algorithms
Copyright (c) 2003 Stefan Farthofer
This file is part of libface, which is
free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For further information seek us at http://sourceforge.net/projects/openbio/
** or write an email to dimitri.pissarenko@gmx.net or farthofer@chello.at.
***/
#include <memory.h>
#include <malloc.h>
#include <stdio.h>
#include <IL/IL.h>
#include "frbase.h"
#include "fr.h"
#include "recoalgo.h"
void frutilFreeTrainedDataArray(FRrecognitionParameters* gParms, FRtrainedData* tData, unsigned int nr);
/* recognition parameter serialize */
int frRecoParamsCreate(FRrecognitionParameters** gParms) {
*gParms = (FRrecognitionParameters*)malloc(sizeof(FRrecognitionParameters));
if (*gParms == NULL) return FR_ERR_NOMEM;
memset(*gParms, 0, sizeof(FRrecognitionParameters));
return FR_OK;
}
void frRecoParamsFree(FRrecognitionParameters** gParms) {
/* first delete all trainedData sets */
frutilFreeTrainedDataArray(*gParms, (*gParms)->algorithms, (*gParms)->nrAlgorithms);
free(*gParms);
*gParms = NULL;
}
size_t frRecoParamsGetSize(FRrecognitionParameters* gParms) {
size_t sz=0;
unsigned int i;
FRtrainedData* tData;
FRrecoAlgo* algo;
/* calculate children size */
for (i=0; i<gParms->nrAlgorithms; i++) {
sz = sz + sizeof(FRtrainedData) - sizeof(void*); /* general structure size minus data pointer */
/* now add alog specific size */
tData = gParms->algorithms+i;
algo = frGetRecoAlgoById(tData->algorithmType);
sz = sz + algo->getParametersSize(gParms, tData->data);
}
/* recognitionParameter fields minux algorithms pointer */
sz = sz + sizeof(FRrecognitionParameters) - sizeof(FRtrainedData*);
return sz;
}
int frRecoParamsSerialize(BYTE** mem, size_t maxsz, FRrecognitionParameters** gParms, BYTE direction) {
BYTE* begin = *mem;
unsigned int i;
int ret = FR_OK;
FRtrainedData* tData;
FRrecoAlgo* algo;
/* sanity check */
if (direction == FR_OUT && maxsz < frRecoParamsGetSize(*gParms))
return FR_ERR_ALLOCMORE;
/* if direction is IN, we have to allocate memory */
if (direction == FR_IN) {
*gParms = (FRrecognitionParameters*)malloc(sizeof(FRrecognitionParameters));
if (*gParms == NULL) return FR_ERR_NOMEM;
}
/* write/read fields */
frCopyMem(mem, &(*gParms)->width, sizeof((*gParms)->width), direction);
frCopyMem(mem, &(*gParms)->height, sizeof((*gParms)->height), direction);
frCopyMem(mem, &(*gParms)->nextId, sizeof((*gParms)->nextId), direction);
frCopyMem(mem, &(*gParms)->faceFinder, sizeof((*gParms)->faceFinder), direction);
frCopyMem(mem, &(*gParms)->nrAlgorithms, sizeof((*gParms)->nrAlgorithms), direction);
/* if direction is IN, allocate memroy for algorithm entries */
if (direction == FR_IN) {
(*gParms)->algorithms = (FRtrainedData*)malloc(sizeof(FRtrainedData)*(*gParms)->nrAlgorithms);
if ((*gParms)->algorithms == NULL) {
free(*gParms);
return FR_ERR_NOMEM;
}
}
/* de/serialize trained data entries */
for (i=0; i < (*gParms)->nrAlgorithms && ret == FR_OK; i++) {
tData = (*gParms)->algorithms+i;
frCopyMem(mem, &tData->id, sizeof(tData->id), direction);
frCopyMem(mem, &tData->algorithmType, sizeof(tData->algorithmType), direction);
/* write custom data */
algo = frGetRecoAlgoById(tData->algorithmType);
ret = algo->serializeParameters(*gParms, &tData->data, mem, maxsz-(*mem-begin), direction);
}
if (ret != FR_OK && direction == FR_IN) { /* free all previous allocations */
frutilFreeTrainedDataArray(*gParms, (*gParms)->algorithms, i-1);
free(*gParms);
}
return ret;
}
int frRecoParamsSaveFile(FILE* fileHandle, FRrecognitionParameters* gParms) {
int err = FR_OK;
size_t sz;
BYTE* data, * temp;
/* get serialized data */
sz = frRecoParamsGetSize(gParms);
temp = data = (BYTE*)malloc(sz);
if (data == NULL) return FR_ERR_NOMEM;
err = frRecoParamsSerialize(&temp, sz, &gParms, FR_OUT);
/* write size and then data */
if (err == FR_OK && !fwrite(&sz, sizeof(sz), 1, fileHandle)) err = FR_ERR_FILE;
if (err == FR_OK && !fwrite(data, sz, 1, fileHandle)) err = FR_ERR_FILE;
free(data);
return err;
}
int frRecoParamsLoadFile(FILE* fileHandle, FRrecognitionParameters** gParms) {
int err = FR_OK;
size_t sz;
BYTE* data, * temp;
/* read size */
if (!fread(&sz, sizeof(sz), 1, fileHandle)) return FR_ERR_FILE;
/* allocate memory */
temp = data = (BYTE*) malloc(sz);
if (data == NULL) return FR_ERR_NOMEM;
/* read serialized data */
if (!fread(data, sz, 1, fileHandle)) {
free(data);
return FR_ERR_FILE;
}
/* deserialize */
err = frRecoParamsSerialize(&temp, sz, gParms, FR_IN);
free(data);
return err;
}
/* recognition parameter setup */
int frRecoParamsAddAlogrithm(FRrecognitionParameters* gParms, int type, FRalgoParam* algoParms, unsigned int nrAlgoParms, FRimage* images, unsigned int nrImages) {
unsigned int i;
int err=FR_OK;
FRtrainedData* newdat;
FRrecoAlgo* algo, * newalgo;
/* check if global parms have been set, if not, assume width and height of first picture */
if (gParms->width == 0 || gParms->height == 0) {
if (nrImages == 0) return FR_ERR_INVALID_PARMS;
gParms->height = images->height;
gParms->width = images->width;
}
/* check if requested algo exists */
newalgo = frGetRecoAlgoById(type);
if (newalgo == NULL) return FR_ERR_NOALGO;
/* allocate new FRtrainedData array */
newdat = (FRtrainedData*) malloc(sizeof(FRtrainedData)*(gParms->nrAlgorithms+1));
if (newdat == NULL) return FR_ERR_NOMEM;
/* copy old parameters */
for (i=0; err == FR_OK && i < gParms->nrAlgorithms; i++) {
newdat[i].algorithmType = gParms->algorithms[i].algorithmType;
newdat[i].id = gParms->algorithms[i].id;
algo = frGetRecoAlgoById(gParms->algorithms[i].algorithmType);
err = algo->copyParameters(gParms, &newdat[i].data, gParms->algorithms[i].data);
}
if (err != FR_OK) { /* rollback */
frutilFreeTrainedDataArray(gParms, newdat,i-1);
return err;
}
newdat[i].algorithmType = type;
newdat[i].id = gParms->nextId++;
err = newalgo->setupAlgoInstance(gParms, algoParms, nrAlgoParms, images, nrImages, &newdat[i].data);
if (err != FR_OK) { /* rollback */
frutilFreeTrainedDataArray(gParms, newdat, i);
} else { /* link new array */
frutilFreeTrainedDataArray(gParms, gParms->algorithms, gParms->nrAlgorithms);
gParms->algorithms = newdat;
gParms->nrAlgorithms++;
}
return err;
}
int frRecoParamsRemoveAlgorithm(FRrecognitionParameters* gParms, unsigned int id) {
unsigned int i, j;
int err = FR_OK;
FRtrainedData* newdat;
FRrecoAlgo* algo;
/* check if the specified algo exists */
for (i=0; i < gParms->nrAlgorithms; i++)
if ((gParms->algorithms+i)->id == id) break;
if (i == gParms->nrAlgorithms)
return FR_ERR_NOALGO;
/* allocate memory for new struct */
newdat = (FRtrainedData*) malloc(sizeof(FRtrainedData)*(gParms->nrAlgorithms-1));
if (newdat == NULL) return FR_ERR_NOMEM;
/* fill new struct */
for (i=0, j=0; err == FR_OK && i < gParms->nrAlgorithms; i++) {
if ((gParms->algorithms+i)->id != id) {
(newdat+j)->algorithmType = (gParms->algorithms+i)->algorithmType;
(newdat+j)->id = (gParms->algorithms+i)->id;
algo = frGetRecoAlgoById((gParms->algorithms+i)->algorithmType);
err = algo->copyParameters(gParms, &(newdat+j)->data, (gParms->algorithms+i)->data);
j++;
}
}
if (err != FR_OK) {
/* free everything that has been allocated */
frutilFreeTrainedDataArray(gParms, newdat, j-1);
} else { /* else everything ok and link new FRtrainedData array */
frutilFreeTrainedDataArray(gParms, gParms->algorithms, gParms->nrAlgorithms);
gParms->algorithms = newdat;
gParms->nrAlgorithms--;
}
return err;
}
void frCopyMem(BYTE** mem, void * data, size_t sz, BYTE direction) {
if (direction == FR_IN)
memcpy(data, *mem, sz);
else
memcpy(*mem, data, sz);
*mem = *mem + sz;
}
void frutilFreeTrainedDataArray(FRrecognitionParameters* gParms, FRtrainedData* tData, unsigned int nr) {
unsigned int i = 0;
FRrecoAlgo* algo;
for (; i < nr; i++) {
algo = frGetRecoAlgoById(tData[i].algorithmType);
algo->freeParameters(gParms, &tData[i].data);
}
free(tData);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -