1/* 2Adapted from COCO website 3By: 4- Pedro Simoes 5- Pedro F. Proenza 6*/ 7 8$('#exploreLoading').hide(); 9var selected = ""; 10var nr_images_loaded; 11var img_ids; 12var cats = new Array(); 13var cats_unsorted = new Array(); 14var cat_selected; 15var cat_selected_id; 16 17var supcatId2CatId = { 1: [1], 2: [2], 3: [3,4], 4: [5,6,7], 5: [8,9], 6: [10], 7: [11,12,13], 8: [14,15,16,17,18,19,20], 9: [21,22,23,24,25], 10: [26], 18 11: [27], 12: [28,29], 13: [30], 14: [31,32,33,34], 15: [35,36], 16: [37,38,39,40,41,42,43], 17: [44,45,46,47,48], 18: [49], 19: [50], 20: [51], 19 21: [52], 22: [53], 23: [54], 24: [55], 25: [56,57], 26: [58], 27: [59], 28: [60] 20 }; 21 22var request = $.ajax({ 23 url: "http://178.128.33.132:5901/twirp/v1.taco.annotations.Service/GetCategories", 24 type: "POST", 25 data: '{}', 26 success: function(data) { 27 $(function() { 28 $("#option1").change(function() { 29 30 var $dropdown = $(this); 31 var key = $dropdown.val(); 32 //var vals = []; 33 34 switch(key) { 35 case 'supercats': 36 cats = data.supercats.split(","); 37 cats_unsorted = Array.from(cats); 38 cats.sort(); 39 console.log(cats) 40 break; 41 42 case 'cats': 43 cats = data.cats.split(","); 44 // Quick fix to handle some backend bug that retrieves duplicates 45 cats = [...new Set(cats)]; 46 cats_unsorted = Array.from(cats); 47 cats.sort(); 48 console.log(cats) 49 break; 50 51 case 'base': 52 cats = ['Please choose mode ']; 53 } 54 55 var $option2 = $("#option2"); 56 $option2.empty(); 57 $.each(cats, function(index, value) { 58 $option2.append("<option>" + value + "</option>"); 59 }); 60 61 }); 62 }); 63 }, 64 contentType: "application/json", 65 dataType: "json", 66}); 67 68document.getElementById('button').onclick = function() { 69 clearCanvas(); 70 var e = document.getElementById("option2"); 71 cat_selected_id = e.selectedIndex; 72 console.log('Cat id selected:', cat_selected_id); 73 74 cat_selected = e.options[e.selectedIndex].text; 75 console.log('Cat selected:', cat_selected); 76 77 cat_selected_id = cats_unsorted.indexOf(cat_selected); 78 console.log('Cat id rectified:', cat_selected_id); 79 80 e = document.getElementById("option1"); 81 var mode = e.options[e.selectedIndex].text; 82 loadImageByCat(mode,cat_selected,popRandImageIds); 83}; 84 85function loadVisualizations(imageIds) { 86 if (imageIds.length > 0){ 87 loadImageData(imageIds, function (dataImage) { 88 // Load segments 89 var imageIds = Object.keys(dataImage); 90 for (var j = 0; j < imageIds.length; j++) { 91 var imageId = imageIds[j]; 92 var instances = dataImage[imageId]['instances']; 93 var other_instances = dataImage[imageId]['other_instances']; 94 var flickrUrl = dataImage[imageId]['flickr_url']; 95 var flickrSmallUrl = dataImage[imageId]['flickr_640_url']; 96 97 // Bail out if flickrSmallUrl is missing. This means the image comes from openlittermap which may cause issues loading and displaying image 98 // or if instances are missing (there use to be a bug on the server that caused this) 99 if (instances.length == 0 || !flickrSmallUrl){ 100 continue; 101 } 102 103 var segments = {}; 104 //for (var i = 0; i < instances.length; i++) catToSegms[instances[i]['category_id']] = []; 105 for (var i = 0; i < instances.length; i++) segments[i] = []; 106 for (var i = 0; i < instances.length; i++) { 107 segments[i].push(instances[i][0]["y"]); 108 } 109 var other_segments = {}; 110 for (var i = 0; i < other_instances.length; i++) other_segments[i] = []; 111 for (var i = 0; i < other_instances.length; i++) { 112 other_segments[i].push(other_instances[i][0]["y"]); 113 } 114 //console.log("Image segments: ", segments); 115 //console.log("Image other segments: ", other_instances); 116 createDisplay(imageId, segments, other_segments, flickrUrl, flickrSmallUrl, dataImage[imageId]['height'], dataImage[imageId]['width']); 117 } 118 119 }); 120 } 121 // unlock search button 122 $('#button').prop("disabled", false); 123 $('#exploreLoading').hide(); 124} 125 126function loadImageData(imageIds, callback) { 127 var promises = []; 128 var querytypes = ["MetaFor", "SegmentationFor"]; 129 console.log("Loading meta & annotations"); 130 for (var i = 0; i < 2; i++) { 131 var req= {"image_ids": imageIds}; 132 var uri = "http://178.128.33.132:5901/twirp/v1.taco.annotations.Service/"+querytypes[i]; 133 console.log('uri:', uri); 134 promises.push($.ajax({ 135 type: 'POST',
136 url: uri, 137 data: JSON.stringify(req), 138 contentType: "application/json", 139 dataType: "json", 140 }).done(function(data){ 141 return data 142 })); 143 } 144 145 Promise.all(promises).then(function(data) { 146 //console.log('Annotations unsorted: ',data); 147 var images = data[0]["all"]; 148 var instances = data[1]["all"]; 149 var imageData = {}; 150 for (var i=0; i<images.length; i++){ 151 var imgId = images[i]['id'] 152 imageData[imgId] = {}; 153 imageData[imgId]['taco_url'] = images[i]['filename']; // TODO 154 imageData[imgId]['flickr_url'] = images[i]['flick_url']; 155 imageData[imgId]['flickr_640_url'] = images[i]['flick_640_url']; 156 imageData[imgId]['width'] = images[i]['width']; 157 imageData[imgId]['height'] = images[i]['height']; 158 imageData[imgId]['instances'] = []; 159 imageData[imgId]['other_instances'] = []; 160 } 161 for (var i=0; i<instances.length; i++){ 162 var imgId = instances[i]['image_id']; 163 164 e = document.getElementById("option1"); 165 var mode = e.options[e.selectedIndex].text; 166 167 if (mode == 'Category'){ 168 169 // Not sure why but the class aluminium does not return 'category_id'. So we use an extra condition 170 if ((instances[i]['category_id'] && instances[i]['category_id'] != cat_selected_id-1) || (!instances[i]['category_id'] && cat_selected_id != 1)){ 171 imageData[imgId]['other_instances'].push(instances[i]["segmentation"]); 172 }else{ 173 imageData[imgId]['instances'].push(instances[i]["segmentation"]); 174 } 175 176 }else{ 177 // Condition for super cats 178 // Retrieve sub cats 179 subcat_ids = supcatId2CatId[cat_selected_id]; 180 181 // Not sure why but the super class aluminium does not return 'category_id'. So we use an extra condition 182 if ((instances[i]['category_id'] && subcat_ids.indexOf(instances[i]['category_id']+1)<0) || (!instances[i]['category_id'] && cat_selected_id != 1)){ 183 imageData[imgId]['other_instances'].push(instances[i]["segmentation"]); 184 }else{ 185 imageData[imgId]['instances'].push(instances[i]["segmentation"]); 186 } 187 188 } 189 } 190 console.log('Annotations sorted:',imageData); 191 192 callback(imageData); 193 }); 194} 195 196function createDisplay(imageId, segms, other_segms, flickrUrl, flickrSmallUrl, height_original, height_width, callback) { 197 198 // Adding canvas for each image 199 var display = 200 '<div class="imageDisplay" id="imageDisplay' + imageId + '" >' + 201 '<div><a id="btn_1" class="btn btn-info btn-sm" role="button">Hide '+cat_selected+ '</a>' + 202 '<a id="btn_2" class="btn btn-black btn-sm" role="button">Show others</a></div>' + //todo 203 //'<div class="design" data-design="http://178.128.33.132/data/' + cocoUrl + '" ></div>' + 204 '<a href='+flickrUrl+' target="_blank">'+ 205 '<canvas class="canvas"></canvas></a>' + 206 '</div>'; 207 208 $('#exploreImageDisplayList').append(display); 209 210 var display = $('#imageDisplay' + imageId) 211 var canvas = display.find("canvas")[0]; 212 var ctx = canvas.getContext("2d"); 213 console.log("Drawing image"); 214 var img = new Image; 215 img.src = flickrSmallUrl; 216 img.onload = function () { 217 canvas.width = this.width; 218 canvas.height = this.height; 219 renderImage(ctx, this); 220 scale = this.height/height_original; 221 222 renderSegms(ctx, this, segms, scale); 223 } 224 225 display.data('image', img); // store image object in display 226 display.data('segms', segms); // store image object in display 227 display.data('other_segms', other_segms); 228 display.data('cat_visible', 1); 229 display.data('others_visible', 0); 230 231 // Adding listeners for user interaction 232 display.find('#btn_1').on('click', function () { 233 //var val = $(this).text(); 234 //var val_default = 'Hide '+cat_selected; 235 if ($(this).parents('.imageDisplay').data('cat_visible') == 1){ 236 //if (val == val_default){ 237 $(this).text('Show '+cat_selected); 238 var img = $(this).parents('.imageDisplay').data('image'); 239 renderImage(ctx, img); 240 $(this).parents('.imageDisplay').data('cat_visible',0); 241 if ($(this).parents('.imageDisplay').data('others_visible') == 1){ 242 segms = $(this).parents('.imageDisplay').data('other_segms'); 243 renderSegms(ctx, this, segms, scale); 244 } 245 }else{ 246 $(this).text('Hide '+cat_selected); 247 var img = $(this).parents('.imageDisplay').data('image'); 248 renderImage(ctx, img); 249 var segms = $(this).parents('.imageDisplay').data('segms');
250 scale = img.height/height_original; 251 renderSegms(ctx, this, segms, scale); 252 $(this).parents('.imageDisplay').data('cat_visible',1); 253 if ($(this).parents('.imageDisplay').data('others_visible') == 1){ 254 segms = $(this).parents('.imageDisplay').data('other_segms'); 255 renderSegms(ctx, this, segms, scale); 256 } 257 } 258 }); 259 260 if (Object.keys(other_segms).length){ 261 262 display.find('#btn_2').on('click', function () { 263 if ($(this).parents('.imageDisplay').data('others_visible') == 0){ 264 $(this).text('Hide others'); 265 var img = $(this).parents('.imageDisplay').data('image'); 266 renderImage(ctx, img); 267 var segms = $(this).parents('.imageDisplay').data('other_segms'); 268 console.log(this.height,height_original) 269 scale = img.height/height_original; 270 renderSegms(ctx, this, segms,scale); 271 $(this).parents('.imageDisplay').data('others_visible',1); 272 // Maintain selected cat visible 273 if ($(this).parents('.imageDisplay').data('cat_visible') == 1){ 274 segms = $(this).parents('.imageDisplay').data('segms'); 275 renderSegms(ctx, this, segms, scale); 276 } 277 278 }else{ 279 $(this).text('Show others'); 280 var img = $(this).parents('.imageDisplay').data('image'); 281 renderImage(ctx, img); 282 $(this).parents('.imageDisplay').data('others_visible',0); 283 // Maintain selected cat visible 284 if ($(this).parents('.imageDisplay').data('cat_visible') == 1){ 285 segms = $(this).parents('.imageDisplay').data('segms'); 286 renderSegms(ctx, this, segms, scale); 287 } 288 } 289 }); 290 } 291} 292 293function renderImage(ctx, img) { 294 ctx.clearRect(0, 0, img.width, img.height); 295 ctx.drawImage(img, 0, 0); 296} 297
298function renderSegms(ctx, img, data, scale) { 299 300 var segms = data[0]; 301 // for (var j=0; j<segms.length; j++){ 302 //console.log('Nr of image segments', data[0].length) 303 Object.keys(data).forEach(function (item) { 304 var hue = ~~(Math.random() * 360); 305 var object_color_transparent = "hsla(" + hue + ", 100%, 60%, 0.5)"; 306 ctx.fillStyle = object_color_transparent 307 var poly = data[item][0] 308 ctx.beginPath(); 309 ctx.moveTo(poly[0]*scale, poly[1]*scale); 310 for (var k=2; k<poly.length; k=k+2){ 311 ctx.lineTo(poly[k]*scale,poly[k+1]*scale); 312 } 313 ctx.lineTo(poly[0]*scale,poly[1]*scale); 314 315 ctx.lineWidth = 2; 316 ctx.closePath(); 317 ctx.fill(); 318 var object_color = "hsla(" + hue + ", 100%, 60%, 1.0)"; 319 ctx.strokeStyle = object_color;//'magenta'; 320 ctx.stroke(); 321 }); 322} 323 324function loadSearch(ids) { 325 console.log("Load Images IDs:", ids); 326 // disable search button and show loading 327 $('#button').prop("disabled", true); 328 $('#exploreLoading').show(); 329 if (ids != undefined){ 330 loadVisualizations(ids); 331 } 332} 333 334function loadImageByCat(mode,tag,callback) { 335 if (mode == "Category"){ 336 var req= {"category": tag}; 337 }else{ 338 var req= {"super_category": tag}; 339 } 340 $.ajax({ 341 type: 'POST', 342 url: 'http://178.128.33.132:5901/twirp/v1.taco.annotations.Service/ImageIdsFor', 343 data: JSON.stringify(req), 344 contentType: "application/json", 345 dataType: "json", 346 }).success( function(data) { 347 //,wconsole.log(data); 348 //$('#exploreSearchCount').text(imIdList.length + ' results'); 349 callback(data,loadSearch); 350 }) ; 351} 352 353function popRandImageIds(data,callback) { 354 355 img_ids_unique = [...new Set(data["image_ids"])]; 356 357 img_ids = shuffle(img_ids_unique) 358 359 var randImIds = []; 360 var N = data["image_ids"].length; 361 console.log("Nr images found:", N); 362 363 var nr_images_to_load = Math.min(N, 5); 364 for (var i=0; i<nr_images_to_load; i++){ 365 if(img_ids[i] != undefined){ 366 randImIds.push(img_ids[i]); 367 }else{ 368 nr_images_to_load -= 1; 369 } 370 } 371 callback(randImIds); 372 nr_images_loaded = nr_images_to_load 373} 374 375function shuffle(a) { 376 var j, x, i; 377 for (i = a.length - 1; i > 0; i--) { 378 j = Math.floor(Math.random() * (i + 1)); 379 x = a[i]; 380 a[i] = a[j]; 381 a[j] = x; 382 } 383 return a; 384} 385 386function clearCanvas() { 387 imIdList = []; 388 $('.imageDisplay').remove(); 389} 390 391$(document.body).on('touchmove', onScroll); // for mobile 392$(window).on('scroll', onScroll); 393 394// Load more images if user reaches the bottom 395//$(window).scroll(function() { 396function onScroll(){ 397 //if($(window).scrollTop() + $(window).height() == $(document).height()) { 398 //if ($(window).scrollTop() + 1 >= $(document).height() - $(window).height()){ 399 if( $(window).scrollTop() + window.innerHeight >= document.body.scrollHeight ) { 400 var N = img_ids.length; 401 console.log(img_ids) 402 var nr_images_loaded_so_far = nr_images_loaded; 403 nr_images_loaded = Math.min(N, nr_images_loaded_so_far + 5); 404 console.log('More images:', nr_images_loaded); 405 var randImIds = []; 406 for (var i=nr_images_loaded_so_far; i<nr_images_loaded; i++){ 407 randImIds.push(img_ids[i]); 408 } 409 loadSearch(randImIds); 410 } 411//}); 412}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.