⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 recoparms.c

📁 基于主成份分析(PCA)的人脸特征识别核心源程序。
💻 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 + -