Commit 9b345841e4633ccf8891aae5d051af07e388e32a
1 parent
c3de2618
put some HTML visualization functions in brpy
Showing
2 changed files
with
61 additions
and
13 deletions
scripts/face_cluster_viz.py renamed to scripts/brpy/face_cluster_viz.py
| 1 | 1 | #!/usr/bin/env python |
| 2 | 2 | |
| 3 | -from PIL import Image | |
| 4 | 3 | import csv, sys, json, argparse |
| 4 | +from brpy.html_viz import crop_to_bb | |
| 5 | 5 | |
| 6 | 6 | parser = argparse.ArgumentParser(description='Visualize face cluster results in an HTML page.') |
| 7 | 7 | parser.add_argument('input_file', type=str, help='Results from clustering (in csv format)') |
| ... | ... | @@ -16,24 +16,15 @@ clustmap = dict() |
| 16 | 16 | with open(args.input_file) as f: |
| 17 | 17 | for line in csv.DictReader(f): |
| 18 | 18 | c = int(line[args.cluster_key]) |
| 19 | + if c not in clustmap: | |
| 20 | + clustmap[c] = [] | |
| 19 | 21 | x,y,width,height = [ float(line[k]) for k in ('Face_X','Face_Y','Face_Width','Face_Height') ] |
| 20 | 22 | imname = '%s/%s' % (args.img_loc, line['File']) |
| 21 | 23 | try: |
| 22 | - img = Image.open(imname) | |
| 23 | - imwidth, imheight = img.size | |
| 24 | + html = crop_to_bb(x,y,width,height,imname,maxheight=400) | |
| 24 | 25 | except IOError: |
| 25 | 26 | print('problem with %s' % imname) |
| 26 | 27 | continue |
| 27 | - ratio = maxheight / height | |
| 28 | - # note for future me: | |
| 29 | - # image is cropped with div width/height + overflow:hidden, | |
| 30 | - # resized with img height, | |
| 31 | - # and positioned with img margin | |
| 32 | - html = '<div style="overflow:hidden;display:inline-block;width:%ipx;height:%ipx;">' % (width*ratio, maxheight) | |
| 33 | - html += '<img src="%s" style="height:%ipx;margin:-%ipx 0 0 -%ipx;"/>' % (imname, imheight*ratio, y*ratio, x*ratio) | |
| 34 | - html += '</div>' | |
| 35 | - if c not in clustmap: | |
| 36 | - clustmap[c] = [] | |
| 37 | 28 | clustmap[c].append(html) |
| 38 | 29 | |
| 39 | 30 | # browsers crash for a DOM with this many img tags, | ... | ... |
scripts/brpy/html_viz.py
0 → 100644
| 1 | +''' | |
| 2 | +Some funcs to generate HTML visualizations. | |
| 3 | +Run from the folder you intend to save the HTML page so | |
| 4 | +the relative paths in the HTML file are correct and PIL can find the images on disk. | |
| 5 | +Requires local images, but should be pretty easy to set up an apache server (or whatev) | |
| 6 | +and host them as long as the relative paths remain the same on ya serva. | |
| 7 | +''' | |
| 8 | + | |
| 9 | +from PIL import Image | |
| 10 | + | |
| 11 | +def crop_to_bb(x, y, width, height, imname, maxheight=None): | |
| 12 | + ''' | |
| 13 | + Generates an HTML string that crops to a given bounding box and resizes to maxheight pixels. | |
| 14 | + A maxheight of None will keep the original size (default). | |
| 15 | + When two crops are put next to each other, they will be inline. To make each crop its own line, wrap it in a div. | |
| 16 | + ''' | |
| 17 | + img = Image.open(imname) | |
| 18 | + imwidth, imheight = img.size | |
| 19 | + if not maxheight: | |
| 20 | + maxheight = height | |
| 21 | + ratio = maxheight / height | |
| 22 | + # note for future me: | |
| 23 | + # image is cropped with div width/height + overflow:hidden, | |
| 24 | + # resized with img height, | |
| 25 | + # and positioned with img margin | |
| 26 | + html = '<div style="overflow:hidden; display:inline-block; width:%ipx; height:%ipx;">' % (width*ratio, maxheight) | |
| 27 | + html += '<img src="%s" style="height:%ipx; margin:-%ipx 0 0 -%ipx;"/>' % (imname, imheight*ratio, y*ratio, x*ratio) | |
| 28 | + html += '</div>' | |
| 29 | + return html | |
| 30 | + | |
| 31 | +def bbs_for_image(imname, bbs, maxheight=None, colors=None): | |
| 32 | + ''' | |
| 33 | + Generates an HTML string for an image with bounding boxes. | |
| 34 | + bbs: iterable of (x,y,width,height) bounding box tuples | |
| 35 | + ''' | |
| 36 | + img = Image.open(imname) | |
| 37 | + imwidth, imheight = img.size | |
| 38 | + if not maxheight: | |
| 39 | + maxheight = imheight | |
| 40 | + ratio = maxheight/imheight | |
| 41 | + html = [ | |
| 42 | + '<div style="position:relative">', | |
| 43 | + '<img src="%s" style="height:%ipx" />' % (imname, maxheight) | |
| 44 | + ] | |
| 45 | + if not colors: | |
| 46 | + colors = ['green']*len(bbs) | |
| 47 | + html.extend([ bb(*box, ratio=ratio, color=color) for color,box in zip(colors,bbs) ]) | |
| 48 | + html.append('</div>') | |
| 49 | + return '\n'.join(html) | |
| 50 | + | |
| 51 | + | |
| 52 | +def bb(x, y, width, height, ratio=1.0, color='green'): | |
| 53 | + ''' | |
| 54 | + Generates an HTML string bounding box. | |
| 55 | + ''' | |
| 56 | + html = '<div style="position:absolute; border:2px solid %s; color:%s; left:%ipx; top:%ipx; width:%ipx; height:%ipx;"></div>' | |
| 57 | + return html % (color, color, x*ratio, y*ratio, width*ratio, height*ratio) | ... | ... |