Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automated image matching and stitching using matcher-core library #312

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
node_modules
coverage
todo.txt
*.swp
*.swo
package-lock.json
bower_components
.vscode
node_modules
1 change: 1 addition & 0 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ module.exports = function(grunt) {
warpWebGl: false,
EXIF: false,
alert: false,
processedPoints: false,

// Mocha

Expand Down
27 changes: 27 additions & 0 deletions dist/leaflet.distortableimage.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
body {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have started using more specific css selectors in our library so they don't overwrite anything downstream. see #330

margin:0;
background-color: darkgreen;
overflow: hidden;
}

#imgcontainer {
position:relative;
width: 100%;
Expand Down Expand Up @@ -49,6 +55,7 @@ img.leaflet-image-layer.selected {
font-weight: 400;
letter-spacing: 0.5px;
line-height: 1.2;
border-radius: 5px;
}

.l-container table th{
Expand Down Expand Up @@ -89,3 +96,23 @@ span {
letter-spacing: 1.2px;
}

.loader-container {
width: 100px;
height: 100vh;
margin-top:30vh;
}

#matcher-button {
position: absolute;
bottom: 20px;
left: 20px;
background-color: rgba(255, 255, 255, .6);
border: none;
font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
color: black;
cursor: pointer;
z-index: 500;
border-radius: 5px;
padding: 5px;
font-weight: bold;
}
37 changes: 30 additions & 7 deletions dist/leaflet.distortableimage.js
Original file line number Diff line number Diff line change
Expand Up @@ -1040,6 +1040,27 @@ var EditOverlayAction = LeafletToolbar.ToolbarAction.extend({
LeafletToolbar.ToolbarAction.prototype.initialize.call(this, options);
}
}),
// make one for initializing matcher also
Stitcher = EditOverlayAction.extend({
options: {
toolbarIcon: {
html: '<span class="fa fa-puzzle-piece"><span>',
tooltip: 'Enable stitcher'
}
},

addHooks: function() {
var map = this._map;
var overlay = this._overlay;
try {
stitcher(processedPoints, overlay, map); // jshint ignore:line
} catch(err) {
console.error('err: check if matcher is initialized properly and correct parameters are supplied \n', err);
}
map.setView(overlay.getCorner(2), 13);
this.disable();
}
}),

ToggleTransparency = EditOverlayAction.extend({
options: { toolbarIcon: {
Expand Down Expand Up @@ -1186,7 +1207,8 @@ L.DistortableImage.EditToolbar = LeafletToolbar.Popup.extend({
ToggleRotateScale,
ToggleExport,
EnableEXIF,
ToggleOrder
ToggleOrder,
Stitcher
]
},

Expand Down Expand Up @@ -1310,29 +1332,29 @@ L.DistortableImage.Edit = L.Handler.extend({
var overlay = this._overlay,
i;

this._lockHandles = new L.LayerGroup();
this._lockHandles = L.layerGroup();
for (i = 0; i < 4; i++) {
this._lockHandles.addLayer(
new L.LockHandle(overlay, i, { draggable: false })
);
}

this._distortHandles = new L.LayerGroup();
this._distortHandles = L.layerGroup();
for (i = 0; i < 4; i++) {
this._distortHandles.addLayer(new L.DistortHandle(overlay, i));
}

this._rotateHandles = new L.LayerGroup(); // individual rotate
this._rotateHandles = L.layerGroup(); // individual rotate
for (i = 0; i < 4; i++) {
this._rotateHandles.addLayer(new L.RotateHandle(overlay, i));
}

this._scaleHandles = new L.LayerGroup();
this._scaleHandles = L.layerGroup();
for (i = 0; i < 4; i++) {
this._scaleHandles.addLayer(new L.ScaleHandle(overlay, i));
}

this._rotateScaleHandles = new L.LayerGroup(); // handle includes rotate AND scale
this._rotateScaleHandles = L.layerGroup(); // handle includes rotate AND scale
for (i = 0; i < 4; i++) {
this._rotateScaleHandles.addLayer(new L.RotateScaleHandle(overlay, i));
}
Expand Down Expand Up @@ -1780,7 +1802,8 @@ L.DistortableImage.Keymapper = L.Control.extend({
"</tbody></table>";
return el_wrapper;
}
});
});

L.Map.mergeOptions({ boxSelector: true, boxZoom: false });

// used for multiple image select. Temporarily disabled until click
Expand Down
Binary file added examples/dot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
211 changes: 104 additions & 107 deletions examples/index.html
Original file line number Diff line number Diff line change
@@ -1,121 +1,118 @@
<!DOCTYPE html>
<html>
<head>
<title>Leaflet.DistortableImage Example</title>
<meta charset="utf-8" />

<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<head>
<title>Leaflet.DistortableImage Example</title>
<meta charset="utf-8" />

<script
src="../node_modules/leaflet/dist/leaflet.js"
type="text/javascript"
charset="utf-8"
></script>
<link
href="../node_modules/font-awesome/css/font-awesome.min.css"
rel="stylesheet"
/>
<link
rel="stylesheet"
href="../node_modules/leaflet/dist/leaflet.css"
type="text/css"
media="screen"
title="no title"
charset="utf-8"
/>
<script src="../node_modules/leaflet-toolbar/dist/leaflet.toolbar.js"></script>
<link
href="../node_modules/leaflet-toolbar/dist/leaflet.toolbar.css"
rel="stylesheet"
/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<!-- for full-res export -->
<script src="../node_modules/jquery/dist/jquery.js"></script>
<script src="../node_modules/webgl-distort/dist/webgl-distort.js"></script>
<script src="../node_modules/glfx/glfx.js"></script>
<script src="../node_modules/leaflet/dist/leaflet.js" type="text/javascript" charset="utf-8"></script>
<link href="../node_modules/font-awesome/css/font-awesome.min.css" rel="stylesheet" />
<link rel="stylesheet" href="../node_modules/leaflet/dist/leaflet.css" type="text/css" media="screen" title="no title"
charset="utf-8" />
<script src="../node_modules/leaflet-toolbar/dist/leaflet.toolbar.js"></script>
<link href="../node_modules/leaflet-toolbar/dist/leaflet.toolbar.css" rel="stylesheet" />
<!-- for pattern-mining utility -->
<script src="../node_modules/matcher-core/orb.core.com.js"></script>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we ought to move this to a unique example file called "matcher"?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rexagod i think we'd better follow up on this, matcher.html sounds like a good name for the example!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, on it! 👍

<script src="../src/util/matcher/init_with_matcher.js"></script>
<script src="../src/util/matcher/projector.js"></script>
<script src="../src/util/matcher/stitcher.js"></script>
<script src="../src/util/matcher/init_.js"></script>
<!-- for full-res export -->
<script src="../node_modules/jquery/dist/jquery.js"></script>
<script src="../node_modules/webgl-distort/dist/webgl-distort.js"></script>
<script src="../node_modules/glfx/glfx.js"></script>

<!-- for EXIF geocode -->
<script
type="text/javascript"
src="../node_modules/exif-js/exif.js"
></script>
<!-- for EXIF geocode -->
<script type="text/javascript" src="../node_modules/exif-js/exif.js"></script>

<link
rel="stylesheet"
href="../dist/leaflet.distortableimage.css"
type="text/css"
media="screen"
title="no title"
charset="utf-8"
/>
<script src="../dist/leaflet.distortableimage.js"></script>
</head>
<body style="margin:0;">
<form id="test_form">
<input type="file" id="inputimage" accept="image/*" />
</form>
<link rel="stylesheet" href="../dist/leaflet.distortableimage.css" type="text/css" media="screen" title="no title"
charset="utf-8" />
<script src="../dist/leaflet.distortableimage.js"></script>
</head>

<div
id="map"
style="width:100%; height:100%; position:absolute; top:0;"
></div>
</body>
<script>
var map;
<body>
<center>
<div class="loader-container">
<img width="100" src="leaflet.gif">
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, what is happening while this is showing? The matcher is searching for interest points in some images?

Copy link
Member

@rexagod rexagod Jul 17, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup! But now with the caching implemented, I guess we won't be needing this at all from the second iteration onwards, and the initial iteration should take way lesser loading time (~7000 to ~15 frames perf improvement), so I guess it would be better if we should synchronously process those, and remove this loading screen altogether?

</div>
</center>
<form id="test_form">
<input type="file" id="inputimage" accept="image/*" />
</form>
<div id="map" style="width:100%; height:100%; position:absolute; top:0;"></div>
<button id="matcher-button">Toggle matcher.js</button>
</body>

(function() {
// basic Leaflet map setup
map = L.map("map").setView([51.505, -0.09], 13);
L.tileLayer(
"https://{s}.tiles.mapbox.com/v3/anishshah101.ipm9j6em/{z}/{x}/{y}.png",
{
maxZoom: 18,
attribution:
'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
'<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
'Imagery © <a href="http://mapbox.com">Mapbox</a>',
id: "examples.map-i86knfo3"
}
).addTo(map);
<script>

// create an image
img = L.distortableImageOverlay("example.png", {
// (WIP) add a toolbarType field with values 'popup' (default) or 'control'
// add a keymapper: false <== hides the keymapper
// add a keymapper_position field with combinations of 'top', 'bottom', 'left' or 'right'
// mode: "distort", => default handle
selected: true,
corners: [
L.latLng(51.52, -0.1),
L.latLng(51.52, -0.14),
L.latLng(51.5, -0.1),
L.latLng(51.5, -0.14)
],
fullResolutionSrc: "large.jpg"
}).addTo(map);
paths = ['../node_modules/matcher-core/assets/resources/big.jpg', '../node_modules/matcher-core/assets/resources/small.jpg'];

/* add custom icon functionality */
// refer this snippet below inorder to add a custom functionality
function add() {
var map = L.map("map").setView([51.505, -0.09], 12);
L.tileLayer(
"https://{s}.tiles.mapbox.com/v3/anishshah101.ipm9j6em/{z}/{x}/{y}.png",
{
maxZoom: 18,
id: "examples.map-i86knfo3"
}
).addTo(map);

// var tool = EditOverlayAction.extend({
// options: {
// toolbarIcon: {
// html: '<span class="fa fa-plus-circle"></span>',
// tooltip: "Print a console message!",
// title: "Console logger"
// }
// },
//
// addHooks: function() {
// var editing = this._overlay.editing;
// editing._demonstrator();
// this.disable();
// }
// });
//
// img._addTool(tool);
var img1 = L.distortableImageOverlay(paths[0], {
selected: true,
corners: [
L.latLng(51.52, -0.1),
L.latLng(51.52, -0.14),
L.latLng(51.5, -0.1),
L.latLng(51.5, -0.14)
],
fullResolutionSrc: "large.jpg"
}).addTo(map);

var img2 = L.distortableImageOverlay(paths[1], {
selected: true,
corners: [
L.latLng(51.52, -0.14),
L.latLng(51.52, -0.18),
L.latLng(51.5, -0.14),
L.latLng(51.5, -0.18)
],
fullResolutionSrc: "large.jpg"
}).addTo(map);
var L_img_array = [img1, img2];
for (var y = 0; y < L_img_array.length; y++) {
L.DomEvent.on(L_img_array[y]._image, "load", L_img_array[y].editing.enable, L_img_array[y].editing);
}
return { L_img_array: L_img_array, map: map };
}

(function start() {
if (sessionStorage.getItem('flag')==='true') {
init_with_matcher(add, paths);
} else {
sessionStorage.setItem('flag', 'false');
init_(add);
}
})();

document.getElementById('matcher-button').addEventListener('click', setter);
document.getElementById('matcher-button').addEventListener('mouseover', function(e) {
if(sessionStorage.getItem('flag')==='true') {
e.target.innerHTML = "current state: running";
} else {
e.target.innerHTML = "current state: not initialized";
}
});
document.getElementById('matcher-button').addEventListener('mouseleave', function(e) {
e.target.innerHTML = "Toggle matcher.js";
});

function setter() {
sessionStorage.setItem('flag', (sessionStorage.getItem('flag')==='true'?'false':'true'));
location.reload();
}

</script>

L.DomEvent.on(img._image, "load", img.editing.enable, img.editing);
})();
</script>
</html>
Binary file added examples/leaflet.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading