Add results page with functionality
This commit is contained in:
parent
a75c94d5c6
commit
270bb92c4c
@ -0,0 +1,26 @@
|
||||
# Generated by Django 4.2.7 on 2023-12-19 21:15
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("DetectionApp", "0010_rename_detectimage_uploadimage"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name="predictedimage",
|
||||
name="class_name",
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name="predictedimage",
|
||||
name="confidence",
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="predictedimage",
|
||||
name="prediction_data",
|
||||
field=models.JSONField(default={"data": "no predictions"}),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
@ -1,3 +1,4 @@
|
||||
import json
|
||||
from django.db import models
|
||||
from django.core.validators import FileExtensionValidator
|
||||
from django.contrib.auth.models import User
|
||||
@ -17,8 +18,7 @@ class UploadImage(models.Model):
|
||||
class PredictedImage(models.Model):
|
||||
original_image = models.OneToOneField(UploadImage, on_delete=models.CASCADE)
|
||||
image = models.ImageField(upload_to=f"plankton/%Y/%m/%d/{original_image.name}")
|
||||
confidence = models.FloatField()
|
||||
class_name = models.CharField(max_length=100)
|
||||
prediction_data = models.JSONField()
|
||||
date_predicted = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
@property
|
||||
@ -28,3 +28,9 @@ class PredictedImage(models.Model):
|
||||
@property
|
||||
def get_original_image(self):
|
||||
return self.original_image.image
|
||||
|
||||
def get_prediction_data(self):
|
||||
results = json.loads(self.prediction_data)
|
||||
for pred in results:
|
||||
pred["confidence"] = round(pred["confidence"] * 100, 2)
|
||||
return results
|
||||
|
@ -16,5 +16,6 @@ def predict_image(image):
|
||||
name=f"{image.image.name}_predicted",
|
||||
imgsz=[640, 640],
|
||||
)
|
||||
x = json.loads(results[0].tojson())
|
||||
for r in results:
|
||||
x = r.tojson()
|
||||
return x
|
||||
|
@ -9,6 +9,7 @@ from django.utils.decorators import method_decorator
|
||||
from .models import UploadImage, PredictedImage
|
||||
from .utils import predict_image
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
import json
|
||||
|
||||
|
||||
class DetectView(View):
|
||||
@ -37,22 +38,20 @@ class DetectView(View):
|
||||
)
|
||||
image.save()
|
||||
try:
|
||||
results_metrics = prediciton_results[0]
|
||||
results_metrics = prediciton_results
|
||||
except IndexError as e:
|
||||
PredictedImage.objects.create(
|
||||
predicted_image = PredictedImage.objects.create(
|
||||
original_image=image,
|
||||
image=image.predicted_image_url,
|
||||
confidence=0.0,
|
||||
class_name="no predictions",
|
||||
prediction_data={"data": "no results"},
|
||||
)
|
||||
else:
|
||||
PredictedImage.objects.create(
|
||||
predicted_image = PredictedImage.objects.create(
|
||||
original_image=image,
|
||||
image=image.predicted_image_url,
|
||||
confidence=results_metrics["confidence"],
|
||||
class_name=results_metrics["name"],
|
||||
prediction_data=results_metrics,
|
||||
)
|
||||
predictions.append(image)
|
||||
predictions.append(predicted_image)
|
||||
return render(
|
||||
request,
|
||||
"results.html",
|
||||
|
Binary file not shown.
@ -1,10 +1,12 @@
|
||||
body, html{
|
||||
height:100%;
|
||||
margin: 0px 0px 0px 0px;
|
||||
min-height: 100%;
|
||||
margin: 35px 0px 0px 0px;
|
||||
display:flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
font-family:'Inter', sans-serif;
|
||||
overflow-x:hidden
|
||||
}
|
||||
|
||||
.top-menu a{
|
||||
@ -16,10 +18,12 @@ body, html{
|
||||
.top-menu{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
position: fixed;
|
||||
top:0;
|
||||
width: 100%;
|
||||
justify-content:flex-end;
|
||||
align-items: center;
|
||||
background-color:lightgray;
|
||||
margin-bottom:5px;
|
||||
height: 45px;
|
||||
border: grey solid;
|
||||
border-width: 0px 2px 2px 2px;
|
||||
@ -29,14 +33,10 @@ body, html{
|
||||
|
||||
.footer{
|
||||
display:flex;
|
||||
position:fixed;
|
||||
position:relative;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left:0;
|
||||
width: 100%;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 5px;
|
||||
background-color: lightgray;
|
||||
border: grey solid;
|
||||
border-width: 2px 2px 0px 2px;
|
||||
|
@ -5,29 +5,31 @@ form{
|
||||
display:flex;
|
||||
flex-direction:row;
|
||||
margin:auto;
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
|
||||
.side_menu{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
justify-content: space-between;
|
||||
align-items:center;
|
||||
flex-direction: column;
|
||||
width: 25%;
|
||||
background-color: lightgray;
|
||||
border: grey solid;
|
||||
border-width: 2px;
|
||||
margin-bottom: 59px;
|
||||
border: 2px grey solid;
|
||||
padding: 0px 0px 40px 0px;
|
||||
margin-bottom: 5px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
|
||||
#description{
|
||||
font-size: 40px;
|
||||
text-align: center;
|
||||
margin: 10px 0px 15px 0px;
|
||||
}
|
||||
|
||||
#submit{
|
||||
margin-bottom: 40px;
|
||||
background-color: chartreuse;
|
||||
margin-top: auto;
|
||||
height: 50px;
|
||||
@ -62,3 +64,24 @@ form{
|
||||
}
|
||||
|
||||
|
||||
.image_number {
|
||||
font-size: medium;
|
||||
margin: 0 0 5px 0 ;
|
||||
}
|
||||
|
||||
.results{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: white;
|
||||
width: 70%;
|
||||
align-items: center;
|
||||
border: 2px black solid;
|
||||
border-radius: 5%;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.detection_info{
|
||||
font-size: large;
|
||||
text-decoration:solid;
|
||||
color: black;
|
||||
}
|
@ -5,6 +5,7 @@ form{
|
||||
display:flex;
|
||||
flex-direction:row;
|
||||
margin:auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
@ -17,7 +18,7 @@ form{
|
||||
background-color: lightgray;
|
||||
border: grey solid;
|
||||
border-width: 2px;
|
||||
margin-bottom: 59px;
|
||||
margin-bottom:5px;
|
||||
}
|
||||
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
<title>Plankton Detector</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="top-menu">
|
||||
<div class="top-menu" id="top-menu">
|
||||
<a href="{% url 'posts' %}">Community</a>
|
||||
<a href="{% url 'detect' %}">Predict</a>
|
||||
{% if user.is_authenticated %}
|
||||
@ -24,17 +24,17 @@
|
||||
{%endif%}
|
||||
</div>
|
||||
{%block content%}{%endblock content%}
|
||||
<div class="footer">
|
||||
<footer class="footer">
|
||||
<p>Footer</p>
|
||||
</div>
|
||||
</footer>
|
||||
<script>
|
||||
var prevScrollpos = window.pageYOffset;
|
||||
window.onscroll = function() {
|
||||
var currentScrollPos = window.pageYOffset;
|
||||
if (prevScrollpos > currentScrollPos) {
|
||||
document.getElementsByClassName("top-menu").style.top = "0";
|
||||
document.getElementById("top-menu").style.top = "0";
|
||||
} else {
|
||||
document.getElementsByClassName("top-menu").style.top = "-50px";
|
||||
document.getElementById("top-menu").style.top = "-45px";
|
||||
}
|
||||
prevScrollpos = currentScrollPos;
|
||||
}
|
||||
|
@ -12,15 +12,29 @@
|
||||
<button onclick="location.href='{% url 'login' %}'" id='submit' method="GET" type='button'>Login</button>
|
||||
{% else %}
|
||||
<p id="description">Results:</p>
|
||||
{%for img in img_url%}
|
||||
<p class="image_number">Image {{forloop.counter}}</p>
|
||||
{%for detection in img.get_prediction_data%}
|
||||
<div class="results">
|
||||
<p class="detection_info">{{detection.name}}: {{detection.confidence}}%</p>
|
||||
</div>
|
||||
{%endfor%}
|
||||
{%endfor%}
|
||||
<button onclick="location.href='{% url 'detect' %}'" id='submit' method="GET" type='button'>Submit again</button>
|
||||
{%endif%}
|
||||
</div>
|
||||
<div class="upload_field">
|
||||
<label>
|
||||
{%for img in img_url%}
|
||||
<img src="{%get_media_prefix%}{{img.predicted_image_url}}" alt="upload_image" style="width:640px; height:460px;">
|
||||
<img src="{{img.image.url}}" alt="upload_image" style="width:640px; height:460px;">
|
||||
{%endfor%}
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
<script>
|
||||
var results=document.getElementsByClassName("results")
|
||||
for (var i = 0; i < results.length; i++){
|
||||
results[i].style.background=`linear-gradient(90deg, #7fff00 ${results[i].textContent.split(":")[1]}, #FFFFFF 0%)`
|
||||
};
|
||||
</script>
|
||||
{%endblock content%}
|
@ -4,7 +4,7 @@
|
||||
<link rel="stylesheet" href="{%static 'DetectionApp/css/upload.css' %}">
|
||||
{%endblock extracss%}
|
||||
{%block content%}
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
<form method="POST" enctype="multipart/form-data" id="upload_form">
|
||||
{% csrf_token %}
|
||||
<div class="side_menu">
|
||||
{% if not user.is_authenticated %}
|
||||
@ -15,6 +15,7 @@
|
||||
<input type="submit" id="submit" value="Submit">
|
||||
{%endif%}
|
||||
</div>
|
||||
<div id="progress"></div>
|
||||
<div class="upload_field">
|
||||
<label for="id_image", class="upload_button" id="image-preview-container">
|
||||
{{form.as_p}}
|
||||
|
Loading…
Reference in New Issue
Block a user