register.html 4.51 KB
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Web Attendance System Register</title>
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Nanum+Gothic:400,700,800&amp;subset=korean">
<style>body,h1,h2,h3,h4,h5 {font-family: "Nanum+Gothic", sans-serif}</style>
<script type='text/javascript' src="{{url_for('static', filename='js/opencv.js')}}"></script>
<script type='text/javascript' src="{{url_for('static', filename='js/utils.js')}}"></script>
<script type='text/javascript' src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script type='text/javascript'>
var tempImage = new Image();
var tempCanvas = document.createElement("canvas");

function load_cascade()
{
    let faceCascadeFile = 'haarcascade_frontalface_default.xml'
    let faceCascadeURL = 'static/js/haarcascade_frontalface_default.xml'
    let utils = new Utils('errorMessage');	
    utils.createFileFromUrl(faceCascadeFile, faceCascadeURL, () => {
        activate();
    });
}
function activate()
{
	let fileloader = document.getElementById("fileloader");
	fileloader.disabled = false;
}

function detect_face()
{
	let canvas = document.createElement('canvas');
	canvas.width = tempImage.width;
	canvas.height = tempImage.height;
	let ctx = canvas.getContext('2d')
	ctx.drawImage(tempImage, 0, 0);
	let src = cv.imread(canvas);
	let dst = new cv.Mat(src.cols, src.rows, cv.CV_8UC4);
	let gray = new cv.Mat();
	let faces = new cv.RectVector();
	let classifier = new cv.CascadeClassifier();
	classifier.load('haarcascade_frontalface_default.xml');
	src.copyTo(dst);
	cv.cvtColor(dst, gray, cv.COLOR_RGBA2GRAY, 0);
	let msize = new cv.Size(120, 120);
	// detect faces.
	classifier.detectMultiScale(gray, faces, 1.1, 3, 0, msize);
	// draw faces.
	for (let i = 0; i < faces.size(); ++i) {
		let face = faces.get(i);
		let point1 = new cv.Point(face.x, face.y);
		let point2 = new cv.Point(face.x + face.width, face.y + face.height);
		cv.rectangle(dst, point1, point2, [255, 0, 0, 255]);
		// margin 44
		let rect = new cv.Rect(Math.max(face.x - 22, 0), Math.max(face.y - 22, 0), face.width + 22, face.height + 22);
                let cropped = src.roi(rect);
                cv.imshow(tempCanvas,cropped);
	}
	let preview = document.getElementById('preview');
	cv.imshow(preview, dst);
	if (faces.size() == 1)
	{
		let sender = document.getElementById("sender");
		sender.disabled = false;
	}
	else if (faces.size() == 0)
	{
	    alert('얼굴이 인식되지 않았습니다.');
	}
	else
	{
		alert('하나의 얼굴만 등록해주세요.')
	}
}

function submit()
{
	let b64encoded = tempCanvas.toDataURL('image/jpeg', 1.0);
	let student_id = document.getElementById('student_id').value;
	let student_name = document.getElementById('student_name').value;
	b64encoded = b64encoded.replace('data:image/jpeg;base64,', '')
	$.ajax({
	   type: "POST",
	   url: "/register",
	   dataType: "json",
	   data: {'image':b64encoded, 'student_id':student_id, 'student_name':student_name},
	   success: function(data){
		   if (data.status == "success"){
			   alert("등록 성공");
		   }
		   else{
			   alert("등록 실패");
		   }
	   }
	})
}

var loadFile = function(event) {
    var reader = new FileReader();
    reader.readAsDataURL(event.target.files[0]);
    reader.onload = function() {
		tempImage.src = reader.result;
	        tempImage.onload = function()
	        {
		    detect_face();
	        }
    };
  };
</script>
</head>
<body onload="cv['onRuntimeInitialized']=()=>{load_cascade();};" class="w3-light-grey">
<!-- w3-content defines a container for fixed size centered content,
and is wrapped around the whole page content, except for the footer in this example -->
	<div class="w3-content" style="max-width:1400px">
	<!-- Header -->
		<header class="w3-container w3-center w3-padding-32"> 
			<h1><b>얼굴 등록</b></h1>
			<p>Made by <span class="w3-tag">정해갑</span></p>
		</header>

		<div class="w3-row", style='text-align:center'>
			<h2><b>얼굴 파일을 등록해주세요 (jpeg only)</b></h2>
			<div>
				학번: <input type="text" id="student_id"><br>
				이름: <input type="text" id="student_name"><br><br>
				<input type="file" id="fileloader" name="file" onchange="loadFile(event)" autocomplete="off" accept="image/jpeg" required disabled>
				<div>
					<canvas id="preview"></canvas>
				</div>
				<input id="sender" type="button" onclick="submit()" value="등록" disabled>
			</div>
		</div>
	</div>
</body>
</html>