{"cells":[{"metadata":{"_uuid":"1e99c1e6d51186e4459acda86ab1316c8fef9019"},"cell_type":"markdown","source":"**# Blueprint Pressure Gauge recognition \nBased on Line Drawings of 3D Models from the paper https://gfx.cs.princeton.edu/pubs/_2009_LDO/cole_2009_ldo.pdf\n\n <b>Prompt Selection</b>\nA second design decision is to select 3D models and rendering parameters to use when\nproducing prompts (images depicting a shape for the artists to draw). In making this\nchoice, we use the following design criteria:\n\n <b>• Comprehension:</b> our first concern is to provide images from which the\nartists can easily infer shape. This consideration rules out overly abstract\n3D surfaces (i.e., shapes unlike anything in common experience), complicated\nconcave shapes (e.g., with lots of occluded surfaces), and surfaces with spatiallyvarying\nBRDFs (e.g., textures). It also suggests that multiple views of the shape\nbe provided as prompts, so that ambiguities in one view are resolved by another.\nFinally, prompt images should be photorealistic, to avoid confusing artists that\nare not familiar with classic CG rendering artifacts such as hard shadows and\nlack of indirect illumination.\n\n <b>• Coverage:</b> the set of prompts presented to each artist should have pixels that\ncover a wide variety of mathematical properties (e.g., high image gradients,\nsurface critical points, etc.). This consideration rules out objects containing\nonly large, planar facets (few interesting surface features), convex objects (no\nconcave surface features), and other surfaces with few inflections. Rather, it\nsuggests blobby objects with many curved surfaces.\n\n <b>• Separation:</b> the prompt images should have mathematical features of particular\ninterest (e.g., suggestive contours, apparent ridges) in clearly distinguishable\npositions within the image. This consideration rules out using headlights (a\npoint light centered at the viewer’s eye), since many interesting image features\nline up directly with object-space features in that case (e.g., suggestive contours\nand image intensity valleys).\n\n <b>• Familiarity:</b> the objects shown in prompts must be familiar to the artist (so\nthat he/she can understand it), but not so familiar to the that he/she applies\ndomain-specific knowledge when drawing. This consideration rules out objects\nwith strong semantic features (e.g., human faces) and ones commonly drawn in\nart classes (e.g., fruit).\n\n <b>• Simplicity:</b> the objects must be relatively simple, without much fine scale\ndetail. Otherwise, the artists may be tempted to abstract or simply omit\nimportant features.\n\n![](http://www.elmundoplay.com/images/pressure_gauge.png)\n\nFigure 1: Gauge figure results. In this study different people were shown six different\nrenderings of a shape: (a) a shaded image, (b) a line drawing made from the shaded\nimage by a person, (c) contours, (d) apparent ridges, and (shown in Figure 4.7)\nridges/valleys and suggestive contours. Overlaid are representative “gauges” (discs\nrevealing the surface normal) oriented on the images by people in the study, colored\nby how far they deviate from the ground truth\n\n\n![](http://www.elmundoplay.com/images/3Dblueprint.png)\n\nFigure 2: Distributions of angular errors from ground truth for all models. Colors\nare as in Figure 4.4. Below the graphs are the human artists’ drawings used for the\nmodels. Inset in each graph is a visualization of the p-values for significance (black:\np-value > 0.05) of difference between distributions, where the colors correspond to\nthe styles in the histogram. The table for the cubehole is incomplete and therefore\nomitted. Images are ordered by the mean error for the human artist’s drawing.\n\n\n"},{"metadata":{"trusted":true,"_uuid":"f2cac137d7913d05b8e04a4c39a8c243f54eebb9"},"cell_type":"code","source":"import ast\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as blueprint #blueprint\nfrom dask import bag #bag\nfrom tqdm import tqdm\nfrom PIL import Image, ImageDraw\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4b1bd54ae26d12b76232f21bfea7da034cf89f94"},"cell_type":"code","source":"def gauge_F(x):\n    counts = np.bincount(x)\n    p = counts[counts > 0] / float(len(x))\n    # compute Shannon gauge in bits\n    return -np.sum(p * np.log2(p))\n\ndef draw_F(strokes):\n    image = Image.new(\"P\", (256,256), color=255)\n    draw = ImageDraw.Draw(image)\n    for stroke in ast.literal_eval(strokes):\n        for i in range(len(stroke[0])-1):\n            draw.line([stroke[0][i], stroke[1][i], stroke[0][i+1], stroke[1][i+1]], fill=0, width=5)\n    image = np.array(image)\n    return gauge_F(image.flatten()), image\n\ndef plot_F(gauge, images, indices, n=5): #plot_F\n    fig, axs = blueprint.subplots(nrows=n, ncols=n, figsize=(12, 10))\n    for i, j in enumerate(indices[0][:n*n]):\n        ax = axs[i // n, i % n]\n        ax.set_title(\"%.4f\" % gauge[j])\n        ax.imshow(images[j], cmap=\"gray\")\n        ax.set_yticks([])\n        ax.set_xticks([])\n        blueprint.setp(ax.spines.values(), color=\"red\")\n    blueprint.subplots_adjust(bottom=-0.2)\n    blueprint.show()\n","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true,"scrolled":false},"cell_type":"code","source":"reader = pd.read_csv('../input/train_simplified/clock.csv', index_col=['key_id'], chunksize=1024)\n\ndata = []\nfor chunk in tqdm(reader):\n    gaugebag = bag.from_sequence(chunk.drawing.values).map(draw_F) \n    data.extend(gaugebag.compute()) # PARALLELIZE\n\ngauge, images = zip(*data)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e988d652a20ec614fc6cf2bf542da06091acdfce"},"cell_type":"markdown","source":"## **Recognition messure**"},{"metadata":{"trusted":true,"_uuid":"184f0bf97c087adad3dbcf2bf63a22603b312eb4","scrolled":true},"cell_type":"code","source":"threshold = 1\nlower = np.percentile(gauge, threshold)\nupper = np.percentile(gauge, 100 - threshold)\nprint(np.min(gauge), np.max(gauge))\nprint(lower, upper)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f52b2c414cf41a7b0c36c818e86d0cacea3225cb"},"cell_type":"code","source":"blueprint.title(\"Recognition messure\")\nblueprint.xlabel('gauge')\nblueprint.ylabel('count')\nblueprint.hist(gauge, bins=100)\nblueprint.axvline(x=lower, color='r')\nblueprint.axvline(x=upper, color='r')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b772d50c2bd04ecfc7520783c7542083cdad0c0f"},"cell_type":"markdown","source":"> ## Low precision"},{"metadata":{"trusted":true,"_uuid":"5984a58ffc27a19e15cda5405851fe08f396a698","scrolled":true},"cell_type":"code","source":"plot_F(gauge, images, np.where(gauge < lower))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"58575b67be908d46564b21fdb6d4b27994974d71"},"cell_type":"markdown","source":"## High precision"},{"metadata":{"trusted":true,"_uuid":"8455359246b67d05c2ad51310a5e06740e35756c"},"cell_type":"code","source":"plot_F(gauge, images, np.where(gauge > upper))","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}