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

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

Next phase of developing focusing on colour histogram similarity. C# code by JoJo now ported to JavaScript using colour/get-pixel example developed by Dave Nichols.

File size: 6.4 KB
Line 
1
2var progressVal = 0;
3
4var show_progress = 5;
5
6var timeout_delay = 100;
7
8function drawImage(imageObj, canvasId) {
9 "use strict";
10 var imgCanvas = document.getElementById(canvasId),
11 context, imageData, data,
12 imageX = 0, imageY = 0,
13 imageWidth = imageObj.width,
14 imageHeight = imageObj.height;
15
16 context = imgCanvas.getContext('2d');
17 context.drawImage(imageObj, imageX, imageY, imageWidth, imageHeight);
18 imageData = context.getImageData(imageX, imageY, imageWidth, imageHeight);
19
20 return imageData;
21}
22
23function createHSLHistogram(imageObj, quant)
24{
25 var i;
26
27 if (!$('#hsl_canvas').length) {
28 $('<canvas>', {id: 'hsl_canvas'}).hide().appendTo('body');
29 }
30
31 imageData = drawImage(imageObj,'hsl_canvas');
32
33 var outputLength = quant * quant * quant;
34 var outputArray = new Array(outputLength);
35 for (i=0; i<outputLength; i++) {
36 outputArray[i] = 0;
37 }
38
39 var total = 0.0;
40
41 var log2 = Math.log(2);
42
43 //calculate value to shift by (log base 2)
44
45 var shift_sat = Math.floor(Math.log(quant)/log2);
46 var shift_hue = Math.floor(Math.log(quant*quant)/log2);
47
48 //console.log("bit-shift sat = " + shift_sat);
49 //console.log("bit-shift hue = " + shift_hue);
50
51 var data = imageData.data;
52
53 //Loop through each pixel
54 var y,p;
55 for (y=0,p=0; y<imageObj.height; y++) {
56 var x;
57 for (x=0; x<imageObj.width; x++,p+=4) {
58 // convert 4 byte data value into a colour pixel
59 var rgb_c = new RGBColour(data[p],data[p+1],data[p+2],data[p+3]/255.0);
60 var hsl = new rgb_c.getHSL();
61
62 // express h,s and b in the range 0..1
63
64 var h = hsl.h / 360.0;
65 var s = hsl.s / 100.0;
66 var b = hsl.l / 100.0;
67
68 var result = (Math.floor(h * (quant - 1)) << shift_hue)
69 | (Math.floor(s * (quant - 1)) << shift_sat)
70 | Math.floor(b * (quant - 1));
71
72 //number of opaque pixels
73 var count = hsl.a; // 'a' is naturally in the range 0..1
74
75 //add to the total number of opaque pixels
76 total += count;
77
78 //add the frequency of each colour to the histogram
79 outputArray[result] += count;
80 }
81 }
82
83 //Normalise the histogram, based on the number of opaque pixels
84 for (i=0; i<outputArray.length; i++) {
85 outputArray[i] = outputArray[i] / total;
86 }
87
88 return outputArray;
89}
90
91var flag_comparison_array = Array(2);
92var clicked_on_count = 0;
93
94function quantizedColourHistogramComparison(quant_colour_hist1,quant_colour_hist2)
95{
96 // Assumes both histograms are of the same length
97
98 var i;
99 var quant_product = 0.0;
100
101 //Loop through and compare the histograms
102 for (i=0; i<quant_colour_hist1.length; i++) {
103 //take the overlap
104 quant_product += Math.min(quant_colour_hist1[i], quant_colour_hist2[i]);
105
106 // consider replacing with abs for difference
107 }
108
109 alert("Product for HSL histogram: " + quant_product);
110
111}
112
113
114function displayFlags(img_list,$displayDiv,$progressArea,$progressBar)
115{
116 var img_list_len = img_list.length;
117
118 if (img_list_len==0) {
119 return;
120 }
121 else if (img_list_len>show_progress) {
122 $progressArea.slideDown();
123 }
124
125 var root_img_re = /^.*\/(.*?)\..*?$/;
126
127 var progress_step = 100.0 / img_list_len;
128
129 var callback_count = 0;
130
131 var i;
132 for (i=0; i<img_list.length; i++) {
133 var img_url = img_list[i];
134 var img_matches = root_img_re.exec(img_url);
135 var title = img_matches[1];
136
137 var imageObj = new Image();
138 imageObj.onload = function() {
139 callback_count++;
140 progressVal += progress_step;
141 $progressBar.progressbar('value',progressVal);
142
143 if (callback_count == img_list_len) {
144 if (img_list_len>show_progress) {
145 progressVal = 100;
146 $progressBar.progressbar('value',progressVal);
147 //$progressArea.slideUp();
148
149 // Now move on and start computing colour histograms
150 setTimeout(function()
151 { computeFlagHistograms(img_list,$progressArea,$progressBar); }
152 ,timeout_delay);
153 }
154 }
155 };
156
157 imageObj.onclick = function() {
158 // Store result of HSL quantization in the image object/tag
159 if (!this.quantHSLHist) {
160 // Only need to compute this if it is not already stored in the object/tag
161 this.quantHSLHist = createHSLHistogram(this,16);
162 console.log(this.quantHSLHist);
163 }
164 flag_comparison_array[clicked_on_count] = this.quantHSLHist;
165
166 clicked_on_count++;
167 if (clicked_on_count==2) {
168 // trigger comparison
169 quantizedColourHistogramComparison(flag_comparison_array[0],flag_comparison_array[1]);
170 clicked_on_count=0;
171 }
172 };
173
174
175 imageObj.src = img_url;
176 imageObj.title = title;
177 imageObj.id = "flag-img-" + i;
178
179 $displayDiv.append(imageObj);
180 }
181}
182
183function computeFlagHistogramChain(chain_count, img_list_len,
184 progressVal, progress_step,
185 $progressArea,$progressBar)
186{
187 var flag_id = "flag-img-" + chain_count;
188 console.log("Processing Image ID: " + flag_id);
189 var imageObj = document.getElementById(flag_id);
190
191 if (!imageObj.quantHSLHist) {
192 // Only need to compute this if it is not
193 // already stored in the object/tag
194 imageObj.quantHSLHist = createHSLHistogram(imageObj,16);
195 //console.log(imageObj.quantHSLHist);
196 }
197
198 if (chain_count < img_list_len-1) {
199 progressVal += progress_step;
200 $progressBar.progressbar('value',progressVal);
201
202 setTimeout(function()
203 { computeFlagHistogramChain(chain_count+1,img_list_len,
204 progressVal, progress_step,
205 $progressArea,$progressBar)
206 }
207 ,timeout_delay // any time delay causes break in 'rendering' thread, even 0!
208 );
209
210 }
211 else {
212 $progressArea.find('span:first').text("Done.");
213 if (img_list_len>show_progress) {
214 progressVal = 100;
215 $progressBar.progressbar('value',progressVal);
216 $progressArea.slideUp();
217 }
218 }
219}
220
221function computeFlagHistograms(img_list,$progressArea,$progressBar)
222{
223 var img_list_len = img_list.length;
224
225
226 if (img_list_len==0) {
227 $progressArea.find('span:first').text("Empty list: no computation needed.");
228 return;
229 }
230
231 $progressArea.find('span:first').text("Computing histograms:");
232 progressVal = 0;
233
234 if (img_list_len>show_progress) {
235 $progressArea.slideDown();
236 }
237
238 var progress_step = 100.0 / img_list_len;
239
240 // Start the chaining process
241 setTimeout(function()
242 { computeFlagHistogramChain(0,img_list_len,
243 progressVal, progress_step,
244 $progressArea,$progressBar)
245 }
246 ,timeout_delay // any time delay causes break in 'rendering' thread, even 0!
247 );
248
249}
Note: See TracBrowser for help on using the repository browser.