New clustering with profile removal
Signed-off-by: James Ketrenos <james_gitlab@ketrenos.com>
This commit is contained in:
parent
94776ca233
commit
9f375399a5
@ -14,6 +14,13 @@
|
||||
#define MAX_DISTANCE 0.354667L
|
||||
#endif
|
||||
|
||||
/* descriptors extracted from a profile face photo, used to filter out faces near a profile image
|
||||
* (which all identify as the same person) */
|
||||
long double profileDescriptors[2][128] = {
|
||||
{ -0.061601437628269196,0.11936908215284348,0.05469074845314026,-0.01107284426689148,-0.11588133871555328,-0.002019548788666725,-0.11300364136695862,-0.07167613506317139,0.1764453798532486,-0.05901609733700752,0.2385266125202179,0.012328468263149261,-0.2573902904987335,0.04025992751121521,-0.11443999409675598,0.11594478785991669,-0.17500847578048706,-0.07691430300474167,-0.12378361076116562,-0.11740189790725708,0.03630289435386658,0.06033151596784592,0.04939301311969757,0.004410859197378159,-0.20615431666374207,-0.25997376441955566,-0.08603082597255707,-0.09167610853910446,0.03498300909996033,-0.18279242515563965,0.041221488267183304,0.09842021763324738,-0.10988932847976685,0.031966306269168854,0.013916028663516045,0.008073337376117706,0.013303801417350769,-0.06880992650985718,0.17893345654010773,0.027153145521879196,-0.1894378960132599,-0.020184200257062912,0.05442515388131142,0.2977772355079651,0.20385639369487762,0.010473722591996193,0.029712140560150146,-0.10179305076599121,0.07872007042169571,-0.2609504461288452,0.004072457551956177,0.20807254314422607,0.039381805807352066,0.10894455015659332,0.0656222552061081,-0.21101640164852142,0.0015651732683181763,0.09899670630693436,-0.1148049384355545,0.03364836052060127,0.04903073608875275,-0.03714796528220177,-0.06581848114728928,-0.08302658796310425,0.1889929473400116,0.08697575330734253,-0.14220063388347626,-0.18263882398605347,0.17710572481155396,-0.1408098042011261,-0.04034702479839325,0.14808061718940735,-0.14523223042488098,-0.22445881366729736,-0.2085285633802414,0.04144661873579025,0.3701931834220886,0.140765979886055,-0.1524423211812973,0.05934419482946396,-0.09778376668691635,-0.05247225984930992,-0.07087128609418869,0.08293693512678146,-0.07502841204404831,0.01957462728023529,-0.07184667885303497,0.05862969905138016,0.19565513730049133,-0.07941281795501709,0.04070422798395157,0.26956090331077576,0.01857529580593109,-0.03987279161810875,-0.0008930861949920654,0.08536889404058456,-0.16341862082481384,0.03542519360780716,-0.10296104848384857,-0.022122247144579887,0.08253192901611328,-0.07827107608318329,0.01481425017118454,0.08741594851016998,-0.17036983370780945,0.20205597579479218,-0.010307766497135162,-0.04007430374622345,-0.0006583929061889648,-0.016108371317386627,-0.04460605978965759,-0.034171007573604584,0.24336735904216766,-0.2778766453266144,0.18527397513389587,0.1877088099718094,0.098460853099823,0.148922860622406,0.06344866007566452,0.13334715366363525,0.0003817584365606308,0.004202648997306824,-0.11708918958902359,-0.06176237016916275,-0.027644027024507523,-0.10988462716341019,-0.10410083830356598,0.0056285373866558075 },
|
||||
{ -0.05286264419555664,0.1027536615729332,0.0177864171564579,-0.007238239049911499,-0.15839841961860657,-0.013195162639021873,-0.055493343621492386,-0.011598028242588043,0.11436303704977036,-0.023542361333966255,0.23070596158504486,0.006959080696105957,-0.23580302298069,-0.04991580545902252,-0.048089612275362015,0.1130392998456955,-0.1211254671216011,-0.053501617163419724,-0.20760701596736908,-0.11128067970275879,0.015699222683906555,0.048812925815582275,-0.004359103739261627,-0.01246669515967369,-0.08746911585330963,-0.2714271545410156,-0.07527103275060654,-0.07152064889669418,0.13769567012786865,-0.1629178822040558,-0.030123017728328705,-0.006879039108753204,-0.15528543293476105,-0.07373329252004623,0.035297941416502,-0.0019944999366998672,0.00020968541502952576,-0.06796075403690338,0.15615630149841309,-0.02517728880047798,-0.15598921477794647,0.048431847244501114,0.030592434108257294,0.22424748539924622,0.18237638473510742,0.03839367255568504,-0.018516220152378082,-0.07987417280673981,0.10236746072769165,-0.23993468284606934,0.01739603653550148,0.20749998092651367,0.07386040687561035,0.09853726625442505,0.06335064768791199,-0.14400270581245422,-0.0020356550812721252,0.16046060621738434,-0.1502964049577713,0.03028072975575924,-0.013792440295219421,-0.04380643367767334,-0.05555684491991997,-0.13338367640972137,0.17439348995685577,0.08730429410934448,-0.11853333562612534,-0.14580222964286804,0.11578165739774704,-0.15631376206874847,0.0005779601633548737,0.057921670377254486,-0.11303769052028656,-0.14606109261512756,-0.24737423658370972,0.07011876255273819,0.3969222903251648,0.15113821625709534,-0.19518792629241943,0.029213692992925644,-0.11209011822938919,-0.058080971240997314,-0.01972014084458351,-0.010737363249063492,-0.12097814679145813,-0.017350099980831146,-0.057253990322351456,0.049719784408807755,0.19717393815517426,-0.06898155063390732,0.06022507697343826,0.2233758270740509,-0.0060714855790138245,0.03075665421783924,0.014615798369050026,0.029250048100948334,-0.11849372833967209,-0.06616988033056259,-0.042307183146476746,0.0033659040927886963,0.0857284739613533,-0.20014573633670807,0.034076105803251266,0.06595847010612488,-0.16573786735534668,0.12949475646018982,0.008994176983833313,0.004620999097824097,0.02356269210577011,0.0182054340839386,-0.0561535507440567,-0.035449616611003876,0.23626668751239777,-0.2073628008365631,0.3139644265174866,0.1955631524324417,0.029616639018058777,0.11366549134254456,0.07708290964365005,0.10866693407297134,-0.06293588131666183,-0.0077966004610061646,-0.057174161076545715,-0.08943509310483932,0.004156911745667458,-0.0984298512339592,-0.005768085829913616,0.0017160219140350819}
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
UNDEFINED = 0,
|
||||
CORE = 1,
|
||||
@ -128,7 +135,7 @@ FaceLink *RangeQuery(Face **ppFaces, long int faceCount, Face *pQ, double eps) {
|
||||
if (pFace->confidence <= 0.9) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (pFace->faceId == pQ->faceId) {
|
||||
continue;
|
||||
}
|
||||
@ -197,7 +204,6 @@ long int DBSCAN(Face **ppFaces, long int faceCount, double eps, int minPts) {
|
||||
FaceLink *pLink = pNeighbors;
|
||||
while (pLink) {
|
||||
Face *pQ = pLink->pFace;
|
||||
|
||||
if (pQ->faceId == pFace->faceId) {
|
||||
pLink = pLink->pNext;
|
||||
continue;
|
||||
@ -356,9 +362,27 @@ int main(int argc, char *argv[]) {
|
||||
fprintf(stderr, "Unable to read %s.\n", path);
|
||||
continue;
|
||||
}
|
||||
processed++;
|
||||
|
||||
long double profileDistance = 1.0;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
profileDistance = euclideanDistance(ppFaces[processed]->descriptor, profileDescriptors[i]);
|
||||
if (profileDistance > 0.5) {
|
||||
profileDistance = 1.0;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (profileDistance <= 0.5) {
|
||||
fprintf(stderr, "Face id %ld distance from profile face: %Lf\n",
|
||||
ppFaces[processed]->faceId, profileDistance);
|
||||
/* This entry will be skipped */
|
||||
entries--;
|
||||
} else {
|
||||
processed++;
|
||||
}
|
||||
if (processed % 1000 == 0) {
|
||||
int perc = 100 * processed / (entries * entries);
|
||||
int perc = 100 * processed / entries;
|
||||
if (perc != last) {
|
||||
fprintf(stderr, "\rRead %d%% of descriptors.", perc);
|
||||
last = perc;
|
||||
|
@ -24,9 +24,9 @@ require("./console-line.js"); /* Monkey-patch console.log with line numbers */
|
||||
const picturesPath = config.get("picturesPath").replace(/\/$/, "") + "/",
|
||||
faceData = picturesPath + "face-data/";
|
||||
|
||||
function alignFromLandmarks(image, landmarks) {
|
||||
const faceMargin = 0.3,
|
||||
width = 256, height = 256,
|
||||
function alignFromLandmarks(image, landmarks, drawLandmarks) {
|
||||
const faceMargin = 0.45,
|
||||
width = 512, height = 512,
|
||||
dY = landmarks._positions[45]._y - landmarks._positions[36]._y,
|
||||
dX = landmarks._positions[45]._x - landmarks._positions[36]._x,
|
||||
mid = {
|
||||
@ -56,18 +56,20 @@ function alignFromLandmarks(image, landmarks) {
|
||||
ctx.scale(scale, scale);
|
||||
ctx.drawImage(image, 0, 0);
|
||||
|
||||
ctx.strokeStyle = "red";
|
||||
ctx.strokeWidth = "1";
|
||||
ctx.beginPath();
|
||||
landmarks._positions.forEach((point, index) => {
|
||||
if (index == 0) {
|
||||
ctx.moveTo(point._x, point._y);
|
||||
} else {
|
||||
ctx.lineTo(point._x, point._y);
|
||||
}
|
||||
});
|
||||
ctx.stroke();
|
||||
|
||||
if (drawLandmarks) {
|
||||
ctx.strokeStyle = "red";
|
||||
ctx.strokeWidth = "1";
|
||||
ctx.beginPath();
|
||||
landmarks._positions.forEach((point, index) => {
|
||||
if (index == 0) {
|
||||
ctx.moveTo(point._x, point._y);
|
||||
} else {
|
||||
ctx.lineTo(point._x, point._y);
|
||||
}
|
||||
});
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
return canvas;
|
||||
}
|
||||
|
||||
@ -165,25 +167,42 @@ require("./db/photos").then(function(db) {
|
||||
})
|
||||
).withFaceLandmarks();
|
||||
|
||||
detectors.forEach(async (detector) => {
|
||||
const canvas = alignFromLandmarks(image, detector.landmarks);
|
||||
await detectors.forEach(async (detector, index) => {
|
||||
const canvas = alignFromLandmarks(image, detector.landmarks, false);
|
||||
fs.writeFileSync(`rotation-pre-${index}.png`, canvas.toBuffer("image/png", {
|
||||
quality: 0.95,
|
||||
chromaSubsampling: false
|
||||
}));
|
||||
const detected = await faceapi.detectSingleFace(canvas,
|
||||
new faceapi.SsdMobilenetv1Options({
|
||||
minConfidence: 0.1
|
||||
})
|
||||
).withFaceLandmarks();
|
||||
const descriptor = await faceapi.computeFaceDescriptor(canvas);
|
||||
|
||||
fs.writeFileSync("rotation.png", canvas.toBuffer("image/png", {
|
||||
console.log(`Processing face ${index}...`);
|
||||
console.log(`...pre aligned score: ${detector.detection._score}`);
|
||||
if (!detected) {
|
||||
console.log("No face found in re-scaled and aligned image");
|
||||
return;
|
||||
}
|
||||
console.log(`...post-aligned score: ${detected.detection._score}`);
|
||||
const newCanvas = alignFromLandmarks(canvas, detected.landmarks, true);
|
||||
|
||||
fs.writeFileSync(`rotation-post-${index}.png`, newCanvas.toBuffer("image/png", {
|
||||
quality: 0.95,
|
||||
chromaSubsampling: false
|
||||
}));
|
||||
|
||||
process.exit(-1);
|
||||
console.log(`Wrote rotation-${index}.png`);
|
||||
|
||||
// .withFaceDescriptors();
|
||||
const data = [];
|
||||
/* Confert from sparse object to dense array */
|
||||
for (let i = 0; i < 128; i++) {
|
||||
data.push(detector.descriptor[i]);
|
||||
data.push(descriptor[i]);
|
||||
}
|
||||
detector.descriptor = data;
|
||||
});
|
||||
|
||||
return [ file, image, detectors ];
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user