diff --git a/.gitignore b/.gitignore index fc44ca6bd9f25d424b42fa24b1505899302a05d8..b9e5d43c8e464c07ca07e278fec9dbef7e83e52d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ **/sol_*.js **/sol_*.html +**/old* +**/.DS_Store diff --git a/data/16_02.JPG b/data/16_02.JPG new file mode 100644 index 0000000000000000000000000000000000000000..ed3a652cd660ddd9ad3414cc023c4fd8fdf51ca3 Binary files /dev/null and b/data/16_02.JPG differ diff --git a/data/16_03.JPG b/data/16_03.JPG new file mode 100644 index 0000000000000000000000000000000000000000..567d529d5cfc909c21e14215db2412bf0feab849 Binary files /dev/null and b/data/16_03.JPG differ diff --git a/data/16_04.JPG b/data/16_04.JPG new file mode 100644 index 0000000000000000000000000000000000000000..8144088eb781b9d3fb898bcc5207df66fa311cc6 Binary files /dev/null and b/data/16_04.JPG differ diff --git a/data/16_05.JPG b/data/16_05.JPG new file mode 100644 index 0000000000000000000000000000000000000000..58a3a4125e4c59ef695fa51527121b8a12dbfa4f Binary files /dev/null and b/data/16_05.JPG differ diff --git a/data/16_06.JPG b/data/16_06.JPG new file mode 100644 index 0000000000000000000000000000000000000000..714a887141bfb91311d09d7627477e8a175d68c0 Binary files /dev/null and b/data/16_06.JPG differ diff --git a/data/16_07.JPG b/data/16_07.JPG new file mode 100644 index 0000000000000000000000000000000000000000..cfeb0f786b81c458f977f5306ad8fb3a96f3317a Binary files /dev/null and b/data/16_07.JPG differ diff --git a/data/16_08.JPG b/data/16_08.JPG new file mode 100644 index 0000000000000000000000000000000000000000..1b575a2d9a0cfd92339af09f83a36fae167842a4 Binary files /dev/null and b/data/16_08.JPG differ diff --git a/data/16_09.JPG b/data/16_09.JPG new file mode 100644 index 0000000000000000000000000000000000000000..d783241ed401d910ed9462a4f285082a6ab84dea Binary files /dev/null and b/data/16_09.JPG differ diff --git a/data/16_10.JPG b/data/16_10.JPG new file mode 100644 index 0000000000000000000000000000000000000000..7b9c6b9e60d3b1c6afe52f49669dbf92256a8fcf Binary files /dev/null and b/data/16_10.JPG differ diff --git a/data/16_11.JPG b/data/16_11.JPG new file mode 100644 index 0000000000000000000000000000000000000000..2e06317b1e860fccc943d9949d02262bcaff1412 Binary files /dev/null and b/data/16_11.JPG differ diff --git a/data/16_12.JPG b/data/16_12.JPG new file mode 100644 index 0000000000000000000000000000000000000000..9fafb4d74c9bc2af927043fcb32930d4372ea606 Binary files /dev/null and b/data/16_12.JPG differ diff --git a/data/16_13.JPG b/data/16_13.JPG new file mode 100644 index 0000000000000000000000000000000000000000..b7c7b5017538ac25ffdafd0ca3dff00539abf7aa Binary files /dev/null and b/data/16_13.JPG differ diff --git a/data/I1.png b/data/I1.png new file mode 100644 index 0000000000000000000000000000000000000000..4a74690a129640bab53f072efc2b19c59198ae23 Binary files /dev/null and b/data/I1.png differ diff --git a/data/I2.png b/data/I2.png new file mode 100644 index 0000000000000000000000000000000000000000..c30b6ade5df09e8e65741a76ae35d38167e782a1 Binary files /dev/null and b/data/I2.png differ diff --git a/data/I3.png b/data/I3.png new file mode 100644 index 0000000000000000000000000000000000000000..775d0d2e8daffc9153a73186585d19aa3e9a4224 Binary files /dev/null and b/data/I3.png differ diff --git a/data/I4.png b/data/I4.png new file mode 100644 index 0000000000000000000000000000000000000000..3f516d07fb86f460bce173be32b375f02cc361a1 Binary files /dev/null and b/data/I4.png differ diff --git a/data/I5.png b/data/I5.png new file mode 100644 index 0000000000000000000000000000000000000000..48ae0aba6e3afeb44d5d0cf998a0c0238ad57495 Binary files /dev/null and b/data/I5.png differ diff --git a/data/I6.png b/data/I6.png new file mode 100644 index 0000000000000000000000000000000000000000..0a8dd95e11942fc1e688a2d543ddccb98925bf3f Binary files /dev/null and b/data/I6.png differ diff --git a/data/I7.png b/data/I7.png new file mode 100644 index 0000000000000000000000000000000000000000..b874a94dd053bd91e30c529ad776de021cd27d66 Binary files /dev/null and b/data/I7.png differ diff --git a/data/I8.png b/data/I8.png new file mode 100644 index 0000000000000000000000000000000000000000..2b9710eda7e7ace2254bd83a4c623e2dda4d9fc7 Binary files /dev/null and b/data/I8.png differ diff --git a/data/ii2d.png b/data/ii2d.png new file mode 100644 index 0000000000000000000000000000000000000000..0a5cd802446f410c52168be74a31004a245ef706 Binary files /dev/null and b/data/ii2d.png differ diff --git a/data/red.png b/data/red.png new file mode 100644 index 0000000000000000000000000000000000000000..3353a820f9451ee0ff1170ecff2890a7c0ce1aa4 Binary files /dev/null and b/data/red.png differ diff --git a/dataset/images.js b/dataset/images.js new file mode 100644 index 0000000000000000000000000000000000000000..733ab76cfb6f2619c252cf0def0cc148e68e6ec2 --- /dev/null +++ b/dataset/images.js @@ -0,0 +1,51 @@ +var datasets={} + +/* + datasets.ImageDataset + - constructs a collection of images (this.imageDatas) based on image_ids + - ALL IMAGES SHOULD HAVE THE SAME WIDTH and HEIGHT + - it exports this.imageDatas and this.image_ids for accessing image information +*/ +datasets.ImageDataset=function(image_ids){ + this.image_ids=image_ids; + this.imageDatas=[]; + for (var idx in this.image_ids) { + this.imageDatas[idx]=Tools.get_imageData_from_imgEltId(this.image_ids[idx]); + } +} + +/* + datasets.ImageDataset + - constructs a collection of images (this.imageDatas) for a given imageData, + considering various sizes and steps related to floating windows + - it exports this.imageDatas and this.image_ids for accessing image information + - for debugging reasons, if the containing page has a div id="res", + the newly created dataset is displayed +*/ +datasets.PartsOfImageDataset=function(imageData,sizes_and_steps){ + if (document.getElementById("res")) { + document.getElementById("res").appendChild(document.createTextNode("Candidate windows")); + document.getElementById("res").appendChild(document.createElement("br")); + } + + this.imageDatas=[]; + this.count=0; + for (var idx_s in sizes_and_steps) { + height=sizes_and_steps[idx_s].height; width=sizes_and_steps[idx_s].width; + for (var y=0;y<imageData.height-height;y+=sizes_and_steps[idx_s].y) { + for (var x=0;x<imageData.width-width;x+=sizes_and_steps[idx_s].x) { + this.imageDatas[this.count]= + Tools.get_region_from_imageData( + imageData, + x,y,width,height); + + if (document.getElementById("res")) + document.getElementById("res").appendChild(Tools.create_canvasElt_from_imageData(this.imageDatas[this.count])); + + this.count++; + } + if (document.getElementById("res")) + document.getElementById("res").appendChild(document.createElement("br")); + } + } +} diff --git a/multi/fusion.js b/effects/fusion.js similarity index 93% rename from multi/fusion.js rename to effects/fusion.js index 0889deb64d72953634cd049109bfb5fdfdefb8ac..6166f3894dc9e27ada598637813b0a297280a65d 100644 --- a/multi/fusion.js +++ b/effects/fusion.js @@ -5,7 +5,7 @@ MeanFuseMultiImagesTask.prototype.process_multi=function(imageDatas,fused) { for (var y=0;y<fused.height;y++) { for (var x=0;x<fused.width;x++) { fused.data[w]=0; fused.data[w+1]=0; fused.data[w+2]=0; fused.data[w+3]=0; - for (idx in imageDatas) { + for (var idx in imageDatas) { for (var i=0; i<4; i++) { fused.data[w+i]+=imageDatas[idx].data[w+i]; } diff --git a/effects/photo_fill.js b/effects/photo_fill.js new file mode 100644 index 0000000000000000000000000000000000000000..541707f3d99b665192e6c6163e0fb9429314cc07 --- /dev/null +++ b/effects/photo_fill.js @@ -0,0 +1,29 @@ +var photo_fill={}; + +photo_fill.PhotoFillPixelsFromDatasetTask=function(dataset,opt_options){ + this.dataset=dataset; + this.similarity_task=new pixels_similarity.MeanRGBSimilarityTask(_dataset,{}); +; +} + +photo_fill.PhotoFillPixelsFromDatasetTask.prototype.process=function(in_imageData,out_imageData) { + var w=0; + for (var y=0;y<in_imageData.height;y++) { + for (var x=0;x<in_imageData.width;x++,w+=4) { + if (in_imageData.data[w+3]==0) + continue; + + var rgb_pixel=[in_imageData.data[w],in_imageData.data[w+1],in_imageData.data[w+2]]; + + var sim_res=this.similarity_task.process_descriptor(rgb_pixel); + + var min_idx=sim_res[1].idx; + + var pixel_image=this.similarity_task.dataset.imageDatas[min_idx]; + x_dest=x*pixel_image.width; + y_dest=y*pixel_image.height; + + Tools.copy_imageData_into_imageData(pixel_image,out_imageData,x_dest,y_dest); + } + } +} diff --git a/features/generic.js b/features/generic.js new file mode 100644 index 0000000000000000000000000000000000000000..aaf04c0ae01d95b2007e54ed5d52611f1623d769 --- /dev/null +++ b/features/generic.js @@ -0,0 +1,35 @@ +var generic_features={}; + +/* + generic_features.grid_descriptor + - generates grid-like descriptors considering for each cell descriptor_func + as a descriptor extractor + - it requires opt_options.nb_columns and opt_options.nb_lines for grid + construction + - opt_options may contain other options related to param extraction + - on each subsequent cell based descriptor called, x0,y0,dx,dy opt_options + are set + - it returns a grid object containing grid.nb_columns x grid.nb_lines + grid.cells array, where each grid.cells[i] corresponds to + the i-th cell descriptor +*/ +generic_features.grid_descriptor=function(imageData,descriptor_func,opt_options) { + + var grid={}; + grid.cells=[]; + grid.nb_columns=opt_options.nb_columns; grid.nb_lines=opt_options.nb_lines; + cell_width=imageData.width/grid.nb_columns; + cell_height=imageData.height/grid.nb_lines; + + for (var i=0;i<grid.nb_columns;i++) + for (var j=0;j<grid.nb_lines; j++) { + opt_options.x0=i*cell_width; + opt_options.y0=j*cell_height; + opt_options.dx=cell_width; + opt_options.dy=cell_height; + grid.cells.push( + descriptor_func(imageData,opt_options) + ); + } + return grid; +} diff --git a/features/pixels.js b/features/pixels.js index 755c8f109e931bb609af8711bed380534a852851..d471e620af382abdda1e7f3a7b092472127e88ff 100644 --- a/features/pixels.js +++ b/features/pixels.js @@ -1,19 +1,55 @@ -GetPixelRGBATask=function(opt_options) { - this.x=opt_options.x; - this.y=opt_options.y; - this.output=opt_options.output; +var pixels_features={}; + +/* + pixels_features.mean_rgb + - computes RGB mean of all pixels having A>0 within imageData +*/ +pixels_features.mean_rgb=function(imageData,opt_options) { + return pixels_features.mean_rgb_per_region(imageData,{x0:0,y0:0,dx:imageData.width,dy:imageData.height}); } -GetPixelRGBATask.prototype.process=function(imageData) { - var pos=(this.y*imageData.width+this.x)<<2; - var r=imageData.data[pos]; - var g=imageData.data[pos+1]; - var b=imageData.data[pos+2]; - var a=imageData.data[pos+3]; +/* + pixels_features.mean_rgb_per_region + - computes RGB mean of all pixels having A>0 within opt_options.x0 .y0 .dx .dy + - if opt_options missing partially, + replace partially with defaults 0, 0, imageData.width, imageData.height + - returns undefined if none available +*/ +pixels_features.mean_rgb_per_region=function(imageData,opt_options) { + x0=opt_options&&opt_options.x0?opt_options.x0:0; + y0=opt_options&&opt_options.y0?opt_options.y0:0; + dx=opt_options&&opt_options.dx?opt_options.dx:imageData.width; + dy=opt_options&&opt_options.dy?opt_options.dy:imageData.height; + + + var mean=[]; + mean[0]=0; mean[1]=0; mean[2]=0; + var pos=0; var count=0; + for (var y=y0;y<y0+dy;y++) + for (var x=x0;x<x0+dx;x++) { + pos=(y*imageData.width+x)<<2; + if (imageData.data[pos+3]>0) { + for (var i=0;i<3;i++) { + mean[i]+=imageData.data[pos+i]; + } + count++; + } + } + if (count>0) { + for (var i=0;i<3;i++) { + mean[i]=Math.round(mean[i]/count); + } + return mean; + } + return undefined; +} - this.output.innerHTML=this.x+"x"+this.y+" : "; - this.output.innerHTML+="<font color='red'>"+r+"</font> | "; - this.output.innerHTML+="<font color='green'>"+g+"</font> | "; - this.output.innerHTML+="<font color='blue'>"+b+"</font> | "; - this.output.innerHTML+="<font color='gray'>"+a+"</font>"; +/* + pixels_features.grid_mean_rgb + - computes RGB mean of all pixels having A>0 in all grid cells + - grid params are defined as opt_options.nb_lines*opt_options.nb_columns + - returns a generic_features.grid_descriptor (grid.cells - array) +*/ +pixels_features.grid_mean_rgb=function(imageData,opt_options) { + return generic_features.grid_descriptor(imageData,pixels_features.mean_rgb_per_region,opt_options); } diff --git a/generateHtmlAllImages.sh b/generateHtmlAllImages.sh new file mode 100644 index 0000000000000000000000000000000000000000..5db76b6ecfb5cc5ffd828eafee0fcc04aa6c4758 --- /dev/null +++ b/generateHtmlAllImages.sh @@ -0,0 +1,8 @@ +echo "<html><body>" +count=1; +while read img ; +do +echo "<img id='input${count}' src='$img'></img>" +count=$(( $count + 1 )) +done +echo "</body></html>" diff --git a/lookup/windows.js b/lookup/windows.js new file mode 100644 index 0000000000000000000000000000000000000000..77c7dd7a6fca736e7bb01f0a7bdc0525892a2f21 --- /dev/null +++ b/lookup/windows.js @@ -0,0 +1,41 @@ +var lookup_windows={}; + + +lookup_windows.MeanRGBSameSizeTemplate=function( + template_imgElt_id,threshold +) { + this.template_imageData=Tools.get_imageData_from_imgEltId(template_imgElt_id); + this.threshold=threshold; +} + +lookup_windows.MeanRGBSameSizeTemplate.prototype.process=function(in_imageData) { + var lookup_dataset=new datasets.PartsOfImageDataset( + in_imageData, + sizes_and_steps= + [{width:this.template_imageData.width,height:this.template_imageData.height, + x:this.template_imageData.width/4,y:this.template_imageData.height/4}] + ); + + var similarity_task=new pixels_similarity.MeanRGBSimilarityTask(lookup_dataset,{}); + + var sim_res=similarity_task.process(this.template_imageData); + + if (document.getElementById("res")) { + document.getElementById("res").appendChild(document.createTextNode("Selected windows")); + document.getElementById("res").appendChild(document.createElement("br")); + } + + var windows=[]; + for (idx in sim_res) { + if (sim_res[idx].sim>this.threshold) + break; + sim_imageData=lookup_dataset.imageDatas[sim_res[idx].idx]; + windows.push({sim:sim_res[idx].sim,idx:sim_res[idx].idx, + x:sim_imageData.orig_x,y:sim_imageData.orig_x, + dx:sim_imageData.width,dy:sim_imageData.height}); + document.getElementById("res") + .appendChild(Tools.create_canvasElt_from_imageData(sim_imageData)); + } + + return windows; +} diff --git a/metrics/generic.js b/metrics/generic.js new file mode 100644 index 0000000000000000000000000000000000000000..f847b30266ddfd8abb56a07eb8205adddcd006af --- /dev/null +++ b/metrics/generic.js @@ -0,0 +1,26 @@ +var generic_metrics={}; + +/* + generic_metrics.euclidian_distance_btw_feature_vectors + - computes the euclidian distance between two feature vectors sharing + a common structure + - it requires feature_distance_func which computes the distance between + individual components of the descriptor + - return the euclidian distance in the R^n space, + where n is descriptor_array_1.length +*/ +generic_metrics.euclidian_distance_btw_feature_vectors=function( + descriptor_array_1, + descriptor_array_2, + feature_distance_func) { + var sum=0, count=0; + for (var idx in descriptor_array_1) { + var dist=feature_distance_func(descriptor_array_1[idx],descriptor_array_2[idx]); + sum+=dist*dist; + count++; + } + if (count>0) { + return Math.sqrt(sum); + } else + return undefined; +} diff --git a/metrics/pixels.js b/metrics/pixels.js new file mode 100644 index 0000000000000000000000000000000000000000..2a9441cc8e86d627da0cd0027b523e51480a7609 --- /dev/null +++ b/metrics/pixels.js @@ -0,0 +1,18 @@ +var pixel_metrics={}; + +/* + pixel_metrics.rgb_edist - computes euclidian distance between two rgb pixels +*/ +pixel_metrics.rgb_edist=function(pixel_rgb1, pixel_rgb2) { + var dist_fun=function(x,y){return x-y}; + return generic_metrics.euclidian_distance_btw_feature_vectors(pixel_rgb1,pixel_rgb2,dist_fun); +} + +/* + pixel_metrics.rgb_edist - computes euclidian distance between two grids + containing in each cell an rgb pixel +*/ +pixel_metrics.grid_rgb_edist=function(pixels_rgb_grid1, pixels_rgb_grid2) { + var dist_fun=pixel_metrics.rgb_edist; + return generic_metrics.euclidian_distance_btw_feature_vectors(pixels_rgb_grid1.cells,pixels_rgb_grid2.cells,dist_fun); +} diff --git a/multi_processing.js b/multi_processing.js index cafa8dc2e10f3798b1bcf2f6fb5aad9d5b975cfb..94505cd16cd42e53c48814e4886b072c6c4498e8 100644 --- a/multi_processing.js +++ b/multi_processing.js @@ -4,7 +4,7 @@ var multi_processing=function(elementIds,task_multi,outputCanvasId) { this.processing_canvas=[]; this.processing_context=[]; this.imageDatas=[]; var lastCanvasElt={}; - for (idx in elementIds) { + for (var idx in elementIds) { this.element[idx]=document.getElementById(elementIds[idx]); @@ -33,6 +33,7 @@ var multi_processing=function(elementIds,task_multi,outputCanvasId) { this.output_canvas=document.getElementById(outputCanvasId); this.output_context=this.output_canvas.getContext("2d"); } + this.result={}; } multi_processing.prototype.acquire_data_from_img=function(id) { @@ -67,10 +68,14 @@ multi_processing.prototype.acquire_data=function() { multi_processing.prototype.do_process=function() { this.acquire_data(); - this.task_multi.process_multi(this.imageDatas,this.imageData_fused); + this.result=this.task_multi.process_multi(this.imageDatas,this.imageData_fused); if (this.output_canvas) this.update_output(); } multi_processing.prototype.update_output=function() { this.output_context.putImageData(this.imageData_fused,0,0); } + +multi_processing.prototype.get_result=function() { + return this.result; +} diff --git a/filters/gray_filters.js b/processing/filters/gray_filters.js similarity index 100% rename from filters/gray_filters.js rename to processing/filters/gray_filters.js diff --git a/processing/pixels.js b/processing/pixels.js new file mode 100644 index 0000000000000000000000000000000000000000..14f981400c6ba1499fac45c44c7f032bd3e9e7da --- /dev/null +++ b/processing/pixels.js @@ -0,0 +1,43 @@ +GetPixelRGBATask=function(opt_options) { + this.x=opt_options.x; + this.y=opt_options.y; + if (opt_options.output) + this.output=opt_options.output; + +} + +GetPixelRGBATask.prototype.process=function(imageData) { + var pos=(this.y*imageData.width+this.x)<<2; + var r=imageData.data[pos]; + var g=imageData.data[pos+1]; + var b=imageData.data[pos+2]; + var a=imageData.data[pos+3]; + + if (this.output) { + this.output.innerHTML=this.x+"x"+this.y+" : "; + this.output.innerHTML+="<font color='red'>"+r+"</font> | "; + this.output.innerHTML+="<font color='green'>"+g+"</font> | "; + this.output.innerHTML+="<font color='blue'>"+b+"</font> | "; + this.output.innerHTML+="<font color='gray'>"+a+"</font>"; + } + return [r,g,b,a]; +} + +GetMeanPixelRGBATask=function(opt_options) { + if (opt_options && opt_option.output_id) + this.output=document.getElementById(opt_options.output_id); +} + +GetMeanPixelRGBATask.prototype.process=function(imageData) { + if (imageData.width==0) + return; + + var mean=pixels_features.computeRGBMeanPixel(imageData); + if (this.output) { + this.output.style="background-color:rgb("+mean[0]+","+mean[1]+","+mean[2]+")"; + this.output.innerHTML="{r:"+mean[0]+";"; + this.output.innerHTML+="g:"+mean[1]+";"; + this.output.innerHTML+="b:"+mean[2]+"}"; + } + return mean; +} diff --git a/processing2.js b/processing2.js new file mode 100644 index 0000000000000000000000000000000000000000..eba599fefdcc55278cb3fcaa1b54f5d1fc3c06dc --- /dev/null +++ b/processing2.js @@ -0,0 +1,89 @@ +var processing2=function(elementId,task,outputCanvasId,opt_options) { + + + this.element=document.getElementById(elementId); + this.width = this.element.width; + this.height = this.element.height; + + this.in_imageData = {}; + this.out_imageData = {}; + + this.processing_canvas=document.createElement('canvas'); + this.processing_canvas.width = this.width; + this.processing_canvas.height = this.height; + + this.processing_context=this.processing_canvas.getContext("2d"); + + this.task=task; + + + + if (opt_options && opt_options.in_region) + this.in_region=opt_options.in_region + else + this.in_region={x:0,y:0,width:this.width,height:this.height} + + if (outputCanvasId) { + this.output_canvas=document.getElementById(outputCanvasId); + this.output_context=this.output_canvas.getContext("2d"); + + if (opt_options && opt_options.out_region) + this.out_region=opt_options.out_region + else + this.out_region={x:0,y:0,width:this.output_canvas.width,height:this.output_canvas.height} + } + this.result={} +} + +processing2.prototype.acquire_data_from_img=function() { + this.processing_context.drawImage(this.element,0,0,this.width,this.height); + this.in_imageData = this.processing_context.getImageData(0, 0, this.width, this.height); +} + +processing2.prototype.acquire_data_from_video=function() { + this.processing_context.drawImage(this.element,0,0,this.width,this.height); + this.in_imageData = this.processing_context.getImageData(0, 0, this.width, this.height); +} + +processing2.prototype.acquire_data_from_canvas=function() { + this.processing_context.drawImage(this.element,0,0,this.width,this.height); + this.in_imageData = this.processing_context.getImageData(this.in_region.x, this.in_region.y, this.in_region.width, this.in_region.height); +} + +processing2.prototype.acquire_data=function() { + if (this.output_canvas) + this.out_imageData=this.output_context.getImageData(this.out_region.x,this.out_region.y,this.out_region.width,this.out_region.height); + + switch (this.element.nodeName.toLowerCase()) { + case 'canvas': + this.acquire_data_from_canvas(); break; + case 'img': + this.acquire_data_from_img(); break; + case 'video': + this.acquire_data_from_video(); break; + default: + throw new Error('Element not supported!'); + } +} + +processing2.prototype.do_process=function() { + this.acquire_data(); + this.result=this.task.process(this.in_imageData,this.out_imageData); + if (this.output_canvas) this.update_output(); +} + +processing2.prototype.update_output=function() { + this.output_context.putImageData(this.out_imageData,this.out_region.x,this.out_region.y); +} + +processing2.prototype.get_result=function() { + return this.result; +} + +processing2.prototype.get_processing_canvas=function() { + return this.processing_canvas; +} + +processing2.prototype.get_in_imageData=function() { + return this.in_imageData; +} diff --git a/samples/lookup_template.html b/samples/lookup_template.html new file mode 100644 index 0000000000000000000000000000000000000000..09393ee519e7411fe9808a3b2110884ed73ca205 --- /dev/null +++ b/samples/lookup_template.html @@ -0,0 +1,24 @@ +<html> +<head> + <script lang="js" src="../tools.js"></script> + <script lang="js" src="../features/generic.js"></script> + <script lang="js" src="../features/pixels.js"></script> + <script lang="js" src="../metrics/generic.js"></script> + <script lang="js" src="../metrics/pixels.js"></script> + <script lang="js" src="../dataset/images.js"></script> + <script lang="js" src="../similarity/generic.js"></script> + <script lang="js" src="../similarity/pixels.js"></script> + <script lang="js" src="../lookup/windows.js"></script> +</head> +<body> +<img width="84" height="84" id='input1' src='../data/I1.png'></img> +<img width="32" height="32" id='model' src='../data/red.png'></img> +<div id="res"></div> +<script lang="javascript"> +var task=[]; + +_task=new lookup_windows.MeanRGBSameSizeTemplate('model',10); +console.log(_task.process(Tools.get_imageData_from_imgEltId('input1'))); + +</script> +</body></html> diff --git a/samples/photo_fill_pixels.html b/samples/photo_fill_pixels.html new file mode 100644 index 0000000000000000000000000000000000000000..eb0cbff19fc52f2facdcaae38cebc002fdc9fb18 --- /dev/null +++ b/samples/photo_fill_pixels.html @@ -0,0 +1,52 @@ +<html> +<head> + <script lang="js" src="../tools.js"></script> + <script lang="js" src="../dataset/images.js"></script> + <script lang="js" src="../features/generic.js"></script> + <script lang="js" src="../features/pixels.js"></script> + <script lang="js" src="../metrics/generic.js"></script> + <script lang="js" src="../metrics/pixels.js"></script> + <script lang="js" src="../similarity/generic.js"></script> + <script lang="js" src="../similarity/pixels.js"></script> + <script lang="js" src="../effects/photo_fill.js"></script> + <script lang="js" src="../processing2.js"></script> +</head> +<body> +<img width="16" height="16" id='input1' src='../data/16_02.JPG'></img> +<img width="16" height="16" id='input2' src='../data/16_03.JPG'></img> +<img width="16" height="16" id='input3' src='../data/16_04.JPG'></img> +<img width="16" height="16" id='input4' src='../data/16_05.JPG'></img> +<img width="16" height="16" id='input5' src='../data/16_06.JPG'></img> +<img width="16" height="16" id='input6' src='../data/16_07.JPG'></img> +<img width="16" height="16" id='input7' src='../data/16_08.JPG'></img> +<img width="16" height="16" id='input8' src='../data/16_09.JPG'></img> +<img width="16" height="16" id='input9' src='../data/16_10.JPG'></img> +<img width="16" height="16" id='input10' src='../data/16_11.JPG'></img> +<img width="16" height="16" id='input11' src='../data/16_12.JPG'></img> +<img width="16" height="16" id='input12' src='../data/16_13.JPG'></img> +<br></br> +<img id="img0" src="../data/ii2d.png" width="40" height="20"></img> +<br></br> +<img id="big0" src="../data/ii2d.png" width="640" height="320"></img> +<canvas id="output0" width="640" height="320"></canvas> +<br></br> +<img id="img1" src="../data/16_02.jpg" width="40" height="20"></img> +<br></br> +<img id="big1" src="../data/16_02.jpg" width="640" height="320"></img> +<canvas id="output1" width="640" height="320"></canvas> + +<script lang="javascript"> +var proc=[],task=[],inputs=[]; +for (var i=1;i<13;i++) inputs[i]="input"+i; + +_dataset=new datasets.ImageDataset(inputs); +_task=new photo_fill.PhotoFillPixelsFromDatasetTask(_dataset,{}); + +proc=new processing2("img0",_task,"output0"); +proc.do_process(); + +proc=new processing2("img1",_task,"output1"); +proc.do_process(); + +</script> +</body></html> diff --git a/samples/similarity_image.html b/samples/similarity_image.html new file mode 100644 index 0000000000000000000000000000000000000000..88f6e85d46e1c195301166004a73c053ea6f8dfd --- /dev/null +++ b/samples/similarity_image.html @@ -0,0 +1,47 @@ +<html> +<head> + <script lang="js" src="../tools.js"></script> + <script lang="js" src="../features/generic.js"></script> + <script lang="js" src="../features/pixels.js"></script> + <script lang="js" src="../metrics/generic.js"></script> + <script lang="js" src="../metrics/pixels.js"></script> + <script lang="js" src="../dataset/images.js"></script> + <script lang="js" src="../similarity/generic.js"></script> + <script lang="js" src="../similarity/pixels.js"></script> +</head> +<body> +<img border="1" width="32" height="32" id='input1' src='../data/I1.png'></img> +<img border="1" width="32" height="32" id='input2' src='../data/I2.png'></img> +<img border="1" width="32" height="32" id='input3' src='../data/I3.png'></img> +<img border="1" width="32" height="32" id='input4' src='../data/I4.png'></img> +<img border="1" width="32" height="32" id='input5' src='../data/I5.png'></img> +<img border="1" width="32" height="32" id='input6' src='../data/I6.png'></img> +<img border="1" width="32" height="32" id='input7' src='../data/I7.png'></img> +<img border="1" width="32" height="32" id='input8' src='../data/I8.png'></img> +<div id="res"></div> +<script lang="javascript"> +var inputs=[]; +for (var i=1;i<9;i++) inputs[i]="input"+i; +_dataset=new datasets.ImageDataset(inputs); + +_task=new pixels_similarity.MeanRGBSimilarityTask(_dataset,{ + desc_opt_options:{}, + metric_opt_options:{} +}); + +imgData=_dataset.imageDatas[1]; +document.getElementById("res").appendChild( + Tools.create_canvasElt_from_imageData(imgData)); +document.getElementById("res").appendChild(document.createElement("br")); + +res=_task.process(imgData); +console.log("for image id : "+imgData.orig_id); +for (var j=1;j<6;j++) { + console.log(res[j]); + document.getElementById("res").appendChild( + Tools.create_canvasElt_from_imageData(_dataset.imageDatas[res[j].idx])); +} +document.getElementById("res").appendChild(document.createElement("br")); + +</script> +</body></html> diff --git a/samples/similarity_image_grid.html b/samples/similarity_image_grid.html new file mode 100644 index 0000000000000000000000000000000000000000..73147630567384c64b75adebff349a8c6a1ebf98 --- /dev/null +++ b/samples/similarity_image_grid.html @@ -0,0 +1,47 @@ +<html> +<head> + <script lang="js" src="../tools.js"></script> + <script lang="js" src="../features/generic.js"></script> + <script lang="js" src="../features/pixels.js"></script> + <script lang="js" src="../metrics/generic.js"></script> + <script lang="js" src="../metrics/pixels.js"></script> + <script lang="js" src="../dataset/images.js"></script> + <script lang="js" src="../similarity/generic.js"></script> + <script lang="js" src="../similarity/pixels.js"></script> +</head> +<body> +<img border="1" width="32" height="32" id='input1' src='../data/I1.png'></img> +<img border="1" width="32" height="32" id='input2' src='../data/I2.png'></img> +<img border="1" width="32" height="32" id='input3' src='../data/I3.png'></img> +<img border="1" width="32" height="32" id='input4' src='../data/I4.png'></img> +<img border="1" width="32" height="32" id='input5' src='../data/I5.png'></img> +<img border="1" width="32" height="32" id='input6' src='../data/I6.png'></img> +<img border="1" width="32" height="32" id='input7' src='../data/I7.png'></img> +<img border="1" width="32" height="32" id='input8' src='../data/I8.png'></img> +<div id="res"></div> +<script lang="javascript"> +var inputs=[]; +for (var i=1;i<9;i++) inputs[i]="input"+i; +_dataset=new datasets.ImageDataset(inputs); + +_task=new pixels_similarity.GridMeanRGBSimilarityTask(_dataset,{ + desc_opt_options:{nb_lines:2,nb_columns:2}, + metric_opt_options:{} +}); + +imgData=_dataset.imageDatas[1]; +document.getElementById("res").appendChild( + Tools.create_canvasElt_from_imageData(imgData)); +document.getElementById("res").appendChild(document.createElement("br")); + +res=_task.process(imgData); +console.log("for image id : "+imgData.orig_id); +for (var j=1;j<6;j++) { + console.log(res[j]); + document.getElementById("res").appendChild( + Tools.create_canvasElt_from_imageData(_dataset.imageDatas[res[j].idx])); +} +document.getElementById("res").appendChild(document.createElement("br")); + +</script> +</body></html> diff --git a/samples/similarity_images_1.html b/samples/similarity_images_1.html new file mode 100644 index 0000000000000000000000000000000000000000..d93fd529563d08dd051717be6aac71e677bbb023 --- /dev/null +++ b/samples/similarity_images_1.html @@ -0,0 +1,69 @@ +<html> +<head> + <script lang="js" src="../tools.js"></script> + <script lang="js" src="../features/generic.js"></script> + <script lang="js" src="../features/pixels.js"></script> + <script lang="js" src="../metrics/generic.js"></script> + <script lang="js" src="../metrics/pixels.js"></script> + <script lang="js" src="../dataset/images.js"></script> + <script lang="js" src="../similarity/generic.js"></script> + <script lang="js" src="../similarity/pixels.js"></script> +</head> +<body> +<img width="32" height="32" id='input1' src='../data/I1.png'></img> +<img width="32" height="32" id='input2' src='../data/I2.png'></img> +<img width="32" height="32" id='input3' src='../data/I3.png'></img> +<img width="32" height="32" id='input4' src='../data/I4.png'></img> +<img width="32" height="32" id='input5' src='../data/I5.png'></img> +<img width="32" height="32" id='input6' src='../data/I6.png'></img> +<img width="32" height="32" id='input7' src='../data/I7.png'></img> +<img width="32" height="32" id='input8' src='../data/I8.png'></img> +<div id="res"></div> +<script lang="javascript"> +var task=[],inputs=[]; +for (var i=1;i<9;i++) inputs[i]="input"+i; +_dataset=new datasets.ImageDataset(inputs); + +_task=new pixels_similarity.MeanRGBSimilarityTask(_dataset,{ + desc_opt_options:{}, + metric_opt_options:{} +}); + +_task_grid_1x2=new pixels_similarity.GridMeanRGBSimilarityTask(_dataset,{ + dataset_image_ids:inputs, + desc_opt_options:{nb_columns:1,nb_lines:2}, + metric_opt_options:{} +}); + +_task_grid_2x1=new pixels_similarity.GridMeanRGBSimilarityTask(_dataset,{ + dataset_image_ids:inputs, + desc_opt_options:{nb_columns:2,nb_lines:1}, + metric_opt_options:{} +}); + +_task_grid_2x2=new pixels_similarity.GridMeanRGBSimilarityTask(_dataset,{ + dataset_image_ids:inputs, + desc_opt_options:{nb_columns:2,nb_lines:2}, + metric_opt_options:{} +}); + +_tasks=[_task,_task_grid_1x2,_task_grid_2x1,_task_grid_2x2]; + +for (var i=1;i<8;i++) { + imgData=_dataset.imageDatas[i]; + document.getElementById("res").appendChild(Tools.create_canvasElt_from_imageData(imgData)); + document.getElementById("res").appendChild(document.createElement("br")); + for (var taskid in _tasks) { + res=_tasks[taskid].process(imgData); + console.log("for image id : "+imgData.orig_id+" and task id : "+taskid); + for (var j=1;j<6;j++) { + console.log(res[j]); + document.getElementById("res").appendChild(Tools.create_canvasElt_from_imageData(_dataset.imageDatas[res[j].idx])); + } + document.getElementById("res").appendChild(document.createElement("br")); + } + document.getElementById("res").appendChild(document.createElement("hr")); +} + +</script> +</body></html> diff --git a/samples/similarity_images_2.html b/samples/similarity_images_2.html new file mode 100644 index 0000000000000000000000000000000000000000..a8190c003e87f76b46c7eefb42a7a6db1b367274 --- /dev/null +++ b/samples/similarity_images_2.html @@ -0,0 +1,59 @@ +<html> +<head> + <script lang="js" src="../tools.js"></script> + <script lang="js" src="../features/generic.js"></script> + <script lang="js" src="../features/pixels.js"></script> + <script lang="js" src="../metrics/generic.js"></script> + <script lang="js" src="../metrics/pixels.js"></script> + <script lang="js" src="../dataset/images.js"></script> + <script lang="js" src="../similarity/generic.js"></script> + <script lang="js" src="../similarity/pixels.js"></script> +</head> +<body> +<img width="16" height="16" id='input1' src='../data/16_02.JPG'></img> +<img width="16" height="16" id='input2' src='../data/16_03.JPG'></img> +<img width="16" height="16" id='input3' src='../data/16_04.JPG'></img> +<img width="16" height="16" id='input4' src='../data/16_05.JPG'></img> +<img width="16" height="16" id='input5' src='../data/16_06.JPG'></img> +<img width="16" height="16" id='input6' src='../data/16_07.JPG'></img> +<img width="16" height="16" id='input7' src='../data/16_08.JPG'></img> +<img width="16" height="16" id='input8' src='../data/16_09.JPG'></img> +<img width="16" height="16" id='input9' src='../data/16_10.JPG'></img> +<img width="16" height="16" id='input10' src='../data/16_11.JPG'></img> +<img width="16" height="16" id='input11' src='../data/16_12.JPG'></img> +<img width="16" height="16" id='input12' src='../data/16_13.JPG'></img> +<div id="res"></div> +<script lang="javascript"> +var task=[],inputs=[]; +for (var i=1;i<13;i++) inputs[i]="input"+i; +_dataset=new datasets.ImageDataset(inputs); + +_task=new pixels_similarity.MeanRGBSimilarityTask(_dataset,{ + desc_opt_options:{}, + metric_opt_options:{} +}); + +_task_grid=new pixels_similarity.GridMeanRGBSimilarityTask(_dataset,{ + desc_opt_options:{nb_columns:2,nb_lines:2}, + metric_opt_options:{} +}); + +for (var i=1;i<13;i++) { + imgData=_dataset.imageDatas[i]; + document.getElementById("res").appendChild(Tools.create_canvasElt_from_imageData(imgData)); + document.getElementById("res").appendChild(document.createElement("br")); + res=_task.process(imgData); + for (var j=1;j<6;j++) { + document.getElementById("res").appendChild(Tools.create_canvasElt_from_imageData(_dataset.imageDatas[res[j].idx])); + } + document.getElementById("res").appendChild(document.createElement("br")); + + res=_task_grid.process(imgData); + for (var j=1;j<6;j++) { + document.getElementById("res").appendChild(Tools.create_canvasElt_from_imageData(_dataset.imageDatas[res[j].idx])); + } + document.getElementById("res").appendChild(document.createElement("hr")); +} + +</script> +</body></html> diff --git a/similarity/generic.js b/similarity/generic.js new file mode 100644 index 0000000000000000000000000000000000000000..beec1ff77af01f864715e6317055ce6f013938b2 --- /dev/null +++ b/similarity/generic.js @@ -0,0 +1,48 @@ +var generic_similarity={} + +generic_similarity.SimilarityTask= + function(dataset, descriptor_func,similarity_metric_func, opt_options){ + + this.dataset=dataset; + + this.descriptor_func=descriptor_func; + this.desc_opt_options=opt_options.desc_opt_options; + + this.dataset_descriptors=[]; + for (var idx in this.dataset.imageDatas) { + this.dataset_descriptors[idx]= + this.descriptor_func(this.dataset.imageDatas[idx],this.desc_opt_options); + console.log(this.dataset_descriptors[idx]); + } + + this.similarity_metric_func=similarity_metric_func; + this.similarity_metric_opt_options=opt_options.similarity_metric_opt_options; +} + +generic_similarity.SimilarityTask.prototype.process_descriptor=function(in_descriptor) +{ + var sim=[],order=[]; + for (var idx in this.dataset_descriptors) { + sim[idx]=this.similarity_metric_func( + in_descriptor,this.dataset_descriptors[idx],this.metric_opt_options); + order[idx]=idx; + } + for (var idx1 in order) + for (var idx2 in order) + if (sim[order[idx1]]<sim[order[idx2]]) + { aux=order[idx1]; order[idx1]=order[idx2]; order[idx2]=aux; } + + var res=[]; + for (var idx in order) res[idx]={idx:order[idx],sim:sim[order[idx]]} + return res; +} + +generic_similarity.SimilarityTask.prototype.process=function(in_imageData){ + var in_descriptor=this.descriptor_func(in_imageData,this.desc_opt_options); + return this.process_descriptor(in_descriptor); +} + + +generic_similarity.SimilarityTask.prototype.get_dataset_descriptor=function(idx) { + return this.dataset_descriptors[idx]; +} diff --git a/similarity/pixels.js b/similarity/pixels.js new file mode 100644 index 0000000000000000000000000000000000000000..4ea46054ae40a57436e20e2e7f76669fa01a3dd6 --- /dev/null +++ b/similarity/pixels.js @@ -0,0 +1,19 @@ +var pixels_similarity={} + +pixels_similarity.MeanRGBSimilarityTask=function(dataset,opt_options) { + this.__proto__.__proto__=new generic_similarity.SimilarityTask( + dataset, + pixels_features.mean_rgb, + pixel_metrics.rgb_edist, + opt_options + ); +} + +pixels_similarity.GridMeanRGBSimilarityTask=function(dataset,opt_options){ + this.__proto__.__proto__=new generic_similarity.SimilarityTask( + dataset, + pixels_features.grid_mean_rgb, + pixel_metrics.grid_rgb_edist, + opt_options + ); +} diff --git a/tools.js b/tools.js index e51ccca06f6d8344278dd68a61e6cb15a3c0724b..40860ad494c3a8c5dc8e81e5e3fe97ed2b1ae75a 100644 --- a/tools.js +++ b/tools.js @@ -1,15 +1,72 @@ -var tools=function(){ - this.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || - navigator.mozGetUserMedia || navigator.msGetUserMedia; -} +var Tools={} -tools.prototype.initUserMedia=function(element,opt_options) { +Tools.init_user_media=function(element,opt_options) { window.navigator.mediaDevices.getUserMedia({ video: true, audio: (opt_options && opt_options.audio) ? true : false, }).then(function(stream) { - element.srcObject = stream; + element.inObject = stream; }).catch(function(err) { throw Error('Cannot capture user camera.'); }); } + +Tools.get_imageData_from_imgEltId=function(img_elt_id) { + return Tools.get_partial_imageData_from_imgEltId(img_elt_id); +} + +Tools.get_partial_imageData_from_imgEltId=function(img_elt_id,x=0,y=0,dx=undefined,dy=undefined) { + var img=document.getElementById(img_elt_id); + if (!dx) dx=img.width-x; + if (!dy) dy=img.height-y; + var cvs=document.createElement("canvas"); + cvs.width=dx;cvs.height=dy; + var ctxt=cvs.getContext("2d"); + ctxt.drawImage(img,x,y,dx,dy); + var imageData=ctxt.getImageData(0,0,dx,dy); + imageData.ctxt=ctxt; + imageData.orig_id=img_elt_id + imageData.orig_x=x; + imageData.orig_y=y; + return imageData; +} + +Tools.create_canvasElt_from_imageData=function(imageData) { + var cvs_elt=document.createElement("canvas"); + cvs_elt.width=imageData.width; + cvs_elt.height=imageData.height; + cvs_elt.style="border:1px solid #000000"; + cvs_elt.alt=imageData.orig_id; + Tools.update_canvasElt_from_imageData(cvs_elt,imageData) + return cvs_elt; +} + +Tools.update_canvasElt_from_imageData=function(cvs_elt,imageData,x=0,y=0) { + var ctxt=cvs_elt.getContext("2d"); + ctxt.putImageData(imageData,x,y); +} + +Tools.copy_imageData_into_imageData=function(src_imageData,dest_imageData,x0,y0) { + var w_src=0; + for (var src_y=0; src_y<src_imageData.height; src_y++) + for (var src_x=0; src_x < src_imageData.width; src_x++) { + w_out=(y0+src_y)*dest_imageData.width+(x0+src_x)<<2; + dest_imageData.data[w_out]=src_imageData.data[w_src]; + dest_imageData.data[w_out+1]=src_imageData.data[w_src+1]; + dest_imageData.data[w_out+2]=src_imageData.data[w_src+2]; + dest_imageData.data[w_out+3]=src_imageData.data[w_src+3]; + w_src+=4 + } +} + +Tools.get_region_from_imageData=function(src_imageData,x0,y0,dx,dy) { + var reg_imageData=src_imageData.ctxt.getImageData( + src_imageData.orig_x+x0,src_imageData.orig_y+y0, + dx,dy); + reg_imageData.orig_x=src_imageData.orig_x+x0; + reg_imageData.orig_y=src_imageData.orig_y+x0; + reg_imageData.ctxt = src_imageData.ctxt; + reg_imageData.orig_id = src_imageData.orig_id; + + return reg_imageData; +}