Skip to content
Snippets Groups Projects
Commit a345b878 authored by a2-imeri's avatar a2-imeri
Browse files

Update back-end flow

parent 20e00a0f
No related branches found
No related tags found
No related merge requests found
Showing
with 72 additions and 163 deletions
......@@ -3,3 +3,6 @@ __pycache__/
# Ignore all migrations directories
migrations/
/media/
media/
\ No newline at end of file
No preview for this file type
No preview for this file type
......@@ -12,15 +12,10 @@ urlpatterns = [
path('auth/', include('authentication.urls')),
path('admin-app/', include('admin_app.urls')),
path('process_misplaced_manager/', include('process_misplaced_manager.urls', namespace='process_misplaced_manager')), # Ensure namespace is included correctly
path('item_detector/', include('item_detector.urls', namespace='item_detector')), # Include item_detector URLs with namespace
path('placement_rules/', include('placement_rules.urls', namespace='placement_rules')), # Include placement_rules URLs with namespace
path('results_viewer/', include('results_viewer.urls', namespace='results_viewer')),
path('results_viewer/', include('results_viewer.urls', namespace='results_viewer')), # Include results_viewer URLs with namespace
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
from django.contrib import admin
# Register your models here.
# item_detector/apps.py
from django.apps import AppConfig
class ItemDetectorConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'item_detector'
verbose_name = 'Item Detector'
#item_detector/models.py
from django.db import models
class DetectedObject(models.Model):
class_name = models.CharField(max_length=255)
ymin = models.FloatField()
xmin = models.FloatField()
ymax = models.FloatField()
xmax = models.FloatField()
image = models.ForeignKey('process_misplaced_manager.UploadedImage', on_delete=models.CASCADE)
def __str__(self):
return f"{self.class_name} ({self.ymin}, {self.xmin}, {self.ymax}, {self.xmax})"
{% extends 'core/base.html' %}
{% load static %}
{% block content %}
<div class="container mt-5">
<h1>Detected Objects</h1>
<img src="{{ output_image_url }}" alt="Detected Objects" class="img-fluid">
<h2>Details</h2>
<ul>
{% for obj in detected_objects %}
<li>{{ obj.class_name }}: [{{ obj.ymin }}, {{ obj.xmin }}, {{ obj.ymax }}, {{ obj.xmax }}]</li>
{% endfor %}
</ul>
{% if misplaced_objects %}
<h2>Misplaced Objects</h2>
<ul>
{% for obj in misplaced_objects %}
<li>{{ obj.class_name }} is misplaced. It should be on {{ obj.allowed_locations|join:", " }}.</li>
{% endfor %}
</ul>
{% endif %}
<h2>Annotated Image with Misplaced Items</h2>
<img src="{{ annotated_image_url }}" alt="Annotated Image" class="img-fluid">
</div>
{% endblock %}
\ No newline at end of file
from django.urls import path
from .views import detect_items
app_name = 'item_detector'
urlpatterns = [
path('detect/<int:image_id>/', detect_items, name='detect_items'),
]
import os
import glob
import numpy as np
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO
import tensorflow as tf
import os
from PIL import Image
from io import BytesIO
from object_detection.utils import ops as utils_ops, label_map_util
# Patch tf1 functions into `utils.ops` for compatibility
utils_ops.tf = tf.compat.v1
from object_detection.utils import label_map_util, ops as utils_ops
# Patch the location of gfile for TensorFlow file operations
tf.gfile = tf.io.gfile
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"
def load_model(model_path):
"""Load the object detection model from the specified path."""
model = tf.saved_model.load(model_path)
return model
MAX_DIMENSION = 1024
def create_category_index_from_labelmap(label_map_path, use_display_name=True):
"""Create a category index from a label map file."""
return label_map_util.create_category_index_from_labelmap(label_map_path, use_display_name=use_display_name)
def load_image_into_numpy_array(path):
"""Load an image from file into a numpy array."""
img_data = tf.io.gfile.GFile(path, "rb").read()
image = Image.open(BytesIO(img_data))
(im_width, im_height) = image.size
return np.array(image.getdata()).reshape((im_height, im_width, 3)).astype(np.uint8)
def load_model(model_path):
return tf.saved_model.load(model_path)
def run_inference(model, category_index, image_path):
"""Run inference on a single image."""
print("-----------------------------------")
print("DEBUG-MESSAGE--FROM-BATCH-INTERFACE")
def create_category_index_from_labelmap(label_map_path, use_display_name=True):
return label_map_util.create_category_index_from_labelmap(label_map_path, use_display_name)
image_np = load_image_into_numpy_array(image_path)
output_dict = run_inference_for_single_image(model, image_np)
dataLocation = []
print(f"Detected objects in {image_path}:")
for i, box in enumerate(output_dict["detection_boxes"]):
if output_dict["detection_scores"][i] > 0.5:
ymin, xmin, ymax, xmax = box
class_id = output_dict["detection_classes"][i]
class_name = category_index[class_id]["name"] if class_id in category_index else "N/A"
print(f"Object {i+1} ({class_name}): [{ymin:.2f}, {xmin:.2f}, {ymax:.2f}, {xmax:.2f}]")
dataLocation.append({
"Object": i,
"class_name": class_name,
"ymin": ymin,
"xmin": xmin,
"ymax": ymax,
"xmax": xmax,
})
def resize_image(image):
width, height = image.size
if width > MAX_DIMENSION or height > MAX_DIMENSION:
if width > height:
new_width = MAX_DIMENSION
new_height = int((MAX_DIMENSION / width) * height)
else:
new_height = MAX_DIMENSION
new_width = int((MAX_DIMENSION / height) * width)
return image.resize((new_width, new_height), Image.ANTIALIAS)
return image
print("-----------------------------------")
return dataLocation
def run_inference(model, category_index, image_path):
image_np = load_image_into_numpy_array(image_path)
input_tensor = tf.convert_to_tensor(image_np)
def run_inference_for_single_image(model, image):
"""Run inference on a single image and return the output dictionary."""
# Convert image to tensor and add batch dimension
input_tensor = tf.convert_to_tensor(image)
input_tensor = input_tensor[tf.newaxis, ...]
# Run inference
output_dict = model(input_tensor)
# Process output tensors
num_detections = int(output_dict.pop("num_detections"))
output_dict = {key: value[0, :num_detections].numpy() for key, value in output_dict.items()}
output_dict["num_detections"] = num_detections
output_dict["detection_classes"] = output_dict["detection_classes"].astype(np.int64)
detected_objects = []
for i in range(num_detections):
if output_dict['detection_scores'][i] > 0.5:
ymin, xmin, ymax, xmax = output_dict['detection_boxes'][i]
class_id = output_dict['detection_classes'][i]
class_name = category_index[class_id]['name'] if class_id in category_index else 'N/A'
detected_objects.append({
'class_name': class_name,
'ymin': ymin,
'xmin': xmin,
'ymax': ymax,
'xmax': xmax
})
return detected_objects
def visualize_boxes(image_path, detected_objects, output_path):
image = Image.open(image_path)
image = resize_image(image) # Resize the image if necessary
draw = ImageDraw.Draw(image)
font = ImageFont.load_default()
for obj in detected_objects:
ymin = obj['ymin'] * image.height
xmin = obj['xmin'] * image.width
ymax = obj['ymax'] * image.height
xmax = obj['xmax'] * image.width
draw.rectangle([(xmin, ymin), (xmax, ymax)], outline="red", width=3)
draw.text((xmin, ymin), obj['class_name'], fill="red", font=font)
image.save(output_path)
def run_inference_and_visualize(model, category_index, image_path, output_path):
detected_objects = run_inference(model, category_index, image_path)
visualize_boxes(image_path, detected_objects, output_path)
return detected_objects
# Process masks, if available
if "detection_masks" in output_dict:
detection_masks_reframed = utils_ops.reframe_box_masks_to_image_masks(
output_dict["detection_masks"],
output_dict["detection_boxes"],
image.shape[0],
image.shape[1],
)
detection_masks_reframed = tf.cast(detection_masks_reframed > 0.5, tf.uint8)
output_dict["detection_masks_reframed"] = detection_masks_reframed.numpy()
return output_dict
from django.shortcuts import render, get_object_or_404
from .models import DetectedObject
from process_misplaced_manager.models import UploadedImage
from .utils import run_inference, load_model, create_category_index_from_labelmap, run_inference_and_visualize
from placement_rules.utils import PlacementRules
from results_viewer.utils import visualize_misplaced_objects # Import the visualization function
import os
MODEL_PATH = "models/research/object_detection/faster_rcnn_resnet50_v1_1024x1024_coco17_tpu-8/saved_model"
LABEL_MAP_PATH = "models/research/object_detection/data/mscoco_label_map.pbtxt"
detection_model = load_model(MODEL_PATH)
category_index = create_category_index_from_labelmap(LABEL_MAP_PATH)
def detect_items(request, image_id):
image = get_object_or_404(UploadedImage, id=image_id)
image_path = image.image.path
output_image_name = "detected_" + os.path.basename(image_path)
output_image_path = os.path.join("media", output_image_name)
detected_objects = run_inference_and_visualize(detection_model, category_index, image_path, output_image_path)
for obj in detected_objects:
DetectedObject.objects.create(
class_name=obj['class_name'],
ymin=obj['ymin'],
xmin=obj['xmin'],
ymax=obj['ymax'],
xmax=obj['xmax'],
image=image
)
placement_rules = PlacementRules()
misplaced_objects = placement_rules.check_placement(detected_objects)
annotated_image_path = visualize_misplaced_objects(image_path, detected_objects, misplaced_objects)
return render(request, 'item_detector/results.html', {
'detected_objects': detected_objects,
'image': image,
'output_image_url': "/media/" + output_image_name,
'annotated_image_url': "/media/" + os.path.basename(annotated_image_path),
'misplaced_objects': misplaced_objects
})
MisplaceAI/media/annotated_c_s1KC3iy.jpg

79.1 KiB

MisplaceAI/media/detected_1265_8dCYFrT.jpg

99.4 KiB

MisplaceAI/media/detected_1265_SqbKUM7.jpg

686 KiB

MisplaceAI/media/detected_1265_Ut88mRj.jpg

686 KiB

MisplaceAI/media/detected_1265_WZU8Jas.jpg

99.4 KiB

MisplaceAI/media/detected_1265_qlFQMla.jpg

99.4 KiB

MisplaceAI/media/detected_c.jpg

94.4 KiB

MisplaceAI/media/detected_c_Q8DkqzK.jpg

94.4 KiB

MisplaceAI/media/detected_c_oyoy0lB.jpg

94.4 KiB

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment