Skip to content

Commit

Permalink
clean room rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
duhaime committed Dec 7, 2017
1 parent 11489e3 commit de36df3
Show file tree
Hide file tree
Showing 31 changed files with 2,023 additions and 46,337 deletions.
8 changes: 3 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
.DS_Store
data/
data.tar.gz
output/
.DS_Store
*.pem
*.swp
utils/image_vectors/
utils/texture-list.txt
*.swp
64 changes: 16 additions & 48 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,67 +1,35 @@
# TSNE Image Browser

This repository hosts source code used to identify and display 10,000 similar images in a WebGL-powered TSNE image browser.
This repository hosts source code that visualizes tens of thousands of images in a two dimensional projection in which similar images are clustered together. The image analysis leverages Tensorflow's Inception bindings, and the visualization layer leverages a custom performant WebGL viewer.

![App preview](/assets/images/preview.png?raw=true)
![App preview](./assets/images/preview.png?raw=true)

## Dependencies

The scripts in `utils/` rely upon the Python packages identified in `utils/requirememts.txt`. If you create a virtual environment or conda environment, you can run `pip install utils/requirements.txt` to resolve these dependencies.
To install the Python dependencies, you can run (ideally in a virtual environment):
```bash
pip install -r assets/requirements.txt --user
```

Image resizing utilities require ImageMagick compiled with jpg support:
`brew uninstall imagemagick && brew install imagemagick`
```bash
brew uninstall imagemagick && brew install imagemagick
```

The html viewer requires a WebGL-enabled browser.

## Quickstart

If you have a WebGL-enabled browser, you can start a local web server and see the application by running:
If you have a WebGL-enabled browser and a directory full of images to process, you can prepare the data for the viewer by installing the dependencies above then running:

```bash
python imageplot.py "path/to/images/*.jpg"
```
git clone https://github.com/YaleDHLab/tsne-images-webgl
cd tsne-images-webgl

wget https://s3-us-west-2.amazonaws.com/lab-apps/meserve-kunhardt/tsne-map/data.tar.gz
tar -zxf data.tar.gz
To see the results of this process, you can start a web server by running:

# Python3
python -m http.server 7051
# Python3
python -m SimpleHTTPServer 7051
```bash
python server.py
```

The viewer will then be available on `localhost:7051`.

## Data Processing

The following table gives a quick overview of the utilities in `utils/`:

| File | Use |
| ------------- | ------------- |
| classify_images.py | Generates one numpy vector for each input image |
| cluster_vectors.py | Builds a 2d TSNE model with input image vectors |
| get_nearest_neighbors.py | Finds 100 nearest neighbors for each input image vector |
| make_montage.py | Generates one large image file from many small images |
| resize_thumbs.py | Resizes all images in a target directory to 128x128px |
| select_images_to_display.py | Selects a subset of all images to create good-looking clusters |

To process new data, one can run:
```
cd tsne-three-js/utils
pip install -r requirements.txt
# get the nearest neighbors for each image
python get_nearest_neighbors.py
# cherrypick a few thousand images for the tsne map
python select_images_to_display.py
# project the cherry-picked images into a 2d space
python cluster_vectors.py
# make a montage of the cherry-picked images
python make_montage.py
# upload the assets to some s3 bucket
python upload_data_to_s3.py
The visualization will then be available on port 5000.
122 changes: 122 additions & 0 deletions assets/css/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
* {
margin: 0;
padding: 0;
color: #fff;
font-family: 'Open Sans';
}

body,
html,
canvas {
background: #000;
overflow: hidden;
}

h2 {
font-weight: 400;
font-size: 1em;
line-height: 1.05em;
text-align: left;
margin: 10px 0;
}

/***
* Header
***/

.header {
height: 60px;
width: 100%;
position: fixed;
top: 0px;
z-index: 1;
overflow: hidden;
box-shadow: 2px 1px 5px #000;
}

.header,
.logo {
background: #333;
}

.logo {
width: 40px;
padding: 10px 10px 10px 14px;
height: 40px;
}

.app-name,
.tagline {
display: inline-block;
height: 100%;
vertical-align: top;
padding: 18px 34px;
box-sizing: border-box;
font-weight: 300;
}

.app-name {
background: #444;
color: #fff;
font-size: 1.3em;
letter-spacing: 0.1em;
}

.tagline {
color: #999;
font-size: 1em;
padding-top: 20px;
font-weight: 400;
letter-spacing: .025em;
}

@media(max-width: 335px) {
.header .logo {
display: none;
}

.header .app-name {
width: 100%;
text-align: center;
padding: 18px 0;
}
}

/**
* Nav
**/

nav {
position: absolute;
top: 0;
left: 0;
width: 193px;
min-height: 100%;
max-height: 100%;
overflow: auto;
box-sizing: border-box;
padding: 72px 10px 0 10px;
background: rgba(17,17,17,0.9);
box-shadow: 1px 0px 2px rgba(0, 0, 0, 0.7);
transition: transform .5s;
}

nav.hidden {
transform: translateX(-210px);
}

.hotspot {
padding: 6px 2px;
cursor: pointer;
display: inline-block;
text-align: center;
width: 80px;
text-transform: uppercase;
font-size: 13px;
}

.hotspot .background-image {
padding-bottom: 110%;
background-position: 50% 11%;
margin: 0 5%;
}
Binary file removed assets/images/dh-mark.png
Binary file not shown.
31 changes: 31 additions & 0 deletions assets/images/owl.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/images/preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions assets/js/ga.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-101732875-1', 'auto');
ga('send', 'pageview');
Loading

0 comments on commit de36df3

Please sign in to comment.