Skip to content

Commit 0882b35

Browse files
authored
Add files via upload
1 parent eb7eaf7 commit 0882b35

File tree

1 file changed

+100
-117
lines changed

1 file changed

+100
-117
lines changed

index.html

+100-117
Original file line numberDiff line numberDiff line change
@@ -5,146 +5,129 @@
55
<meta name="viewport" content="width=device-width, initial-scale=1.0">
66
<title>YOLOv8 Object Detection</title>
77
<style>
8-
/* 웹캠 영상과 탐지 결과를 화면에 맞게 표시 */
9-
video {
10-
width: 100%;
11-
max-width: 640px;
12-
display: block;
13-
margin: auto;
8+
#webcam-container {
9+
display: flex;
10+
justify-content: center;
11+
align-items: center;
12+
margin-top: 20px;
1413
}
15-
canvas {
16-
position: absolute;
17-
top: 0;
18-
left: 0;
19-
z-index: 2;
14+
#webcam {
15+
border: 2px solid black;
2016
}
2117
</style>
2218
</head>
2319
<body>
24-
<h1>YOLOv8 Object Detection with WebCam</h1>
25-
26-
<!-- 웹캠 비디오 출력 -->
27-
<video id="videoElement" autoplay playsinline></video>
28-
29-
<!-- 추론을 위한 캔버스 (객체 탐지 결과 표시용) -->
30-
<canvas id="canvas"></canvas>
31-
32-
<!-- 알림 소리 -->
33-
<audio id="alertSound" src="alert_sound.mp3" preload="auto"></audio>
34-
35-
<script src="https://cdn.jsdelivr.net/npm/onnxjs/dist/onnx.min.js"></script>
20+
<h1>YOLOv8 Object Detection</h1>
21+
<div id="webcam-container">
22+
<video id="webcam" width="640" height="480" autoplay></video>
23+
</div>
24+
<script src="https://cdn.jsdelivr.net/npm/onnxruntime-web@latest/dist/onnxruntime-web.min.js"></script>
3625
<script>
37-
// 웹캠 비디오 스트림을 가져오는 함수
38-
async function setupWebcam() {
39-
const video = document.getElementById('videoElement');
40-
const constraints = { video: { facingMode: 'user' } };
41-
42-
// 웹캠 권한 요청
43-
const stream = await navigator.mediaDevices.getUserMedia(constraints);
44-
video.srcObject = stream;
45-
video.play();
46-
}
47-
48-
// 모델 로드 및 추론을 위한 ONNX 세션 생성
49-
const session = new onnx.InferenceSession();
26+
// ONNX model path
27+
const modelPath = 'yolov8_model.onnx'; // Make sure this path is correct
5028

51-
// 모델 파일 경로
52-
const modelPath = 'yolov8_model.onnx'; // 변환한 YOLOv8 모델 파일 경로
29+
// Global variables for sound and state
30+
let alertSound = new Audio('alert_sound.mp3'); // Replace with actual sound file path
31+
let isPlaying = false;
5332

54-
async function loadModel() {
55-
await session.loadModel(modelPath);
56-
console.log("YOLOv8 모델 로드 완료");
57-
}
58-
59-
// 웹캠 비디오를 캔버스에 그리기
60-
const canvas = document.getElementById('canvas');
33+
// Initialize webcam
34+
const video = document.getElementById('webcam');
35+
const canvas = document.createElement('canvas');
6136
const ctx = canvas.getContext('2d');
6237

63-
// 탐지된 객체의 클래스에 따라 박스를 그리는 함수
64-
function drawBoundingBoxes(predictions) {
65-
ctx.clearRect(0, 0, canvas.width, canvas.height);
66-
67-
predictions.forEach(prediction => {
68-
const [x, y, width, height] = prediction.box;
69-
ctx.strokeStyle = 'red';
70-
ctx.lineWidth = 2;
71-
ctx.strokeRect(x, y, width, height);
72-
73-
// 객체 레이블을 박스 위에 출력
74-
ctx.font = '16px Arial';
75-
ctx.fillStyle = 'red';
76-
ctx.fillText(prediction.className, x, y > 10 ? y - 5 : 10);
38+
// Access webcam
39+
navigator.mediaDevices.getUserMedia({ video: true })
40+
.then((stream) => {
41+
video.srcObject = stream;
42+
video.play();
43+
})
44+
.catch((error) => {
45+
console.error('Error accessing webcam:', error);
7746
});
78-
}
7947

80-
// 객체 탐지 및 소리 재생을 위한 함수
81-
async function detectObjects(frame) {
82-
// ONNX.js에서 처리할 수 있도록 텐서로 변환
83-
const inputTensor = new onnx.Tensor(new Float32Array(frame.data), 'float32', [1, 3, frame.height, frame.width]);
48+
// Load ONNX model
49+
let session;
8450

85-
// 모델 추론
86-
const output = await session.run([inputTensor]);
87-
88-
// 추론 결과에서 탐지된 객체들
89-
const boxes = output.values().next().value.data;
90-
91-
// 탐지된 객체를 화면에 그리기
92-
const predictions = parsePredictions(boxes);
93-
drawBoundingBoxes(predictions);
94-
95-
// '담배'가 탐지되었는지 확인하여 소리 재생
96-
const cigaretteDetected = predictions.some(pred => pred.className === 'cigarette');
97-
if (cigaretteDetected) {
98-
document.getElementById('alertSound').play();
51+
async function loadModel() {
52+
try {
53+
session = await ort.InferenceSession.create(modelPath);
54+
console.log("Model loaded successfully");
55+
startDetection();
56+
} catch (err) {
57+
console.error("Error loading model:", err);
9958
}
10059
}
10160

102-
// 추론 결과 파싱 (YOLOv8 모델의 출력 형식에 따라 다를 수 있음)
103-
function parsePredictions(boxes) {
104-
const predictions = [];
105-
for (let i = 0; i < boxes.length; i += 6) {
106-
const classId = boxes[i + 5]; // 클래스 ID (YOLOv8)
107-
const confidence = boxes[i + 4]; // 탐지 확신도
108-
109-
if (confidence > 0.5) { // 확신도가 50% 이상일 경우에만
110-
const box = boxes.slice(i, i + 4); // [x, y, width, height]
111-
const className = getClassName(classId);
112-
predictions.push({ box, className });
113-
}
61+
loadModel();
62+
63+
// Start object detection
64+
async function startDetection() {
65+
canvas.width = video.width;
66+
canvas.height = video.height;
67+
68+
function detectObjects() {
69+
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
70+
let frame = canvas.toDataURL('image/jpeg');
71+
72+
// Convert image data to tensor
73+
let tensor = preprocessImage(frame);
74+
75+
// Run inference
76+
session.run([tensor]).then((output) => {
77+
const boxes = output[0].data; // Adjust according to output format
78+
const confidences = output[1].data; // Adjust according to output format
79+
80+
// Check if cigarette is detected
81+
let cigaretteDetected = false;
82+
83+
// Loop through detections and draw boxes
84+
boxes.forEach((box, index) => {
85+
const confidence = confidences[index];
86+
if (confidence > 0.5) { // Adjust the confidence threshold
87+
const [x, y, width, height] = box;
88+
if (/* check if the class is cigarette */) {
89+
cigaretteDetected = true;
90+
drawBoundingBox(x, y, width, height);
91+
}
92+
}
93+
});
94+
95+
// Play alert sound if cigarette is detected
96+
if (cigaretteDetected && !isPlaying) {
97+
alertSound.play();
98+
isPlaying = true;
99+
} else if (!cigaretteDetected && isPlaying) {
100+
alertSound.pause();
101+
isPlaying = false;
102+
}
103+
104+
requestAnimationFrame(detectObjects);
105+
}).catch((error) => {
106+
console.error("Error during inference:", error);
107+
});
114108
}
115-
return predictions;
116-
}
117109

118-
// 클래스 ID에 해당하는 클래스 이름을 반환
119-
function getClassName(classId) {
120-
const classNames = ['cigarette', 'other_class']; // 모델 학습 시 설정한 클래스 목록
121-
return classNames[classId] || 'Unknown';
110+
detectObjects();
122111
}
123112

124-
// 비디오 프레임 처리 및 탐지 실행
125-
function processFrame() {
126-
const video = document.getElementById('videoElement');
127-
canvas.width = video.videoWidth;
128-
canvas.height = video.videoHeight;
129-
130-
const context = video.getContext('2d');
131-
context.drawImage(video, 0, 0, canvas.width, canvas.height);
132-
133-
// 실시간 객체 탐지
134-
detectObjects(context.getImageData(0, 0, canvas.width, canvas.height));
135-
136-
// 비디오 프레임을 계속해서 처리하도록 설정
137-
requestAnimationFrame(processFrame);
113+
// Preprocess webcam frame and convert to tensor
114+
function preprocessImage(frame) {
115+
// Convert frame to tensor here (resize, normalize, etc.)
116+
// This depends on the expected input format for your model
117+
// Example: You might need to resize the frame, normalize, etc.
118+
let tensor = new ort.Tensor('float32', new Float32Array(frame), [1, 3, 640, 640]); // Adjust the shape as per model requirement
119+
return tensor;
138120
}
139121

140-
// 초기 설정
141-
async function start() {
142-
await loadModel();
143-
await setupWebcam();
144-
processFrame();
122+
// Draw bounding box on canvas
123+
function drawBoundingBox(x, y, width, height) {
124+
ctx.beginPath();
125+
ctx.rect(x, y, width, height);
126+
ctx.lineWidth = 3;
127+
ctx.strokeStyle = 'red';
128+
ctx.fillStyle = 'red';
129+
ctx.stroke();
145130
}
146-
147-
start(); // 실행
148131
</script>
149132
</body>
150133
</html>

0 commit comments

Comments
 (0)