Image-Seek
view release on metacpan or search on metacpan
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
******************************************************************************/
/* STL Includes */
#include <map>
#include <queue>
#include <list>
#include <fstream>
#include <iostream>
// NOTE: when running build-ext.sh (auto swig wrappers) this namespace line has to be commented
using namespace std;
/* imgSeek includes */
#include "haar.h"
/* Database */
#include "imgdb.h"
/* C Includes */
#include <math.h>
#include <stdio.h>
#include "EXTERN.h"
#include "perl.h"
void removeID(long int id) {
if (!sigs.count(id)) {
return;
}
delete sigs[id];
sigs.erase(id);
for (int c = 0;c<3;c++)
for (int pn=0;pn<2;pn++)
for (int i = 0;i<16384;i++)
imgbuckets[c][pn][i].remove(id);
}
void cleardb() {
for (sigIterator it = sigs.begin(); it != sigs.end(); it++) {
free((*it).second->sig1);
free((*it).second->sig2);
free((*it).second->sig3);
free((*it).second->avgl);
delete (*it).second;
}
sigs.clear();
for (int c = 0;c<3;c++) for (int pn=0;pn<2;pn++)
for (int i = 0;i<16384;i++) {
imgbuckets[c][pn][i].clear();
}
}
int addImage(const long int id, unsigned char* red, unsigned char* green, unsigned char* blue) {
/* id is a unique image identifier
filename is the image location
thname is the thumbnail location for this image
doThumb should be set to 1 if you want to save the thumbnail on thname
Images with a dimension smaller than ignDim are ignored
*/
double* avgl = (double*)safesysmalloc(3*sizeof(double));
int* sig1;
int* sig2;
int* sig3;
double* cdata1, * cdata2, * cdata3;
int i;
New(200, cdata1, 16384, double);
New(200, cdata2, 16384, double);
New(200, cdata3, 16384, double);
New(200, sig1, 40, int);
New(200, sig2, 40, int);
New(200, sig3, 40, int);
sigStruct* nsig = new sigStruct();
nsig->sig1 = sig1;
nsig->sig2 = sig2;
nsig->sig3 = sig3;
nsig->avgl = avgl;
nsig->id = id;
transformChar(red, green, blue, cdata1,cdata2,cdata3);
sigs[id] = nsig;
calcHaar(cdata1,cdata2,cdata3,sig1,sig2,sig3,avgl);
for (i = 0;i<40;i++) { // populate buckets
if (sig1[i]>0) imgbuckets[0][0][sig1[i]].push_back(id);
if (sig1[i]<0) imgbuckets[0][1][-sig1[i]].push_back(id);
if (sig2[i]>0) imgbuckets[1][0][sig2[i]].push_back(id);
if (sig2[i]<0) imgbuckets[1][1][-sig2[i]].push_back(id);
if (sig3[i]>0) imgbuckets[2][0][sig3[i]].push_back(id);
if (sig3[i]<0) imgbuckets[2][1][-sig3[i]].push_back(id);
}
free(cdata1);
free(cdata2);
free(cdata3);
return 1;
}
/* Data:
buckets[3][2][16835]
sigs (hash)
*/
int loaddb(char* filename) {
std::ifstream f(filename, ios::binary);
if (!f.is_open()) return 0;
int sz,coef,c,k;
long int id;
// read buckets
for ( c = 0;c<3;c++) for (int pn=0;pn<2;pn++)
for (int i = 0;i<16384;i++) {
f.read ((char*)&(sz), sizeof(int) );
for ( k = 0;k<sz;k++) {
f.read ((char*)&(id), sizeof(long int) );
imgbuckets[c][pn][i].push_back(id);
}
}
// read sigs
f.read ((char*)&(sz), sizeof(int) );
for ( k = 0;k<sz;k++) {
f.read ((char*)&(id), sizeof(long int) );
sigs[id] = new sigStruct();
sigs[id]->id = id;
sigs[id]->sig1 = (int*)(safesysmalloc(40*sizeof(int)));
sigs[id]->sig2 = (int*)(safesysmalloc(40*sizeof(int)));
sigs[id]->sig3 = (int*)(safesysmalloc(40*sizeof(int)));
sigs[id]->avgl = (double*)safesysmalloc(3*sizeof(double));
// sig
for ( c = 0;c<40;c++) {
f.read ((char*)&(coef), sizeof( int) );
sigs[id]->sig1[c] = coef;
f.read ((char*)&(coef), sizeof( int) );
sigs[id]->sig2[c] = coef;
f.read ((char*)&(coef), sizeof( int) );
sigs[id]->sig3[c] = coef;
}
// avgl
for ( c = 0;c<3;c++) {
f.read ((char*)&(sigs[id]->avgl[c]), sizeof( double) );
}
}
f.close();
return 1;
}
int savedb(char* filename) {
/*
Serialization order:
for each color {0,1,2}:
for {positive,negative}:
for each 128x128 coefficient {0-16384}:
[int] bucket size (size of list of ids)
for each id:
( run in 0.442 second using v1.01-cache-2.11-cpan-39bf76dae61 )