Skip to content

Instantly share code, notes, and snippets.

@k3ntar0
Last active July 18, 2024 04:24
Show Gist options
  • Save k3ntar0/f86b2d0f64ed459aedad32aa53d7dd56 to your computer and use it in GitHub Desktop.
Save k3ntar0/f86b2d0f64ed459aedad32aa53d7dd56 to your computer and use it in GitHub Desktop.
Claude 3.5 Sonnetで生成した物体検出アプリケーション
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Realtime Object Detection</title>
<style>
body { font-family: Arial, sans-serif; }
#canvas { border: 1px solid #000; }
table { border-collapse: collapse; margin-top: 20px; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
</style>
</head>
<body>
<h1>Realtime Object Detection</h1>
<canvas id="canvas" width="640" height="480"></canvas>
<table id="detectionTable">
<thead>
<tr>
<th width="100">検出物体</th>
<th width="100">確率</th>
</tr>
</thead>
<tbody></tbody>
</table>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"></script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/coco-ssd"></script>
<script>
const video = document.createElement('video');
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const detectionTableBody = document.querySelector('#detectionTable tbody');
const FPS = 30; // フレーム数
const FRAME_INTERVAL = 1000 / FPS;
async function setupCamera() {
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
video.srcObject = stream;
return new Promise((resolve) => {
video.onloadedmetadata = () => {
video.play();
resolve(video);
};
});
}
function drawPredictions(predictions) {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.drawImage(video, 0, 0, ctx.canvas.width, ctx.canvas.height);
predictions.forEach(prediction => {
const [x, y, width, height] = prediction.bbox;
ctx.strokeStyle = '#00F12F';
ctx.lineWidth = 4;
ctx.strokeRect(x, y, width, height);
ctx.fillStyle = '#00F12F';
ctx.font = '18px Arial';
ctx.fillText(`${prediction.class} ${(prediction.score * 100).toFixed(2)}%`, x, y > 10 ? y - 5 : 10);
});
}
function updateDetectionTable(predictions) {
detectionTableBody.innerHTML = '';
predictions.forEach(prediction => {
const row = detectionTableBody.insertRow();
const cellObject = row.insertCell(0);
const cellProbability = row.insertCell(1);
cellObject.textContent = prediction.class;
cellProbability.textContent = `${(prediction.score * 100).toFixed(2)}%`;
});
}
async function detectObjects() {
const model = await cocoSsd.load();
let lastDetectionTime = 0;
async function detectFrame(currentTime) {
if (currentTime - lastDetectionTime >= FRAME_INTERVAL) {
const predictions = await model.detect(video);
drawPredictions(predictions);
updateDetectionTable(predictions);
lastDetectionTime = currentTime;
}
requestAnimationFrame(detectFrame);
}
requestAnimationFrame(detectFrame);
}
(async function() {
await setupCamera();
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
await detectObjects();
})();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment