Skip to content

Instantly share code, notes, and snippets.

@addam
Last active April 8, 2022 11:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save addam/cf93394164d98e811cae7f5c8a3c4990 to your computer and use it in GitHub Desktop.
Save addam/cf93394164d98e811cae7f5c8a3c4990 to your computer and use it in GitHub Desktop.
Webpage for detecting portions of same content in images using Opencv.js and a Bag of Words model
<!doctype html>
<html>
<head>
<meta charset=utf-8>
<title>Classifier</title>
<script>
let descriptors = [];
qs = (sel) => document.querySelector(sel);
cel = (name, parameters={}) => {
const element = document.createElement(name);
for (const param in parameters) {
element[param] = parameters[param];
}
return element;
}
// evaluate the similarity between two point clouds
// enormous robustness against outliers is necessary
score = (a, b) => {
let result = []
for (let i=0; i<a.rows; i++) {
let [best, bestd] = [0, 1/0];
for (let j=0; j<b.rows; j++) {
const d = cv.norm1(a.row(i), b.row(j), cv.NORM_L1);
if (d < bestd) {
best = j;
bestd = d;
}
}
result.push(bestd)
}
// return the sum of 100 smallest distances
result.sort((x, y) => x - y)
return result.slice(0, 100).reduce((x, r)=>x+r)
}
addScoreRow = (desc) => {
const index = descriptors.length
qs("table tr").appendChild(cel("td", {textContent: index}))
const tr = cel("tr")
tr.appendChild(cel("td", {textContent: index}))
for (const other of descriptors) {
const sc = Math.round(score(desc, other))
tr.appendChild(cel("td", {textContent: sc}))
}
qs("table").appendChild(tr)
}
drawKeypoints = (keypoints, mat) => {
const color = new cv.Scalar(1.0, 0.5, 0.0, 0.1);
for (let i=0; i<keypoints.size(); i++) {
const kp = keypoints.get(i);
cv.circle(mat, kp.pt, kp.size, color);
}
cv.imshow(qs("canvas"), mat);
}
imgOnload = (event) => {
const mat = cv.imread(event.target);
while (mat.rows + mat.cols > 1000) {
cv.pyrDown(mat, mat);
}
const detector = new cv.AKAZE();
const result = new cv.Mat();
const keypoints = new cv.KeyPointVector()
detector.detectAndCompute(mat, new cv.Mat(), keypoints, result);
addScoreRow(result);
drawKeypoints(keypoints, mat);
descriptors.push(result);
mat.delete();
}
inputOnchange = (e) => {
qs("img").src = URL.createObjectURL(e.target.files[0]);
}
scriptOnload = () => {
qs("input[type=file]").onchange = inputOnchange;
qs("img").onload = imgOnload;
}
</script>
<script async src="https://docs.opencv.org/4.x/opencv.js" onload="scriptOnload()"></script>
<style>
.hidden {
display: none;
}
.block {
display: block;
}
</style>
</head>
<body>
<img class=hidden>
<input type=file>
<table><tr><td>&delta;</td></tr></table>
<canvas class=block></canvas>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment