1 |
|
---|
2 | var progressVal = 0;
|
---|
3 |
|
---|
4 | var show_progress = 5;
|
---|
5 |
|
---|
6 | var timeout_delay = 100;
|
---|
7 |
|
---|
8 | function 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 |
|
---|
23 | function 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 |
|
---|
91 | var flag_comparison_array = Array(2);
|
---|
92 | var clicked_on_count = 0;
|
---|
93 |
|
---|
94 | function 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 |
|
---|
114 | function 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 |
|
---|
183 | function 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 |
|
---|
221 | function 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 | } |
---|