Skip to content

Instantly share code, notes, and snippets.

@gcr
Created March 29, 2014 13:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gcr/9854495 to your computer and use it in GitHub Desktop.
Save gcr/9854495 to your computer and use it in GitHub Desktop.
#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