2025-12-01 13:42:07 -08:00

131 lines
4.0 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"
/>
<title>Holoprojection Image Comparison</title>
<style>
canvas {
border: 1px solid #ccc;
margin-bottom: 20px;
}
</style>
</head>
<body>
<div id="main-scene-container"></div>
<h2>Rendered image:</h2>
<input type="file" id="renderedImageInput" accept="image/png" />
<br />
<canvas id="renderedImage" width="256" height="256"></canvas>
<h2>Truth image:</h2>
<input type="file" id="truthImageInput" accept="image/png" />
<br />
<canvas id="truthImage" width="256" height="256"></canvas>
<h2>Difference (Pixelmatch):</h2>
<canvas id="diffImage" width="256" height="256"></canvas>
<div id="diffInfo">Images not yet compared.</div>
<script type="importmap">
{
"imports": {
"three": "https://threejs.org/build/three.module.js",
"three/addons/": "https://threejs.org/examples/jsm/"
}
}
</script>
<script type="module">
import pixelmatch from "https://unpkg.com/pixelmatch?module";
const renderedImageInput = document.getElementById("renderedImageInput");
const truthImageInput = document.getElementById("truthImageInput");
const renderedCanvas = document.getElementById("renderedImage");
const truthCanvas = document.getElementById("truthImage");
const diffCanvas = document.getElementById("diffImage");
const diffInfo = document.getElementById("diffInfo");
const width = 256;
const height = 256;
const renderedContext = renderedCanvas.getContext('2d');
const truthContext = truthCanvas.getContext('2d');
const diffContext = diffCanvas.getContext('2d');
let hasRenderedImage = false;
let hasTruthImage = false;
// Helper function to load an image to a canvas
function loadImageToCanvas(file, canvas, callback) {
const reader = new FileReader();
reader.onload = function(e) {
const img = new Image();
img.onload = function() {
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, width, height);
ctx.drawImage(img, 0, 0, width, height);
callback();
};
img.src = e.target.result;
};
reader.readAsDataURL(file);
}
// Run pixelmatch and render diff
function compareImages() {
const img1 = renderedContext.getImageData(0, 0, width, height);
const img2 = truthContext.getImageData(0, 0, width, height);
const diff = diffContext.createImageData(width, height);
const mismatchedPixels = pixelmatch(
img1.data,
img2.data,
diff.data,
width,
height,
{
threshold: 0.1 // adjust for sensitivity
}
);
diffContext.putImageData(diff, 0, 0);
const totalPixels = width * height;
const percentDifference = (mismatchedPixels / totalPixels) * 100;
diffInfo.textContent = `
Mismatched pixels: ${mismatchedPixels}
(${percentDifference.toFixed(2)}% difference)
`;
}
// Set up listeners for file uploads
renderedImageInput.addEventListener('change', (e) => {
const file = e.target.files[0];
if (!file) return;
loadImageToCanvas(file, renderedCanvas, () => {
hasRenderedImage = true;
if (hasTruthImage) compareImages();
});
});
truthImageInput.addEventListener('change', (e) => {
const file = e.target.files[0];
if (!file) return;
loadImageToCanvas(file, truthCanvas, () => {
hasTruthImage = true;
if (hasRenderedImage) compareImages();
});
});
</script>
</body>
</html>