Skip to content
Browse files

add sample collection scripts

  • Loading branch information...
1 parent 0b5d6ce commit e2bcf0d2a63076bb77349adaafd898578b266079 @harthur committed Jun 2, 2012
View
2 hog-params.json
@@ -1,7 +1,7 @@
{
"cellSize": 4,
"blockSize": 2,
- "blockStride": 2,
+ "blockStride": 1,
"bins": 6,
"norm": "L2"
}
View
4 kittydar.js
@@ -36,7 +36,8 @@ exports.detectCats = function detectCats(canvas) {
x: cat.x / scale,
y: cat.y / scale,
width: cat.width / scale,
- height: cat.height / scale
+ height: cat.height / scale,
+ prob: cat.prob
}
});
@@ -47,7 +48,6 @@ exports.detectCats = function detectCats(canvas) {
function isCat(canvas) {
var fts = features.extractFeatures(canvas);
- //console.log(fts.length)
var prob = net.run(fts)[0];
return prob;
}
View
32 test.js
@@ -1,5 +1,16 @@
var assert = require("assert");
+r1 = { x: 204,
+ y: 285.59999999999997,
+ width: 183.6,
+ height: 183.6,
+ prob: 0.9812387701219626 }
+
+r2 = { x: '187', y: '71', width: '207', height: '207' }
+
+doesOverlap(r2, r1);
+
+process.exit(1);
function test(r1, r2, expected) {
var overlaps = doesOverlap(r1, r2);
@@ -42,8 +53,13 @@ r1 = {x: 0, y: 0, width: 10, height: 10};
r2 = {x: 2, y: 2, width: 1, height: 1};
test(r1, r2, false);
-test(r2, r1, true);
+test(r2, r1, false);
+
+r1 = {x: 187, y: 71, width: 207, height: 207};
+r2 = {x: 204, y: 285.599999999999997, width: 183.6, height: 183.6};
+test(r1, r2, false);
+test(r2, r1, false);
function doesOverlap(cat, rect) {
var overlapW, overlapH;
@@ -62,8 +78,16 @@ function doesOverlap(cat, rect) {
overlapH = Math.min((cat.y + cat.height) - rect.y, rect.height);
}
- if (overlapW > 0 && overlapH > 0) {
- return (overlapH * overlapW) > (cat.width * cat.height * 0.5);
+ console.log(overlapW, overlapH);
+
+ if (overlapW <= 0 || overlapH <= 0) {
+ return false;
+ }
+ var intersect = overlapW * overlapH;
+ var union = (cat.width * cat.height) + (rect.width * rect.height) - (intersect * 2);
+
+ if (intersect / union > 0.5) {
+ return true;
}
return false;
-}
+}
View
39 testing/test.js
@@ -3,6 +3,7 @@ var brain = require("brain"),
path = require("path"),
async = require("async"),
utils = require("../utils"),
+ Canvas = require("canvas"),
kittydar = require("../kittydar");
var dir = __dirname + "/TEST/";
@@ -22,15 +23,18 @@ function runTest() {
return path.extname(file) == ".jpg";
})
- images = images.slice(0, 1);
+ images = images.slice(0, 2);
async.forEach(images, function(file, done) {
file = dir + file;
fs.readFile(file + ".rect", "utf-8", function(err, text) {
if (err) throw err;
- var vals = text.split(" ");
+ var vals = text.split(" ").map(function(val) {
+ return parseInt(val)
+ })
+
var rect = {
x: vals[0],
y: vals[1],
@@ -51,13 +55,16 @@ function runTest() {
console.log("testing", file);
cats.forEach(function(cat) {
- if (doesOverlap(cat, rect)) {
+ var overlaps = doesOverlap(cat, rect);
+
+ if (overlaps) {
missed = false;
truePos++;
}
else {
falsePos++;
}
+ saveCrop(canvas, cat, overlaps);
});
if (missed) {
@@ -81,6 +88,22 @@ function runTest() {
});
}
+function saveCrop(canvas, cat, isTrue) {
+ var cropCanvas = new Canvas(cat.width, cat.height);
+ var ctx = cropCanvas.getContext('2d');
+ ctx.patternQuality = "best";
+
+ ctx.drawImage(canvas, cat.x, cat.y, cat.width, cat.height,
+ 0, 0, cat.width, cat.height);
+
+ var dir = __dirname + "/CROPS/" + (isTrue ? "/TRUE/" : "/FALSE/");
+ var file = dir + cat.x + "_" + cat.y + "_" + cat.width
+ + "_" + cat.prob.toFixed(2) + ".jpg"
+ utils.writeCanvasToFile(cropCanvas, file, function(err) {
+ if (err) console.log(err);
+ });
+}
+
function doesOverlap(cat, rect) {
var overlapW, overlapH;
@@ -98,8 +121,14 @@ function doesOverlap(cat, rect) {
overlapH = Math.min((cat.y + cat.height) - rect.y, rect.height);
}
- if (overlapW > 0 && overlapH > 0) {
- return (overlapH * overlapW) > (cat.width * cat.height * 0.5);
+ if (overlapW <= 0 || overlapH <= 0) {
+ return false;
+ }
+ var intersect = overlapW * overlapH;
+ var union = (cat.width * cat.height) + (rect.width * rect.height) - (intersect * 2);
+
+ if (intersect / union > 0.5) {
+ return true;
}
return false;
}
View
34 training/collection/flickr.rb
@@ -0,0 +1,34 @@
+require 'rubygems'
+require 'open-uri'
+require 'flickraw'
+
+FlickRaw.api_key="0cc11cffc8a238efef4dfa6dca255a44"
+FlickRaw.shared_secret="5f76a97053f99673"
+
+$count = 0
+$start = 5690
+
+$fetched = Hash.new
+
+def getPage(page)
+ list = flickr.photos.getRecent :per_page => 500, :page => page
+
+ list.each do |photo|
+ url = "http://farm#{photo.farm}.staticflickr.com/#{photo.server}/#{photo.id}_#{photo.secret}_c.jpg"
+
+ if $fetched[url] != 1
+ $fetched[url] = 1
+
+ file = "NEGS_FLICKR/#{$count + $start}.jpg"
+ open(file, 'wb') do |file|
+ file << open(url).read
+ end
+ puts "saved to #{file}"
+ $count+=1
+ end
+ end
+end
+
+100.times do |i|
+ getPage(i * 3)
+end
View
68 training/collection/makenegs.js
@@ -0,0 +1,68 @@
+var http = require("http"),
+ url = require("url"),
+ fs = require("fs"),
+ async = require("async"),
+ path = require("path"),
+ Canvas = require("canvas"),
+ _ = require("underscore"),
+ utils = require("../../utils");
+
+var dir = __dirname + "/NEGS_FLICKR/";
+var outdir = __dirname + "/NEGS_RAW_SAMPLED/";
+
+var count = 0;
+var start = 45005;
+
+var perFile = 9;
+
+fs.readdir(dir, function(err, files) {
+ if (err) throw err;
+
+ var images = files.filter(function(file) {
+ return path.extname(file) == ".jpg";
+ });
+
+ images = images.slice(1000 * 5, 1000 * 6);
+
+ images.forEach(function(image) {
+ var outfile = outdir + (start + count) + ".jpg";
+
+ try {
+ var canvas = utils.drawImgToCanvasSync(dir + image);
+ }
+ catch(e) {
+ console.log(e, dir + image);
+ }
+ var canvases = generateFromRaw(canvas);
+
+ canvases.forEach(function(canvas) {
+ count++;
+ var file = outdir + (start + count) + ".jpg";
+ utils.writeCanvasToFile(canvas, file, function() {
+ console.log("wrote to", file)
+ });
+ });
+ });
+})
+
+function generateFromRaw(canvas) {
+ var min = 48;
+ var max = Math.min(canvas.width, canvas.height);
+
+ var canvases = _.range(0, perFile).map(function() {
+ var length = Math.max(48, Math.ceil(Math.random() * max));
+
+ var x = Math.floor(Math.random() * (max - length));
+ var y = Math.floor(Math.random() * (max - length));
+
+ return cropCanvas(canvas, x, y, length, length);
+ })
+ return canvases;
+}
+
+function cropCanvas(canvas, x, y, width, height) {
+ var cropCanvas = new Canvas(width, height);
+ var context = cropCanvas.getContext("2d");
+ context.drawImage(canvas, x, y, width, height, 0, 0, width, height);
+ return cropCanvas;
+}
View
31 training/collection/makepos.js
@@ -0,0 +1,31 @@
+var fs = require("fs"),
+ path = require("path"),
+ async = require("async"),
+ cropper = require("./cropper");
+
+var dir = __dirname + "/CATS_ORIG/CAT_06/";
+var outdir = __dirname + "/POS_RAW/";
+
+var count = 0;
+var start = 8622;
+
+fs.readdir(dir, function(err, files) {
+ if (err) throw err;
+
+ console.log("file count", files.length / 2);
+
+ var images = files.filter(function(file) {
+ return path.extname(file) == ".jpg";
+ })
+
+ async.forEachSeries(images, function(file, done) {
+ count++;
+ var outfile = outdir + (start + count) + ".jpg";
+
+ cropper.makeCatFaceImg(dir + file, outfile, function() {
+ console.log("saved cat face to:", outfile);
+ setTimeout(done, 100);
+ });
+ });
+})
+
View
68 training/collection/mine-negatives.js
@@ -0,0 +1,68 @@
+var brain = require("brain"),
+ fs = require("fs"),
+ path = require("path"),
+ util = require("util"),
+ utils = require("../../utils");
+
+var trained = require("./network.json");
+
+var dir = __dirname + "/NEGS_RAW_SAMPLED/";
+var minedDir = __dirname + "/HARD_NEGS/"
+
+var start = 0;
+var count = 0;
+
+var iter = 0;
+
+fs.readdir(dir, function(err, files) {
+ if (err) throw err;
+
+ var images = file.filter(function(file) {
+ return path.extname(file) == ".jpg";
+ });
+
+ images = images.slice(9000 * iter, 9000 * (iter + 1));
+
+
+ async.map(images, function(file, done) {
+ file = dir + file;
+
+ utils.drawImgToCanvas(file, function(canvas) {
+ done(null, {canvas: canvas, file: file, isCat: isCat});
+ });
+ },
+ function(err, canvases) {
+ saveFalsePos(canvases);
+ });
+})
+
+function saveFalsePos(canvases) {
+ var data = canvases.map(function(canvas) {
+ var fts = features.extractFeatures(canvas.canvas, params);
+ return {
+ file: canvas.file
+ input: fts,
+ output: [canvas.isCat]
+ };
+ });
+
+ data = _(data).sortBy(function() {
+ return Math.random();
+ });
+
+ var network = new brain.NeuralNetwork().fromJSON(trained);
+
+ var stats = network.test(data);
+
+ console.log(stats.falsPos, "false positives");
+
+ stats.misclasses.forEach(function(misclass) {
+ if (misclass.expected == 0) {
+ var file = path.basename(misclass.file);
+ newFile = fs.createWriteStream(misclass.file);
+ oldFile = fs.createReadStream(minedDir + file);
+ util.pump(oldFile, newFile);
+ }
+ });
+}
+
View
37 training/findparams.js
@@ -36,27 +36,50 @@ function getCombos() {
return combos;
}
-var combos = [{
+var combos = [
+{
cellSize: 4,
- blockSize: 3,
- blockStride: 3,
- bins: 6,
+ blockSize: 2,
+ blockStride: 1,
+ bins: 9,
norm: "L2"
},
{
cellSize: 4,
- blockSize: 3,
+ blockSize: 2,
blockStride: 2,
+ bins: 9,
+ norm: "L2"
+},
+{
+ cellSize: 4,
+ blockSize: 2,
+ blockStride: 1,
bins: 6,
norm: "L2"
},
{
cellSize: 4,
- blockSize: 3,
+ blockSize: 2,
+ blockStride: 1,
+ bins: 7,
+ norm: "L2"
+},
+{
+ cellSize: 6,
+ blockSize: 2,
+ blockStride: 1,
+ bins: 9,
+ norm: "L2"
+},
+{
+ cellSize: 6,
+ blockSize: 2,
blockStride: 1,
bins: 6,
norm: "L2"
-}];
+}
+];
console.log("testing", combos.length, "combinations");
View
91 training/makenetwork.js
@@ -0,0 +1,91 @@
+var fs = require("fs"),
+ brain = require("brain"),
+ path = require("path"),
+ async = require("async"),
+ _ = require("underscore"),
+ utils = require("../utils"),
+ features = require("../features");
+
+trainNetwork()
+
+function trainNetwork(params) {
+ getCanvases(function(canvases) {
+ var data = canvases.map(function(canvas) {
+ var fts = features.extractFeatures(canvas.canvas, params);
+ return {
+ input: fts,
+ output: [canvas.isCat]
+ };
+ });
+
+ data = _(data).sortBy(function() {
+ return Math.random();
+ });
+
+ console.log("training with", data.length);
+
+ var opts = {
+ hiddenLayers: [40]
+ };
+ var trainOpts = {
+ errorThresh: 0.006,
+ log: true
+ };
+
+ var network = new brain.NeuralNetwork(opts);
+
+ var stats = network.train(data, trainOpts);
+
+ console.log("stats:", stats);
+ console.log("parameters:", opts);
+
+ var json = JSON.stringify(network.toJSON(), 4)
+
+ fs.writeFile('network.json', json, function (err) {
+ if (err) throw err;
+ console.log('saved network to network.json');
+ });
+ })
+}
+
+function getCanvases(callback) {
+ var posDir = __dirname + "/POSITIVES/";
+
+ fs.readdir(posDir, function(err, files) {
+ if (err) throw err;
+
+ getDir(posDir, files, 1, 8000, function(posData) {
+ var negsDir = __dirname + "/NEGATIVES/";
+ fs.readdir(negsDir, function(err, files) {
+ if (err) throw err;
+
+ getDir(negsDir, files, 0, 8000, function(negData) {
+ var data = posData.concat(negData);
+
+ callback(data);
+ })
+ })
+ })
+ });
+}
+
+function getDir(dir, files, isCat, limit, callback) {
+ var images = files.filter(function(file) {
+ return path.extname(file) == ".jpg";
+ });
+ images = images.slice(0, limit);
+
+ var data = [];
+
+ async.map(images, function(file, done) {
+ file = dir + file;
+
+ utils.drawImgToCanvas(file, function(canvas) {
+ done(null, {canvas: canvas, file: file, isCat: isCat});
+ });
+ },
+ function(err, canvases) {
+ console.log("got one directory of images")
+ callback(canvases);
+ });
+}
View
5 training/train.js
@@ -19,6 +19,8 @@ function testParams(params) {
};
});
+ console.log("training on", data.length)
+
var opts = {
hiddenLayers: [30]
};
@@ -79,7 +81,7 @@ function getCanvases(callback) {
}
function getDir(dir, files, isCat, callback) {
- var limit = 5000;
+ var limit = 4000;
var images = files.filter(function(file) {
return path.extname(file) == ".jpg";
});
@@ -95,6 +97,7 @@ function getDir(dir, files, isCat, callback) {
});
},
function(err, canvases) {
+ console.log("got one directory of images")
callback(canvases);
});
}

0 comments on commit e2bcf0d

Please sign in to comment.
Something went wrong with that request. Please try again.