ketr.photos/scanner/scanner.c
James Ketrenos 189a355033 Added scanner updates
Signed-off-by: James Ketrenos <james_gitlab@ketrenos.com>
2020-01-05 19:54:30 -08:00

158 lines
3.6 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/types.h>
#include <string.h>
#include <math.h>
//#include <sqlite3.h>
typedef struct Face {
long double descriptor[128];
int faceId;
long double *distances;
struct Face *next;
struct Face *prev;
} Face;
Face *readFaceDescriptor(int id, char *path) {
FILE *f;
char buf[5000];
Face *pFace = (Face *)malloc(sizeof(Face));
memset(pFace, 0, sizeof(Face));
f = fopen(path, "r");
if (!f) {
free(pFace);
return NULL;
}
size_t s = fread(buf, 1, sizeof(buf), f);
fclose(f);
char *p = buf;
buf[s] = 0;
while (*p && *p != '-' && *p != '+' && (*p < '0' || *p > '9')) {
p++;
}
for (int i = 0; i < 128; i++) {
char *start = p;
while (*p && *p != ',' && *p != ']' && *p != ' ' && *p != '\n') {
p++;
}
if (!*p) {
break;
}
*p++ = 0;
sscanf(start, "%Lf", &pFace->descriptor[i]);
}
pFace->faceId = id;
pFace->next = pFace->prev = NULL;
return pFace;
}
long double euclideanDistance(long double *a, long double *b) {
long double sum = 0.0;
for (int i = 0; i < 128; i++) {
long double delta = a[i] - b[i];
sum += delta * delta;
}
return sqrtl(sum);
}
int main(int argc, char *argv[]) {
int i;
Face *pChain = NULL;
for (i = 0; i < 100; i++) {
char buf[1028];
sprintf(buf, "%s/face-data/%d", argv[1], i);
DIR *faceDir = opendir(buf);
if (!faceDir) {
printf("Can not open %s\n", buf);
continue;
}
struct dirent *ent;
while ((ent = readdir(faceDir)) != NULL) {
if (strstr(ent->d_name, ".json") == NULL) {
continue;
}
int id = 0;
char *p = ent->d_name;
while (*p && *p != '-') {
id *= 10;
id += *p - '0';
p++;
}
char path[1028*2];
sprintf(path, "%s/%s", buf, ent->d_name);
Face *pFace = readFaceDescriptor(id, path);
if (!pFace) {
continue;
}
if (pChain) {
pFace->next = pChain;
}
pChain = pFace;
}
closedir(faceDir);
}
Face *pLink = pChain;
int len = 0;
while (pLink) {
Face *tmp = pLink;
len++;
pLink = pLink->next;
}
printf("DELETE FROM facedistances;\n");
printf("BEGIN TRANSACTION;\n");
/* Allocate storage for all distances */
pLink = pChain;
while (pLink) {
pLink->distances = (long double *)malloc(sizeof(long double) * len);
pLink = pLink->next;
}
pLink = pChain;
int sourceIndex = 0;
while (pLink) {
int targetIndex = 0;
Face *pTarget = pChain;
while (pTarget) {
if (targetIndex == sourceIndex) {
pLink->distances[targetIndex] = 0.0;
pTarget->distances[sourceIndex] = 0.0;
} else {
if (pLink->distances[targetIndex] == 0.0) {
pLink->distances[targetIndex] =
pTarget->distances[sourceIndex] = euclideanDistance(pLink->descriptor, pTarget->descriptor);
printf("INSERT INTO facedistances (face1Id,face2Id,distance) VALUES (%d,%d,%Lf);\n",
((pLink->faceId < pTarget->faceId) ? pLink->faceId : pTarget->faceId),
((pLink->faceId < pTarget->faceId) ? pTarget->faceId : pLink->faceId),
pLink->distances[targetIndex]);
}
}
pTarget = pTarget->next;
targetIndex++;
}
pLink = pLink->next;
sourceIndex++;
}
printf("COMMIT;\n");
/*
sqlite3 *db;
sqlite3_stmt *res;
int rc = sqlite3_open("db/photos.db", &db);
if (rc != SQLITE_OK) {
fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
return 1;
}
sqlite3_close(db);
*/
return 0;
}