Browse files

add sample images to demo, update readme

  • Loading branch information...
1 parent 177289d commit 79acd48a7d38b663832ac099b2397aa526732fb8 @harthur committed Jun 13, 2012
View
22 README.md
@@ -1,8 +1,9 @@
# Kittydar
-Kittydar is short for kitty radar. Kittydar takes an image or a canvas and tells you the locations of all the cats in the image:
+
+Kittydar is short for kitty radar. Kittydar takes an image (canvas) and tells you the locations of all the cats in the image:
```javascript
-var cats = kittydar.detectCats(image);
+var cats = kittydar.detectCats(canvas);
console.log("there are", cats.length, "cats in this photo");
@@ -19,25 +20,28 @@ For node:
```bash
npm install kittydar
```
+
Or grab the [browser file](http://github.com/harthur/kittydar/downloads)
# Specifics
-Kittydar takes either a fully-loaded `Image` or a `canvas` element. In node you can use the `Image` or `Canvas` element from [node-canvas](https://github.com/LearnBoost/node-canvas).
+Kittydar takes a `canvas` element. In node you can get a `Canvas` object with [node-canvas](https://github.com/LearnBoost/node-canvas).
Kittydar will give an approximate rectangle around the cat's head. Each rectangle has an `x` and `y` for the top left corner, and a `width` and `height` of the rectangle.
-Kittydar will miss cats sometimes, and sometimes classify non-cats as cats. It's best at detecting upright cats that are facing forward, but it can handle a small tilt or turn in the head.
-
-Kittydar isn't fast. It'll take a few seconds to find the cats in one image. This is just a first-pass attempt and will hopefully improve in the future.
-
# How it works
-Kittydar first chops the image up into many "windows" to test for the presences of a cat head. For each window, kittydar first extracts more tractable data from the image's data. Namely, it computes the [Histogram of Orient Gradients](http://en.wikipedia.org/wiki/Histogram_of_oriented_gradients) descriptor of the image, using the [hog-descriptor](http://github.com/harthur/hog-descriptor) library. This data describes the directions of the edges in the image (where the image changes from light to dark and vice versa) and what strength they are. This data is a vector of numbers that is then fed into a [neural network](https://github.com/harthur/brain) which gives a number from `0` to `1` on how likely the histogram data represents a cat.
+Kittydar first chops the image up into many "windows" to test for the presence of a cat head. For each window, kittydar first extracts more tractable data from the image's data. Namely, it computes the [Histogram of Orient Gradients](http://en.wikipedia.org/wiki/Histogram_of_oriented_gradients) descriptor of the image, using the [hog-descriptor](http://github.com/harthur/hog-descriptor) library. This data describes the directions of the edges in the image (where the image changes from light to dark and vice versa) and what strength they are. This data is a vector of numbers that is then fed into a [neural network](https://github.com/harthur/brain) which gives a number from `0` to `1` on how likely the histogram data represents a cat.
The neural network (the JSON of which is located in this repo) has been pre-trained with thousands of photos of cat heads and their histograms, as well as thousands of non-cats. See the repo for the node training scripts.
-# Propers
+# Limitations
+
+Kittydar will miss cats sometimes, and sometimes classify non-cats as cats. It's best at detecting upright cats that are facing forward, but it can handle a small tilt or turn in the head.
+
+Kittydar isn't fast. It'll take a few seconds to find the cats in one image. There's lots of room for improvement, so fork and send requests.
+
+## Propers
* This informative reasearch paper: [Cat Head Detection - How to Effectively Exploit Shape and Texture Features](http://research.microsoft.com/pubs/80582/ECCV_CAT_PROC.pdf) by Weiwei Zhang, Jian Sun, and Xiaoou Tang
View
2,561 demo/bundle-6.js
2,561 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
38 demo/demo.js
@@ -1,4 +1,30 @@
$(document).ready(function() {
+ $("#example-chooser").hide();
+
+ $("#select-button").on("mouseover", function(event) {
+ $(event.target).css({cursor: "pointer"})
+ })
+
+ $("#select-button").click(function(event) {
+ $("#example-chooser").toggle();
+ $("#example-chooser").css({
+ left: event.pageX + 50,
+ top: event.pageY - 50
+ });
+ console.log(event.target.screenX)
+ });
+
+ $('.example-thumb').click(function(event) {
+ // reload to get full size
+ var img = new Image();
+ img.onload = function() {
+ detectImage(img);
+ }
+ img.src = event.target.src;
+
+ $("#example-chooser").hide()
+ })
+
var viewer = $("#viewer");
viewer.on('dragover', function(e) {
@@ -27,8 +53,15 @@ $(document).ready(function() {
handleFiles(files);
return false;
});
+
});
+function detectImage(img) {
+ drawToCanvas(img);
+ detector.abortCurrent();
+ detector.detectCats();
+}
+
function handleFiles(files) {
var file = files[0];
var imageType = /image.*/;
@@ -42,9 +75,7 @@ function handleFiles(files) {
var reader = new FileReader();
reader.onload = function(e) {
img.onload = function() {
- drawToCanvas(img);
- detector.abortCurrent();
- detector.detectCats();
+ detectImage(img);
}
$("#progress").text("loading image...");
img.src = e.target.result;
@@ -63,6 +94,7 @@ function drawToCanvas(img) {
width *= scale;
height *= scale;
+ $("#viewer-container").width(width).height(height);
$("#viewer").width(width).height(height);
var anno = $("#annotations").get(0);
View
BIN demo/images/.DS_Store
Binary file not shown.
View
BIN demo/images/cat1.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN demo/images/cat2.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN demo/images/cat3.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN demo/images/cat4.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
75 demo/index.css
@@ -1,5 +1,5 @@
body {
- font-family: Helvetica Neue, sans-serif;
+ font-family: Helvetica Neue, Helvetica, Tahoma, sans-serif;
}
#title {
@@ -12,7 +12,7 @@ body {
font-size: 44px;
}
-#subtitle {
+#subtitle, footer {
font-family: Monaco, Menlo, Tahoma, sans-serif;
margin-top: 20px;
}
@@ -23,9 +23,38 @@ body {
text-align: center;
}
+#example-chooser {
+ padding: 20px;
+}
+
+#button-box {
+ display: inline-block;
+}
+
+#example-chooser {
+ background-color: white;
+ z-index: 1;
+ position: absolute;
+ border: 4px solid #CCC;
+ border-radius: 3px;
+}
+
+.example-thumb {
+ width: 48px;
+ height: 48px;
+ border: 3px solid #AAA;
+ border-radius: 2px;
+ cursor: pointer;
+ margin-left: 6px;
+}
+
+#viewer-container {
+ width: 500px;
+ margin: 60px auto 30px auto;
+}
+
#viewer {
position: relative;
- margin: 60px auto 30px auto;
width: 500px;
height: 240px;
border: 4px dashed #ccc;
@@ -73,6 +102,46 @@ body {
font-size: 42px;
}
+.button {
+ background-color: #E2E2E2;
+ box-shadow: #EEE 0 .15em 0.6em;
+ border: 1px solid #CCC;
+ padding: 4px 8px;
+ border-radius: 4px;
+ cursor: pointer;
+ display: inline-block;
+}
+
+.button:active {
+ background-color: #CCC !important;
+}
+
+footer {
+ margin-top: 100px;
+ text-align: center;
+ font-size: 13px;
+ text-align: center;
+ color: grey;
+}
+
+#select-button {
+ font-size: 13px;
+ color: grey;
+ cursor: pointer;
+}
+
+#select-button:hover {
+ color: black;
+}
+
+#select-button:after {
+ content: ">";
+}
+
+#note {
+ margin-top: 20px;
+}
+
@font-face {
font-family: CatsAlphabet;
src: url(CatsAlphabet.ttf);
View
41 demo/index.html
@@ -5,6 +5,7 @@
<script src="jquery.js"></script>
<script src="demo.js"></script>
<script src="bundle-6.js"></script>
+ <script src="bootstrap-dropdown.js"></script>
</head>
<body>
<div id="container">
@@ -16,18 +17,42 @@
Face detection for cats
</div>
</header>
- <div id="viewer">
- <div id="droparea-text">
- Drag an image here to find cats.
+ <div id="viewer-container">
+ <div id="viewer">
+ <div id="droparea-text">
+ Drag an image here to find cats.
+ </div>
+ <canvas id="preview">
+ </canvas>
+ <canvas id="annotations">
+ </canvas>
+ </div>
+
+ <div id="example-chooser">
+ <div id="thumbs">
+ <img class="example-thumb" src="images/cat1.jpg"></img>
+ <img class="example-thumb" src="images/cat2.jpg"></img>
+ <img class="example-thumb" src="images/cat3.jpg"></img>
+ <img class="example-thumb" src="images/cat4.jpg"></img>
+ </div>
</div>
- <canvas id="preview">
- </canvas>
- <canvas id="annotations">
- </canvas>
</div>
</div>
+
<div id="progress">
</div>
- <div id="drawing" hidden=true>1</div>
+
+ <footer>
+ <div id="select-button">
+ test images
+ </div>
+ <div id="note">
+ kittydar is best at detecting upright cats that are facing forward
+ </div>
+ </footer>
+
+ <div id="drawing" hidden=true>1</div>
+
+<a href="http://github.com/harthur/kittydar"><img style="position: absolute; top: 0; right: 0; border: 0;" src="http://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png" alt="Fork me on GitHub"></a>
</body>
</html>
View
2,540 demo/kittydar-browser.js
2,488 additions, 52 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
2 kittydar.js
@@ -1,7 +1,7 @@
var brain = require("brain"),
hog = require("hog-descriptor");
-var network = require("./network-6-final.js");
+var network = require("./networks/network-june13-7.json");
var net = new brain.NeuralNetwork().fromJSON(network);
if (process.arch) {
View
6 testing/test.js
@@ -44,9 +44,9 @@ function runTest() {
console.time("detecting")
var options = {
scaleStep: 6,
- overlapThresh: 0.2,
- minOverlaps: 2,
- shiftBy: 6
+ overlapThresh: 0.3,
+ minOverlaps: 1,
+ shiftBy: 8
};
var cats = kittydar.detectCats(canvas, options);
View
2 training/collection/flickr.rb
@@ -34,5 +34,5 @@ def getPage(page)
end
120.times do |i|
- getPage((i * 7))
+ getPage(i)
end
View
4 training/collection/makenegs.js
@@ -8,7 +8,7 @@ var http = require("http"),
utils = require("../../utils");
var dir = __dirname + "/NEGS_FLICKR/";
-var outdir = __dirname + "/NEGS_SAMPLED2/";
+var outdir = __dirname + "/NEGS_SAMPLED3/";
var part = parseInt(process.argv[2]);
@@ -35,7 +35,7 @@ fs.readdir(dir, function(err, files) {
var canvases = generateFromRaw(canvas);
canvases.forEach(function(canvas) {
- var name = Math.floor(Math.random() * 1000000000);
+ var name = Math.floor(Math.random() * 10000000000);
var file = outdir + name + ".jpg";
utils.writeCanvasToFile(canvas, file, function() {
View
13 training/collection/mine-negatives.js
@@ -6,13 +6,14 @@ var fs = require("fs"),
features = require("../../features"),
utils = require("../../utils");
-var trained = require("./network-6.json");
+var trained = require("../network-6-random.json");
-var dir = __dirname + "/NEGS_SAMPLED2/";
-var minedDir = __dirname + "/NEGS_HARD2/";
+var dir = __dirname + "/NEGS_SAMPLED/";
+var minedDir = __dirname + "/NEGS_HARD1_RAND/";
-var start = 0;
-var count = 0;
+var params = {
+ cellSize: 6
+}
var part = parseInt(process.argv[2]);
@@ -53,7 +54,7 @@ function saveFalsePos(canvases) {
});
var data = canvases.map(function(canvas) {
- var fts = features.extractFeatures(canvas.canvas);
+ var fts = features.extractFeatures(canvas.canvas, params);
return {
file: canvas.file,
input: fts,

0 comments on commit 79acd48

Please sign in to comment.