-
Notifications
You must be signed in to change notification settings - Fork 139
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
31 changed files
with
2,023 additions
and
46,337 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'); |
Oops, something went wrong.