Created
March 29, 2014 13:26
-
-
Save gcr/9854495 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
#lang at-exp racket | |
(require racket/draw | |
slideshow | |
unstable/gui/pict | |
(planet gcr/pdf-render)) | |
(define-syntax-rule (inches: n) (* n 72)) | |
(define-syntax-rule (feet: n) (* n 12 72)) | |
(define-syntax-rule (einches: n) (inexact->exact (round (inches: n)))) | |
(define-syntax-rule (efeet: n) (inexact->exact (round (feet: n)))) | |
(define-syntax-rule (points: n) n) | |
;;; | |
;;; UNITS AND SCALING | |
;;; | |
(define *width* (feet: 8)) | |
(define *height* (feet: 4)) | |
(define *printer-margin* (inches: 3)) | |
(define *col-vert-whitespace* (inches: 0.8)) ; Between blocks in a column | |
(define *col-horiz-whitespace* (inches: 1)) ; Between successive columns | |
(define *base-font-size* (points: 48)) | |
(define *colheading-font-size* (einches: 1.5)) | |
(define *blocktitle-font-size* (inches: 1)) | |
(define *block-padding* (inches: 0.5)) | |
(define *block-vert-whitespace* (inches: 0.5)) | |
(define *poster-file-name* "cvpr2012-mughunt-demo-poster.pdf") | |
;;; | |
;;; HELPER FUNCTIONS | |
;;; | |
(define (preview pict [dpi 15]) | |
;; Preview the given pict at 20 pixels per inch | |
(scale pict (/ dpi (inches: 1)))) | |
(define (save!) | |
;; IF ALL ELSE FAILS, save as an SVG (use svg-dc%) and have inkscape convert to PDF ;) | |
(send (current-ps-setup) set-scaling 1.0 1.0) | |
(let* ([dc (new pdf-dc% | |
[interactive #f] ; not wanted for SVG | |
[use-paper-bbox #f] ; not wanted for SVG | |
[width *width*] | |
[height *height*] | |
[output *poster-file-name*])]) | |
(send dc start-doc "Poster") | |
(send dc start-page) | |
(draw-pict poster #;(rotate poster (/ pi 2)) dc 0 0) | |
(send dc end-page) | |
(send dc end-doc))) | |
;;; | |
;;; PRETTY GRAPHICS | |
;;; | |
(define (clean-whitespace . texts) | |
(regexp-replace* #px"\\s+" (apply string-append texts) " ")) | |
(define (ftext size st . texts) | |
(define style (cond [(list? st) (append st (current-main-font))] | |
[(symbol? st) (cons st (current-main-font))] | |
[else (current-main-font)])) | |
(text (apply string-append texts) style size)) | |
(define (btt . texts) | |
(map bt (regexp-split #rx" " (apply clean-whitespace texts)))) | |
(define (scale-to-height pict size) | |
(scale pict (/ size (pict-height pict)))) | |
(define (scale-to-width pict size) | |
(scale pict (/ size (pict-width pict)))) | |
(define (scale-to-column-width pict) | |
(scale-to-width pict (current-para-width))) | |
(define (gradient w h x0 y0 x1 y1 stops) | |
(dc | |
(λ (dc x y) | |
(let ([pen (send dc get-pen)] | |
[brush (send dc get-brush)]) | |
(send dc set-pen "black" 0 'transparent) | |
(send dc set-brush (new brush% [style 'solid] [color "red"])) | |
(send dc set-brush (new brush% | |
[style 'solid] [color "red"] | |
[gradient | |
(new linear-gradient% | |
; [x0 x] [y0 y] | |
; [x1 *width*] [y1 y] | |
[x0 (+ x (* w x0))] [y0 (+ y (* h y0))] | |
[x1 (+ x (* w x1))] [y1 (+ y (* h y1))] | |
#; [stops (list (list 0 (make-object color% 0 0 0)) | |
(list 1 (make-object color% 255 0 0)))] | |
[stops | |
(for/list ([stop (in-list stops)]) | |
(list (car stop) | |
(if (list? (cadr stop)) | |
(apply make-object color% | |
(cdr stop)) | |
(cadr stop))))])])) | |
(send dc draw-rectangle x y w h) | |
(send dc flush) | |
(send dc set-pen pen) | |
(send dc set-brush brush))) | |
w h)) | |
(define (hr #:alpha [alpha 0.3] #:color [color (list 0 0 0)]) | |
; We have to specify our colors manually because PDF | |
; does not support transparent gradients. | |
(gradient (current-para-width) (inches: 0.1) | |
0 0 1 0 `((0 ,(lighten 1 color) 1) | |
(0.2 ,(lighten (- 1 (* alpha 0.9)) color) 1) | |
(0.5 ,(lighten (- 1 alpha) color) 1) | |
(0.8 ,(lighten (- 1 (* alpha 0.9)) color) 1) | |
(1 ,(lighten 1 color) 1)))) | |
(define (shade-bg r g b #:lighten [lgh 0] pict) | |
(cc-superimpose | |
(colorize (filled-rounded-rectangle (pict-width pict) (pict-height pict) | |
(inches: 0.5)) | |
(lighten lgh (make-object color% r g b))) | |
pict)) | |
(define (lighten scale c) | |
(if (list? c) | |
(lighten scale (make-object color% (car c) (cadr c) (caddr c))) | |
(make-object color% | |
(- 255 (inexact->exact (round (* (- 255 (send c red)) (- 1 scale))))) | |
(- 255 (inexact->exact (round (* (- 255 (send c green)) (- 1 scale))))) | |
(- 255 (inexact->exact (round (* (- 255 (send c blue)) (- 1 scale)))))))) | |
;;; | |
;;; POSTER LAYOUT | |
;;; | |
(define ((corners #:top-left [tl (blank)] #:top-right [tr (blank)] | |
#:bot-left [bl (blank)] #:bot-right [br (blank)] | |
#:frame? [frame? #f]) width height) | |
(define fr (if frame? frame values)) | |
(fr | |
(lt-superimpose (rt-superimpose (lb-superimpose (rb-superimpose (blank width height) br) bl) tr) tl))) | |
(define (column . picts) | |
;; Ensure that picts are in a column of the correct width and | |
;; have the correct vertical spacing between them. | |
(vc-append (blank (current-para-width) 0) | |
(apply vc-append *col-vert-whitespace* | |
picts))) | |
(define (colspan-thunk nchild colspan columns-thunk) | |
;; Draw columns horizontally | |
;; [ TOP ] | |
;; [1] [2] | |
;; [ BOT ] | |
;; nchild: How many children we have (makes each child smaller) | |
;; colspan: How many colums we should span in our parent (makes this object bigger) | |
(let* ([colspan-width (+ (* (current-para-width) colspan) | |
(* *col-horiz-whitespace* (sub1 colspan)))] | |
[each-child-width (/ (- colspan-width (* *col-horiz-whitespace* (sub1 nchild))) | |
nchild)]) | |
(parameterize ([current-para-width each-child-width]) | |
(apply ht-append *col-horiz-whitespace* (columns-thunk))))) | |
(define-syntax-rule (colspan nchild colspan columns ...) | |
(colspan-thunk nchild colspan (λ() (list columns ...)))) | |
(define (draw-poster-thunk title authors bg ncols column-thunk) | |
;; Draw a poster from columns in column-thunk with the proper parameters | |
(parameterize ([current-para-width (- *width* (* 2 *printer-margin*))] | |
[current-font-size *base-font-size*]) | |
(cc-superimpose ; I wish I could use inset but postscript is stupid and needs a background ._. | |
(colorize (filled-rectangle *width* *height*) "white") | |
(ct-superimpose (bg (- *width* (* 2 *printer-margin*)) | |
(- *height* (* 2 *printer-margin*))) | |
(column | |
(vc-append | |
(scale-to-height title (inches: 2.5)) | |
;; (shadow | |
;; (ftext *maintitle-font-size* 'bold title) | |
;; (inches: 1.0) (inches: 0.2) | |
;; #:shadow-color (make-object color% 210 210 210)) | |
(blank (inches: 0.0)) | |
(cc-superimpose (hr #:alpha 1 #:color '(210 107 30)) | |
(shade-bg | |
255 255 255 | |
(inset authors | |
*block-padding* 0 | |
*block-padding* 0)))) | |
(colspan-thunk | |
ncols 1 ;; We have ncols children, but take up the entire width of the poster (1) | |
(λ() (column-thunk)))))))) | |
(define-syntax-rule (draw-poster title authors bg ncols columns ...) | |
(draw-poster-thunk title authors bg ncols (λ() (list columns ...)))) | |
(define (block-thunk title color thunk) | |
;; Make a shaded block with a title and everything | |
(define block-margin *block-padding*) | |
(define half-margin (* block-margin 0.75)) | |
(define border (- block-margin half-margin)) | |
(define block-spacing *block-vert-whitespace*) | |
(parameterize ([current-para-width (- (current-para-width) (* 2 block-margin))]) | |
(define shaded-block-content | |
(shade-bg (first color) (second color) (third color) | |
#:lighten 0.5 | |
(inset (apply vc-append block-spacing (thunk)) | |
half-margin))) | |
(shade-bg (first color) (second color) (third color) | |
#:lighten 0 | |
(inset | |
(vc-append | |
(colorize (ftext *blocktitle-font-size* 'bold title) "white") | |
shaded-block-content) | |
border 0 border border)))) | |
(define-syntax-rule (block title color picts ...) (block-thunk title color (λ() (list picts ...)))) | |
(define (colheading title color) | |
(vc-append (ftext *colheading-font-size* 'bold title) | |
(hr #:alpha 1 #:color color))) | |
;;; | |
;;; ACTUAL LAYOUT | |
;;; | |
(define color1 '(100 77 82)) | |
(define color2 '(255 151 79)) | |
(define color3 '(247 122 82)) | |
(define color4 '(164 154 135)) | |
(define poster | |
(draw-poster | |
(hc-append (inches: 0.75) | |
(ftext (inches: 2) 'bold "The") | |
(scale-to-height (page->pict "figures/mughunt-logo.pdf") | |
(inches: 2)) | |
(ftext (inches: 2) 'bold "Attribute Search Engine")) | |
(hc-append | |
@ftext[(points: 56) 'bold]{Paper authors:} | |
@ftext[(points: 56) #f]{ Terrance E. Boult, Walter J. Scheirer, Neeraj Kumar, Peter N. Belhumeur.} | |
@ftext[(points: 56) 'bold]{ Demo authors:} | |
@ftext[(points: 56) #f]{ Michael Wilber, Vijay Iyer}) | |
;; TODO: include Columbia and Washington logos to credit the other guys too | |
(corners #:frame? #f | |
#:top-right | |
(vc-append | |
(blank (inches: 0.25)) | |
(hc-append (inches: 1) | |
(scale-to-height (page->pict "figures/UWashington-logo.pdf") | |
(inches: 1.75)) | |
(scale-to-height (page->pict "figures/columbia-logo.pdf") | |
(inches: 1.75)))) | |
#:top-left | |
(hc-append (inches: 1) | |
(scale-to-height (page->pict "figures/UCCSLogo-Standard-Color.pdf") | |
(inches: 2)) | |
(scale-to-height (bitmap "figures/securics-logo.png") | |
(inches: 2))) | |
#:bot-right | |
(ftext (points: 40) #f @clean-whitespace{ | |
This work was supported by | |
ONR SBIR Award N00014-11-C-0243 | |
and ONR MURI Award N00014-08-1-0638. | |
}) | |
) | |
5 ; The poster will have space for this many columns | |
(column | |
(colheading "Background" color1) | |
(block "What is MugHunt?" color1 | |
@para{ | |
MugHunt¹ is a highly scalable Google-like@btt{face search | |
system} based around Cassandra, allowing searching over millions of | |
face images by attributes. | |
@;MugHunt uses custom fusion techniques to analyze score data, returning | |
@;relevant candidates from the database based on the query. | |
}) | |
(block "What are attributes?" color1 | |
@para{An attribute is a textual description of a certain property of an image²—gender, race, expression, ...} | |
(scale (scale-to-column-width (page->pict "figures/attribute-description.pdf")) | |
0.8)) | |
(block "MugHunt features" color1 | |
@para{ | |
Search for faces by@btt{target attributes}, like ``Man with pale skin and beard'' | |
} | |
(scale (scale-to-column-width (page->pict "figures/target-search.pdf")) 0.85) | |
@para{ | |
Mughunt can also search for faces@btt{similar to others}, like | |
``Man with hair and smile similar to @btt{this one}...'' | |
} | |
(scale (scale-to-column-width (page->pict "figures/similarity-search.pdf")) 0.85)) | |
(block "Why Cassandra?" color1 | |
@para{ | |
Cassandra is a@btt{scalable distributed database} | |
system developed by Facebook and currently in use at Twitter. | |
Traditional databases do not perform well with 2 million images | |
and 65 classifier scores for each. Our goal is to scale to | |
200 million images sourced from around the web and various public datasets. | |
} | |
;; @para{ | |
;; Mughunt is designed with scalability in mind, making traditional | |
;; database systems infeasible. Our production Cassandra cluster | |
;; has over 1.5 million images. | |
;; } | |
) | |
;; (block "Why is MugHunt useful?" color1 | |
;; @para{..... crime scenes..... identify based on description... etc}) | |
;; (block "What makes this problem hard?" color1 | |
;; @para{ | |
;; - Using 65 classifiers requires each image to be a point in | |
;; 65-dimensional space | |
;; } | |
;; @para{ | |
;; - Scalability: 1.5 million points. That's a lot of data for any system. | |
;; }) | |
) | |
; (colspan 1 3 | |
; (column | |
; (colspan 3 1 | |
; (colspan 1 2 | |
(colspan 1 3 | |
(column | |
(colheading "About MugHunt: Try it out! http://mughunt.securics.com" color2) | |
(block "Architecture" color2 | |
(scale-to-column-width (page->pict "figures/mughunt-diagram.pdf"))))) | |
(column | |
(colheading "Theory" color4) | |
(block "Score normalization" color4 | |
;; @para{Normalization turns each face's individual classifier | |
;; scores into W-scores, which are meaningful accross | |
;; the multiple-attribute space. This step helps ensure | |
;; each attribute classifier fairly contributes to the | |
;; results, and improves the qualitative performance | |
;; of the system compared to traditional systems. | |
;; } | |
@para{Normalizing each classifier's scores ensures | |
that each attribute classifier has a fair contribution | |
to the results.} | |
(scale (scale-to-column-width (page->pict "figures/normalized-spaces.pdf")) 0.9) | |
@para{This step improves performance compared to other | |
systems:} | |
(scale-to-column-width | |
(page->pict "figures/query-normalize-comparison.pdf"))) | |
(block "Come see our CVPR poster!" color4 | |
@para{For more on the normalization process and to see | |
more theoretical details, please visit:} | |
(vc-append (inches: 0.1) | |
@para[#:align 'center]{@btt{Multi-Attribute Spaces: Calibration for Attribute Fusion and Similarity Search}} | |
@para[#:align 'center]{Posters 3B, Wednesday, 1:35PM})) | |
(parameterize ([current-font-size (points: 25)]) | |
(block "References" color4 | |
(vc-append (inches: 0.1) | |
@para{1: @btt{Multi-Attribute Spaces: Calibration for Attribute Fusion and Similarity Search}, | |
W. Scheirer, N. Kumar, P. Belhumeur, and T. Boult, | |
CVPR 2012} | |
@para{2: @btt{FaceTracer: A Search Engine for Large Collections of Image with Faces}, | |
N. Kumar, P. Belhumeur, and S. Nayar, ECCV 2008} | |
@para{3: @btt{Describable Visual Attributes for Face Verification and Image Search}, | |
N. Kumar, A. Berg, P. Belhumeur, and S. Nayar, T-PAMI, October 2011} | |
@para{4: @btt{Meta-Recognition: The Theory and Practice of Recognition Score Analysis}, | |
W. Scheirer, A. Rocha, R. Micheals, and T. Boult, T-PAMI, August 2011} | |
@para{5: @btt{Robust Fusion: Extreme Value Theory for Recognition Score Normalization}, | |
W. Scheirer, A. Rocha, R. Michaels, and T. Boult, ECCV, September 2010} | |
))) | |
) | |
;) | |
; (block "Examples" color3 | |
; @para{ | |
; Maybe include the figures from the paper here | |
; } | |
; (scale-to-column-width | |
; (cc-superimpose (frame (blank 800 100)) (text "Figure showing example queries")))))) | |
)) | |
#;(show-pict (preview (lt-superimpose poster | |
(frame (blank *width* *height*))))) | |
(displayln "Everything loaded; writing poster...") | |
(save!) | |
(displayln "Done") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment