194 lines
10 KiB
PHP
194 lines
10 KiB
PHP
@extends('layouts.app')
|
|
@section('content')
|
|
<section class="bg-white dark:bg-gray-900 pt-20">
|
|
<div class="px-4 mx-auto max-w-screen-xl text-center lg:py-16">
|
|
<h1 class="mb-4 text-4xl font-extrabold tracking-tight leading-none text-gray-900 md:text-5xl lg:text-6xl dark:text-white">Deteksi Pelaku Kejahatan</h1>
|
|
<p class="mb-8 text-lg font-normal text-gray-500 lg:text-xl sm:px-16 lg:px-48 dark:text-gray-400">Silahkan upload foto wajah yang terduga pelaku kejahatan.</p>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="px-80 pb-20">
|
|
<form id="form-deteksi" method="post" enctype="multipart/form-data" class="w-full flex flex-wrap justify-between shadow-lg p-8" autocomplete="off">
|
|
@csrf
|
|
<div class="flex justify-between w-full p-4 mb-4">
|
|
<button id="upload-gambar" type="button" class="text-white w-5/12 bg-red-700 hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-red-600 dark:hover:bg-red-700 dark:focus:ring-red-800">Upload Foto</button>
|
|
<button id="ambil-foto" type="button" class="text-white w-5/12 bg-green-700 hover:bg-green-800 focus:ring-4 focus:outline-none focus:ring-green-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-green-600 dark:hover:bg-green-700 dark:focus:ring-green-800" onclick="openCamera()">Ambil Foto</button>
|
|
</div>
|
|
<div class="mb-6 w-full px-4" id="box-upload">
|
|
<label for="gambar" class="block mb-2 text-md font-medium text-gray-900 dark:text-white">*Upload Foto Pelaku</label>
|
|
<div class="flex items-center justify-center w-full">
|
|
<label for="gambar" class="flex flex-col items-center justify-center w-full h-64 border-2 border-gray-300 border-dashed rounded-lg cursor-pointer bg-gray-50 dark:hover:bg-bray-800 dark:bg-gray-700 hover:bg-gray-100 dark:border-gray-600 dark:hover:border-gray-500 dark:hover:bg-gray-600">
|
|
<div class="flex flex-col items-center justify-center pt-5 pb-6" id="desc-upload">
|
|
<svg class="w-8 h-8 mb-4 text-gray-500 dark:text-gray-400" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 16">
|
|
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 13h3a3 3 0 0 0 0-6h-.025A5.56 5.56 0 0 0 16 6.5 5.5 5.5 0 0 0 5.207 5.021C5.137 5.017 5.071 5 5 5a4 4 0 0 0 0 8h2.167M10 15V6m0 0L8 8m2-2 2 2"/>
|
|
</svg>
|
|
<p class="mb-2 text-sm text-gray-500 dark:text-gray-400"><span class="font-semibold">Click to upload</span> or drag and drop</p>
|
|
<p class="text-xs text-gray-500 dark:text-gray-400">SVG, PNG, JPG (MAX. 800x400px)</p>
|
|
</div>
|
|
<input id="gambar" type="file" name="image" accept="image/*" class="hidden" required />
|
|
</label>
|
|
</div>
|
|
@if ($errors->has('image'))
|
|
<strong class="text-red-600 lowercase"> * {{ $errors->first('image') }}</strong>
|
|
@endif
|
|
</div>
|
|
<div id="box-preview" class="mb-6 w-full px-4" hidden>
|
|
<label for="gambar" class="block mb-2 text-md font-medium text-gray-900 dark:text-white">*Upload Foto Pelaku</label>
|
|
<img id="preview" src="" alt="Preview Image" class="hidden rounded-lg w-full" />
|
|
</div>
|
|
<div id="box-preview-video" class="mt-4 mb-6 w-full px-4" hidden>
|
|
<video id="video-preview" class="rounded-lg" autoplay></video>
|
|
</div>
|
|
<div class="w-full p-4">
|
|
<button id="btn-detection" type="button" class="w-full text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-md px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">Mulai Proses Deteksi</button>
|
|
</div>
|
|
<div class="w-full p-4 text-center" id="show-detection" hidden>
|
|
<h1 class="mb-4 text-4xl text-center font-extrabold tracking-tight leading-none text-blue-600 dark:text-white">Proses Deteksi Dimulai</h1>
|
|
<div class="slider-container" id="slider-container">
|
|
@foreach ($data as $item)
|
|
<img class="slider-image rounded-lg w-full" src="{{ asset('foto-pelaku/' . $item->image) }}" alt="Gambar Pelaku Kejahatan">
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
|
|
<div class="w-full p-4 text-center">
|
|
<p id="error-heading" class="text-4xl font-bold text-red-600 mb-2"></p>
|
|
<div id="error-message" class="mb-4 text-xl font-semibold text-red-600"></div>
|
|
<div id="result-heading" class="mt-4 mb-4 text-xl font-semibold text-gray-700"></div>
|
|
<p id="predicted-name" class="text-4xl font-bold text-blue-700 mb-8"></p>
|
|
<div class="text-center">
|
|
<img id="show-result-picture" class="rounded-lg w-full">
|
|
</div>
|
|
<div id="lbp-note" class="mt-8 text-sm font-semibold text-red-600"></div>
|
|
<div id="lbp-heading" class="mt-2 mb-4 text-xl font-semibold text-gray-700"></div>
|
|
<p id="lbp-features" class="text-blue-700"></p>
|
|
</div>
|
|
|
|
</form>
|
|
</section>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
document.getElementById('btn-detection').addEventListener('click', function(event) {
|
|
event.preventDefault();
|
|
let input = document.getElementById('gambar');
|
|
let csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
|
|
|
|
// Membuat objek FormData
|
|
let formData = new FormData();
|
|
formData.append('image', input.files[0]);
|
|
// Menambahkan token CSRF ke dalam FormData
|
|
formData.append('_token', csrfToken);
|
|
|
|
// Memeriksa apakah file telah dipilih
|
|
if (input.files && input.files[0]) {
|
|
document.getElementById('show-detection').removeAttribute('hidden');
|
|
const sliderContainer = document.getElementById('slider-container');
|
|
const sliderImages = document.querySelectorAll('.slider-image');
|
|
let currentSlide = 0;
|
|
|
|
function showSlide() {
|
|
sliderImages.forEach(image => {
|
|
image.style.display = 'none';
|
|
});
|
|
sliderImages[currentSlide].style.display = 'block';
|
|
currentSlide = (currentSlide + 1) % sliderImages.length;
|
|
}
|
|
setInterval(showSlide, 200);
|
|
setTimeout(() => {
|
|
document.getElementById('show-detection').setAttribute('hidden', '');
|
|
|
|
// Mengirimkan permintaan AJAX menggunakan Fetch API
|
|
fetch('/deteksi-pelaku-kejatan', {
|
|
method: 'POST',
|
|
body: formData
|
|
})
|
|
.then(response => {
|
|
if (!response.ok) {
|
|
throw new Error('Network response was not ok');
|
|
}
|
|
return response.json();
|
|
})
|
|
.then(data => {
|
|
console.log(data);
|
|
// Mengonversi string fitur LBP menjadi array
|
|
const lbpArray = JSON.parse(data.lbpFeatures);
|
|
// Memformat nilai-fitur LBP dengan dua angka di belakang koma
|
|
const formattedLBP = lbpArray[0].map(feature => parseFloat(feature).toFixed(4));
|
|
// Menggabungkan semua fitur menjadi satu string dengan satu kurung siku
|
|
const formattedString = `[${formattedLBP.join(', ')}]`;
|
|
// Menampilkan hasil deteksi dan fitur LBP di UI
|
|
document.getElementById('result-heading').innerText = 'Hasil deteksi dari foto wajah di atas terdeteksi sebagai';
|
|
document.getElementById('predicted-name').innerText = `${data.predictions[0]}.`;
|
|
document.getElementById('lbp-heading').innerText = 'Data nilai berikut merupakan hasil dari proses ekstraksi (Local Binary Pattern) yang dihasilkan dari foto wajah di atas.';
|
|
document.getElementById('lbp-note').innerText = '(note: nilai di bawah ini hanya ditampilkan untuk keperluan ujian sidang skripsi)';
|
|
document.getElementById('lbp-features').innerText = formattedString;
|
|
document.getElementById('show-result-picture').setAttribute('src', 'foto-pelaku/' + data.image);
|
|
})
|
|
.catch(error => {
|
|
// console.error('Error:', error);
|
|
document.getElementById('error-heading').innerText = 'Ups, Rupanya Terjadi Kesalahan!';
|
|
document.getElementById('error-message').innerText = 'Tidak dapat menemukan wajah dari foto yang diunggah';
|
|
});
|
|
}, 6000);
|
|
} else {
|
|
console.log('File belum dipilih.');
|
|
}
|
|
});
|
|
});
|
|
|
|
</script>
|
|
|
|
<script>
|
|
function openCamera() {
|
|
const video = document.getElementById('video-preview');
|
|
|
|
navigator.mediaDevices.getUserMedia({ video: true })
|
|
.then(function (stream) {
|
|
video.srcObject = stream;
|
|
})
|
|
.catch(function (error) {
|
|
console.error('Error accessing camera:', error);
|
|
});
|
|
}
|
|
|
|
document.getElementById('ambil-foto').addEventListener('click', () => {
|
|
document.getElementById('box-upload').setAttribute('hidden', '');
|
|
document.getElementById('box-preview-video').removeAttribute('hidden');
|
|
})
|
|
|
|
document.getElementById('upload-gambar').addEventListener('click', () => {
|
|
document.getElementById('box-preview-video').setAttribute('hidden', '');
|
|
document.getElementById('box-upload').removeAttribute('hidden');
|
|
})
|
|
</script>
|
|
|
|
<script>
|
|
const desc = document.getElementById('desc-upload');
|
|
const input = document.getElementById('gambar');
|
|
const preview = document.getElementById('preview');
|
|
const boxupload = document.getElementById('box-upload');
|
|
const boxpreview = document.getElementById('box-preview');
|
|
|
|
input.addEventListener('change', () => {
|
|
desc.style.display = 'none';
|
|
input.style.display = 'none';
|
|
boxupload.setAttribute('hidden', '');
|
|
boxpreview.removeAttribute('hidden');
|
|
|
|
const file = input.files[0];
|
|
|
|
if (file) {
|
|
const reader = new FileReader();
|
|
|
|
reader.addEventListener('load', () => {
|
|
preview.src = reader.result;
|
|
preview.classList.remove('hidden');
|
|
});
|
|
|
|
reader.readAsDataURL(file);
|
|
}
|
|
});
|
|
</script>
|
|
@endsection
|