3
3
< head >
4
4
< meta charset ="UTF-8 ">
5
5
< meta name ="viewport " content ="width=device-width, initial-scale=1.0 ">
6
- < title > YOLOv8 Object Detection with Logs </ title >
6
+ < title > YOLOv8 Object Detection with Sound Alert </ title >
7
7
< style >
8
- # webcam-container {
8
+ body {
9
+ font-family : Arial, sans-serif;
10
+ margin : 0 ;
11
+ padding : 0 ;
12
+ background-color : # f4f4f9 ;
9
13
display : flex;
10
14
justify-content : center;
11
15
align-items : center;
12
- margin-top : 20 px ;
16
+ height : 100 vh ;
13
17
}
18
+
19
+ # container {
20
+ position : relative;
21
+ width : 640px ;
22
+ height : 480px ;
23
+ border : 2px solid # ccc ;
24
+ background-color : # fff ;
25
+ }
26
+
14
27
# webcam {
15
- border : 2px solid black;
28
+ width : 100% ;
29
+ height : 100% ;
30
+ object-fit : cover;
31
+ position : absolute;
16
32
}
33
+
34
+ # canvas {
35
+ position : absolute;
36
+ top : 0 ;
37
+ left : 0 ;
38
+ z-index : 10 ;
39
+ pointer-events : none; /* 캔버스가 비디오 위에 있지만 클릭할 수 없도록 설정 */
40
+ }
41
+
17
42
# log {
18
43
margin-top : 20px ;
19
44
padding : 10px ;
20
45
width : 640px ;
21
- height : 150 px ;
22
- border : 2 px solid # 000 ;
23
- overflow-y : scroll ;
24
- background- color: # f0f0f0 ;
46
+ max- height: 200 px ;
47
+ overflow-y : auto ;
48
+ background-color : # 222 ;
49
+ color : # fff ;
25
50
font-family : monospace;
51
+ border-radius : 5px ;
52
+ border : 2px solid # 333 ;
53
+ }
54
+
55
+ h1 {
56
+ text-align : center;
57
+ color : # 333 ;
26
58
}
59
+
27
60
</ style >
28
61
</ head >
29
62
< body >
30
- < h1 > YOLOv8 Object Detection </ h1 >
31
- < div id ="webcam-container " >
32
- < video id ="webcam " width ="640 " height ="480 " autoplay > </ video >
63
+ < div id =" container " >
64
+ < video id ="webcam " autoplay > </ video >
65
+ < canvas id ="canvas " width ="640 " height ="480 "> </ canvas >
33
66
</ div >
34
67
< div id ="log "> </ div > <!-- 로그를 표시할 영역 추가 -->
35
- < script src ="ort.min.js "> </ script > <!-- 로컬 ort.min.js 파일을 로드 -->
68
+
69
+ < script src ="
https://cdn.jsdelivr.net/npm/[email protected] /dist/ort.min.js "
> </ script >
36
70
< script >
37
71
// 전역 변수: 소리, 상태
38
72
let alertSound = new Audio ( 'alert_sound.mp3' ) ; // 알림 소리 파일 경로 수정
39
73
let isPlaying = false ;
40
74
41
75
// 웹캠 초기화
42
76
const video = document . getElementById ( 'webcam' ) ;
43
- const canvas = document . createElement ( 'canvas' ) ;
77
+ const canvas = document . getElementById ( 'canvas' ) ;
44
78
const ctx = canvas . getContext ( '2d' ) ;
45
79
46
80
// 웹캠 권한 요청 및 설정
@@ -78,21 +112,28 @@ <h1>YOLOv8 Object Detection</h1>
78
112
79
113
// 객체 탐지 시작
80
114
async function startDetection ( ) {
81
- canvas . width = video . width ;
82
- canvas . height = video . height ;
83
-
84
115
function detectObjects ( ) {
85
116
ctx . drawImage ( video , 0 , 0 , canvas . width , canvas . height ) ;
86
- let frame = canvas . toDataURL ( 'image/jpeg' ) ;
117
+ let frame = canvas ;
87
118
88
119
// 이미지 데이터를 텐서로 변환
89
120
let tensor = preprocessImage ( frame ) ;
90
121
122
+ // 모델의 입력 이름을 확인 후, feeds 객체에 적절한 값을 추가
123
+ const feeds = { } ;
124
+ feeds [ 'input.1' ] = tensor ; // 입력 이름을 정확하게 확인하고 변경하세요
125
+
91
126
// 추론 실행
92
- session . run ( [ tensor ] ) . then ( ( output ) => {
93
- const boxes = output [ 0 ] . data ; // 박스 데이터
94
- const confidences = output [ 1 ] . data ; // 신뢰도 데이터
95
- const classIds = output [ 2 ] . data ; // 클래스 ID 데이터
127
+ session . run ( feeds ) . then ( ( output ) => {
128
+ // output 객체 출력 (디버깅을 위해 추가)
129
+ console . log ( "Model output:" , output ) ;
130
+
131
+ // output의 구조를 확인한 후 아래와 같이 수정합니다.
132
+ // output[0], output[1], output[2] 등은 실제 모델의 출력 형식에 따라 다를 수 있습니다.
133
+
134
+ const boxes = output [ 0 ] ? output [ 0 ] . data : [ ] ; // 박스 데이터
135
+ const confidences = output [ 1 ] ? output [ 1 ] . data : [ ] ; // 신뢰도 데이터
136
+ const classIds = output [ 2 ] ? output [ 2 ] . data : [ ] ; // 클래스 ID 데이터
96
137
97
138
// 'cigarette'가 탐지된 경우
98
139
let cigaretteDetected = false ;
@@ -132,9 +173,23 @@ <h1>YOLOv8 Object Detection</h1>
132
173
133
174
// 웹캠 이미지 전처리 및 텐서로 변환
134
175
function preprocessImage ( frame ) {
135
- // 이미지 전처리 (크기 조정, 정규화 등)
136
- // 모델에 맞는 텐서 형태로 변환
137
- let tensor = new ort . Tensor ( 'float32' , new Float32Array ( frame ) , [ 1 , 3 , 640 , 640 ] ) ; // 모델의 입력 형식에 맞게 수정 필요
176
+ canvas . width = 640 ;
177
+ canvas . height = 640 ;
178
+ ctx . drawImage ( frame , 0 , 0 , canvas . width , canvas . height ) ;
179
+
180
+ const imageData = ctx . getImageData ( 0 , 0 , canvas . width , canvas . height ) ;
181
+ const data = new Float32Array ( 3 * 640 * 640 ) ;
182
+ let index = 0 ;
183
+
184
+ // RGBA -> RGB로 변환하고 정규화
185
+ for ( let i = 0 ; i < imageData . data . length ; i += 4 ) {
186
+ data [ index ++ ] = imageData . data [ i ] / 255 ; // Red
187
+ data [ index ++ ] = imageData . data [ i + 1 ] / 255 ; // Green
188
+ data [ index ++ ] = imageData . data [ i + 2 ] / 255 ; // Blue
189
+ }
190
+
191
+ // 모델에 맞게 텐서 생성
192
+ const tensor = new ort . Tensor ( 'float32' , data , [ 1 , 3 , 640 , 640 ] ) ;
138
193
return tensor ;
139
194
}
140
195
@@ -146,6 +201,11 @@ <h1>YOLOv8 Object Detection</h1>
146
201
ctx . strokeStyle = 'red' ;
147
202
ctx . fillStyle = 'red' ;
148
203
ctx . stroke ( ) ;
204
+
205
+ // 텍스트 추가: "Cigarette" 또는 클래스명 출력
206
+ ctx . font = "20px Arial" ;
207
+ ctx . fillStyle = "red" ;
208
+ ctx . fillText ( "Cigarette" , x , y - 10 ) ;
149
209
}
150
210
151
211
// 로그 메시지 추가
0 commit comments