source: other-projects/nz-flag-design/trunk/similarity-2d/flag-processing.js@ 29757

Last change on this file since 29757 was 29757, checked in by davidb, 9 years ago

Fixed position/test for a console.log statement

File size: 8.9 KB
Line 
1"use strict";
2
3var progressVal = 0;
4
5var show_progress = 5;
6
7var start_hist_delay = 4000;
8var mini_delay = 300;
9
10
11var hasLocalStorage = false;
12var needToComputeHistograms = true;
13var quantHSLHistogramArray;
14
15
16function drawImage(imageObj, canvasId) {
17 var imgCanvas = document.getElementById(canvasId),
18 context, imageData, data,
19 imageX = 0, imageY = 0,
20 imageWidth = imageObj.width,
21 imageHeight = imageObj.height;
22
23 context = imgCanvas.getContext('2d');
24 context.drawImage(imageObj, imageX, imageY, imageWidth, imageHeight);
25 imageData = context.getImageData(imageX, imageY, imageWidth, imageHeight);
26
27 return imageData;
28}
29
30function createHSLHistogram(imageObj, quant)
31{
32 var i;
33
34 if (!$('#hsl_canvas').length) {
35 $('<canvas>', {id: 'hsl_canvas'}).hide().appendTo('body');
36 }
37
38 var imageData = drawImage(imageObj,'hsl_canvas');
39
40 var outputLength = quant * quant * quant;
41 var outputArray = new Array(outputLength);
42 for (i=0; i<outputLength; i++) {
43 outputArray[i] = 0;
44 }
45
46 var total = 0.0;
47
48 var log2 = Math.log(2);
49
50 //calculate value to shift by (log base 2)
51
52 var shift_sat = Math.floor(Math.log(quant)/log2);
53 var shift_hue = Math.floor(Math.log(quant*quant)/log2);
54
55 //console.log("bit-shift sat = " + shift_sat);
56 //console.log("bit-shift hue = " + shift_hue);
57
58 var data = imageData.data;
59
60 //Loop through each pixel
61 var y,p;
62 for (y=0,p=0; y<imageObj.height; y++) {
63// setTimeout(function() {
64 var x;
65 for (x=0; x<imageObj.width; x++,p+=4) {
66 // convert 4 byte data value into a colour pixel
67 var rgb_c = new RGBColour(data[p],data[p+1],data[p+2],data[p+3]/255.0);
68 var hsl = new rgb_c.getHSL();
69
70 // express h,s and b in the range 0..1
71
72 var h = hsl.h / 360.0;
73 var s = hsl.s / 100.0;
74 var b = hsl.l / 100.0;
75
76 var result = (Math.floor(h * (quant - 1)) << shift_hue)
77 | (Math.floor(s * (quant - 1)) << shift_sat)
78 | Math.floor(b * (quant - 1));
79
80 //number of opaque pixels
81 var count = hsl.a; // 'a' is naturally in the range 0..1
82
83 //add to the total number of opaque pixels
84 total += count;
85
86 //add the frequency of each colour to the histogram
87 outputArray[result] += count;
88 }
89// },4);
90 }
91
92 //Normalise the histogram, based on the number of opaque pixels
93 for (i=0; i<outputArray.length; i++) {
94 outputArray[i] = outputArray[i] / total;
95 }
96
97 return outputArray;
98}
99
100var flag_comparison_array = Array(2);
101var clicked_on_count = 0;
102
103function quantizedColourHistogramComparison(quant_colour_hist1,quant_colour_hist2)
104{
105 // Assumes both histograms are of the same length
106
107 var i;
108 var quant_product = 0.0;
109
110 //Loop through and compare the histograms
111 for (i=0; i<quant_colour_hist1.length; i++) {
112 //take the overlap
113 quant_product += Math.min(quant_colour_hist1[i], quant_colour_hist2[i]);
114
115 // consider replacing with abs for difference
116 }
117
118 alert("Product for HSL histogram: " + quant_product);
119
120}
121
122
123function displayFlags(img_list,$displayDiv,$progressArea,$progressBar)
124{
125 var img_list_len = img_list.length;
126
127 if (img_list_len==0) {
128 return;
129 }
130 else if (img_list_len>show_progress) {
131 $progressArea.slideDown();
132 }
133
134 img_list.sort();
135
136 var root_img_re = /^.*\/(.*?)\..*?$/;
137
138 var progress_step = 100.0 / img_list_len;
139
140 var callback_count = 0;
141
142 var i;
143 for (i=0; i<img_list.length; i++) {
144 var img_url = img_list[i];
145 var img_matches = root_img_re.exec(img_url);
146 var title = img_matches[1];
147
148 var imageObj = new Image();
149 imageObj.onload = function() {
150 callback_count++;
151 progressVal += progress_step;
152 $progressBar.progressbar('value',progressVal);
153
154 if (callback_count == img_list_len) {
155 if (img_list_len>show_progress) {
156 progressVal = 100;
157 $progressBar.progressbar('value',progressVal);
158 //$progressArea.slideUp();
159
160 // Now move on and start computing colour histograms
161 setTimeout(function()
162 { doneDisplayFlags(img_list,$progressArea,$progressBar); }
163 ,start_hist_delay);
164 }
165 }
166 };
167
168
169 /*
170$("h2").live('mousedown', function(e) {
171 if( (e.which == 1) ) {
172 alert("left button");
173 }if( (e.which == 3) ) {
174 alert("right button");
175 }else if( (e.which == 2) ) {
176 alert("middle button");
177 }
178 e.preventDefault();
179}).live('contextmenu', function(e){
180 e.preventDefault();
181});
182 */
183
184
185
186 imageObj.onclick = function(e) {
187 // Store result of HSL quantization in the image object/tag
188 if (!this.quantHSLHist) {
189 // Only need to compute this if it is not already stored in the object/tag
190 this.quantHSLHist = createHSLHistogram(this,16);
191 console.log(this.quantHSLHist);
192 }
193
194 if (e.which == 1 ) {
195 // Left => use in comparison pair
196 flag_comparison_array[clicked_on_count] = this.quantHSLHist;
197
198 clicked_on_count++;
199 if (clicked_on_count==2) {
200 // trigger comparison
201 quantizedColourHistogramComparison(flag_comparison_array[0],flag_comparison_array[1]);
202 clicked_on_count=0;
203 }
204 }
205 else if (e.which == 2) {
206 // Middle => fix on this and do similarity with everything else
207 var fix_id = this.id;
208 e.preventDefault();
209 }
210
211 };
212
213
214 imageObj.src = img_url;
215 imageObj.title = title;
216 imageObj.id = "flag-img-" + i;
217
218 $displayDiv.append(imageObj);
219 }
220}
221
222function computeFlagHistogramChain(chain_count, img_list_len,
223 progressVal, progress_step,
224 $progressArea,$progressBar)
225{
226 var flag_id = "flag-img-" + chain_count;
227 console.log("Processing Image ID: " + flag_id);
228 var imageObj = document.getElementById(flag_id);
229
230 if (!imageObj.quantHSLHist) {
231 // Only need to compute this if it is not
232 // already stored in the object/tag
233 imageObj.quantHSLHist = createHSLHistogram(imageObj,16);
234 //console.log(imageObj.quantHSLHist);
235 }
236
237 if (chain_count < img_list_len-1) {
238 progressVal += progress_step;
239 $progressBar.progressbar('value',progressVal);
240
241 setTimeout(function()
242 { computeFlagHistogramChain(chain_count+1,img_list_len,
243 progressVal, progress_step,
244 $progressArea,$progressBar)
245 }
246 ,mini_delay // any time delay causes break in 'rendering' thread, even 0!
247 );
248
249 }
250 else {
251 $progressArea.find('span:first').text("Done.");
252 if (img_list_len>show_progress) {
253 progressVal = 100;
254 $progressBar.progressbar('value',progressVal);
255 $progressArea.slideUp();
256 }
257
258 doneComputingHistograms(img_list_len);
259 }
260}
261
262
263function computeFlagHistograms(img_list,$progressArea,$progressBar)
264{
265 var img_list_len = img_list.length;
266
267
268 if (img_list_len==0) {
269 $progressArea.find('span:first').text("Empty list: no computation needed.");
270 return;
271 }
272
273
274 $progressArea.find('span:first').text("Computing histograms:");
275 progressVal = 0;
276
277 if (img_list_len>show_progress) {
278 $progressArea.slideDown();
279 }
280
281 var progress_step = 100.0 / img_list_len;
282
283 // Start the chaining process
284 setTimeout(function()
285 { computeFlagHistogramChain(0,img_list_len,
286 progressVal, progress_step,
287 $progressArea,$progressBar)
288 }
289 ,mini_delay // any time delay causes break in 'rendering' thread, even 0!
290 );
291
292}
293
294function doneComputingHistograms(img_list_len)
295{
296 if (hasLocalStorage) {
297 // build up quantHSLHistogramArray from all the images
298
299 quantHSLHistogramArray = new Array(img_list_len);
300 var i;
301 for (i=0; i<img_list_len; i++) {
302 var flag_id = "flag-img-" + i;
303 var imageObj = document.getElementById(flag_id);
304 quantHSLHistogramArray[i] = imageObj.quantHSLHist;
305 }
306
307 console.log("Storing computed HSL histograms in localStorage");
308 localStorage.quantHSLHistogramArray = JSON.stringify(quantHSLHistogramArray);
309 }
310}
311
312function doneDisplayFlags(img_list,$progressArea,$progressBar)
313{
314 hasLocalStorage = false;
315 needToComputeHistograms = true;
316
317 if (typeof(Storage) !== "undefined") {
318 hasLocalStorage = true;
319
320 if (localStorage.quantHSLHistogramArray) {
321
322 console.log("Retrieving quantized HSL histograms");
323
324 var stored_hist_array = JSON.parse(localStorage["quantHSLHistogramArray"]);
325 if (stored_hist_array.length == img_list.length) {
326 // Assume if the number of images process hasn't changed, then neither
327 // has the stored historgram values
328
329 quantHSLHistogramArray = stored_hist_array;
330
331 var i;
332 for (i=0; i<img_list.length; i++) {
333 var flag_id = "flag-img-" + i;
334 var imageObj = document.getElementById(flag_id);
335 imageObj.quantHSLHist = quantHSLHistogramArray[i];
336 }
337
338
339 needToComputeHistograms = false;
340 }
341 else {
342 console.log("Different number of images detected => regenerating");
343 }
344 }
345 }
346
347
348 if (needToComputeHistograms) {
349 computeFlagHistograms(img_list,$progressArea,$progressBar);
350 }
351 else {
352 $progressArea.slideUp();
353 doneComputingHistograms(img_list.length);
354 }
355}
356
357function rankBySimilarity(imageData,x_dim,y_dim)
358{
359 // quantizedColourHistogramComparison(quant_colour_hist1,quant_colour_hist2)
360
361}
Note: See TracBrowser for help on using the repository browser.