timer
Logic flow for training
Logic flow for updating model
<!DOCTYPE html>
<html>
<head>
<title>Grid View</title>
<style>
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-gap: 10px;
}
.grid-item {
display: flex;
justify-content: center;
align-items: center;
height: 200px;
border: 1px solid #ddd;
}
.grid-item img {
max-width: 100%;
max-height: 100%;
}
</style>
<script>
document.addEventListener("DOMContentLoaded", function() {
const images = document.querySelectorAll('.grid-item img');
images.forEach(function(img) {
img.onload = function() {
// Adjust the CSS properties of the image element if needed
this.style.maxWidth = '100%';
this.style.maxHeight = '100%';
this.style.margin = '0';
};
img.src = '/images/directory/' + img.getAttribute('data-filename');
});
});
</script>
</head>
<body>
<h1>Grid View</h1>
<div class="grid-container">
{% for image in images %}
<div class="grid-item">
<img src="" alt="{{ image }}" data-filename="{{ image }}">
</div>
{% endfor %}
</div>
</body>
</html>
Grid-view
<script>
$(document).ready(function() {
const dropArea = document.getElementById('dropArea');
const selectFilesBtn = document.getElementById('selectFilesBtn');
const fileInput = document.getElementById('fileInput');
// Prevent default drag behaviors
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
dropArea.addEventListener(eventName, preventDefaults, false);
document.body.addEventListener(eventName, preventDefaults, false);
});
// Highlight the drop area when a file is dragged over it
['dragenter', 'dragover'].forEach(eventName => {
dropArea.addEventListener(eventName, highlight, false);
});
// Remove the highlight when a file is dragged out of the drop area
['dragleave', 'drop'].forEach(eventName => {
dropArea.addEventListener(eventName, unhighlight, false);
});
// Handle dropped files
dropArea.addEventListener('drop', handleDrop, false);
// Open file selection dialog when the select files button is clicked
selectFilesBtn.addEventListener('click', function() {
fileInput.click();
});
// Handle file selection through the file input element
fileInput.addEventListener('change', function(event) {
const files = event.target.files;
handleFiles(files);
}, false);
function preventDefaults(event) {
event.preventDefault();
event.stopPropagation();
}
function highlight() {
dropArea.classList.add('highlight');
}
function unhighlight() {
dropArea.classList.remove('highlight');
}
function handleDrop(event) {
const files = event.dataTransfer.files;
handleFiles(files);
}
function handleFiles(files) {
const formData = new FormData();
for (let i = 0; i < files.length; i++) {
formData.append('files', files[i]);
}
// Send the files to the Flask server using AJAX
uploadFiles(formData);
}
function uploadFiles(formData) {
$.ajax({
type: 'POST',
url: '/upload',
data: formData,
processData: false,
contentType: false,
success: function(response) {
console.log(response);
// Handle the server response as needed
},
error: function(xhr, status, error) {
console.error(xhr.responseText);
// Handle the error as needed
}
});
}
function displayImages(images) {
const imageGrid = document.getElementById('imageGrid');
imageGrid.innerHTML = ''; // Clear the previous content
images.forEach(function(image) {
const imgElement = document.createElement('img');
imgElement.src = image; // Set the source of the image
// Adjust the CSS properties of the image element if needed
imgElement.style.maxWidth = '200px';
imgElement.style.maxHeight = '200px';
imgElement.style.margin = '10px';
imgElement.addEventListener('load', function() {
// Image loaded successfully
imageGrid.appendChild(imgElement); // Add the image to the grid container
});
imgElement.addEventListener('error', function() {
// Image failed to load
imageGrid.removeChild(imgElement); // Remove the image from the grid container
});
});
}
});
</script>
Drag and Drop for uploading multiple images all at once
def pascal_to_yolo(image_width, image_height, xMin, yMin, xMax, yMax):
dw = 1.0 / image_width
dh = 1.0 / image_height
x = (float(xMin) + float(xMax)) / 2.0
y = (float(yMin) + float(yMax)) / 2.0
w = float(xMax) - float(xMin)
h = float(yMax) - float(yMin)
x = x * dw
w = w * dw
y = y * dh
h = h * dh
return x, y, w, h
X,Y Coordinate is changed to yolo format
# Upload image from SAP BTP Kyma to S3
@app.route('/update', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
if 'file1' not in request.files: # when uploading multiple images in "/upload" route
if 'Bucket-Name' not in request.headers:
return 'there is no Bucket Name'
if 'Access_Key' not in request.headers:
return 'there is no Access Key'
if 'Secret_Key' not in request.headers:
return 'there is no Secret Key'
app.config['S3_BUCKET'] = request.headers['Bucket-Name']
app.config['S3_KEY'] = request.headers['Access_Key']
app.config['S3_SECRET'] = request.headers['Secret_Key']
s3 = boto3.client(
"s3",
aws_access_key_id=app.config['S3_KEY'],
aws_secret_access_key=app.config['S3_SECRET']
)
acl="private"
path = os.listdir(app.config['UPLOAD_FOLDER'])
for filename in path:
with open(app.config['UPLOAD_FOLDER'] +"/"+ filename, 'rb') as f:
data = f.read()
file2 = io.BytesIO(data)
try:
s3.upload_fileobj(
file2,
app.config['S3_BUCKET'],
"yolov8-yong/custom_datasets"+ "/new_data/" + filename,
ExtraArgs={
"ACL": acl,
#"ContentType": file1.content_type #Set appropriate content type as per the file
"ContentType": "multipart/form-data"
}
)
except Exception as e:
print("Something Happened: ", e)
return str(e)
return 'ok'
else: # when uploading image one by one from SAP Build Apps
app.config['S3_BUCKET'] = request.headers['Bucket-Name']
app.config['S3_KEY'] = request.headers['Access_Key']
app.config['S3_SECRET'] = request.headers['Secret_Key']
s3 = boto3.client(
"s3",
aws_access_key_id=app.config['S3_KEY'],
aws_secret_access_key=app.config['S3_SECRET']
)
file1 = request.files['file1']
path = os.path.join(app.config['UPLOAD_FOLDER'], file1.filename)
acl="private"
file1.save(path)
with open(path, 'rb') as f:
data = f.read()
file2 = io.BytesIO(data)
try:
s3.upload_fileobj(
file2,
app.config['S3_BUCKET'],
"yolov8-yong/custom_datasets"+ "/new_data/" +file1.filename,
ExtraArgs={
"ACL": acl,
#"ContentType": file1.content_type #Set appropriate content type as per the file
"ContentType": "multipart/form-data"
}
)
except Exception as e:
print("Something Happened: ", e)
return str(e)
return 'ok'
return '''
<h1>Upload new File</h1>
<form method="post" enctype="multipart/form-data">
<input type="file" name="file[]" multiple>
<input type="submit">
</form>
'''
Custom REST API Call in flask server
Data (consisting of jpg, txt, and dataset.yaml files) for 50 images of baguettes and croissants.
New data is stored in s3
# FROM docker.io/pytorch/pytorch:latest
FROM pytorch/pytorch:latest
# Downloads to user config dir
ADD https://ultralytics.com/assets/Arial.ttf https://ultralytics.com/assets/Arial.Unicode.ttf /root/.config/Ultralytics/
# Install linux packages
ENV DEBIAN_FRONTEND noninteractive
RUN apt update
RUN TZ=Etc/UTC apt install -y tzdata
RUN apt install --no-install-recommends -y gcc git zip curl htop libgl1-mesa-glx libglib2.0-0 libpython3-dev gnupg g++
# RUN alias python=python3
# Security updates
# https://security.snyk.io/vuln/SNYK-UBUNTU1804-OPENSSL-3314796
# RUN apt upgrade --no-install-recommends -y openssl
# Create working directory
RUN mkdir -p /usr/src/ultralytics
COPY ultralytics /usr/src/ultralytics
RUN mkdir -p /usr/src/custom_datasets
RUN mkdir -p /usr/src/ultralytics/runs/detect/train/weights
RUN mkdir -p /usr/src/ultralytics/runs/detect/train/weights/test
#pip install
COPY requirements.txt /usr/src/requirements.txt
RUN pip3 install -r /usr/src/requirements.txt
#work dir
WORKDIR /usr/src/ultralytics
# Data source
ENV DATA_SOURCE=/usr/src/custom_datasets/
ENV OUTPUT_PATH=/usr/src/ultralytics/runs/detect/train/weights/
ENV TRAIN_PATH_IMG=/usr/src/datasets/images/train
ENV TRAIN_PATH_LABEL=/usr/src/datasets/labels/train
ENV VAL_PATH_IMG=/usr/src/datasets/images/val
ENV VAL_PATH_LABEL=/usr/src/datasets/labels/val
ENV TEST_PATH=/usr/src/datasets/test
ENV YAML_PATH=/usr/src/ultralytics/ultralytics/datasets/
ENV NEW_DATA_PATH=/usr/src/custom_datasets/new_data/
# Set environment variables
ENV OMP_NUM_THREADS=1
ENV PYTHONPATH /usr/src/ultralytics
# Cleanup
ENV DEBIAN_FRONTEND teletype
# Required to execute script
RUN chgrp -R nogroup /usr/src && \
chmod -R 770 /usr/src
Dockerfile for Training in SAP AI Core
names=trainer.validator.names
nt= trainer.validator.nt_per_class
def isNaN(num):
return num != num
for name in names:
if isNaN(trainer.validator.confusion_matrix.array[name][name]):
trainer.validator.confusion_matrix.array[name][name]=0
aic_connection.set_custom_info(
custom_info=[
MetricCustomInfo(name=names[name],
value=str(round(trainer.validator.confusion_matrix.array[name][name] * nt[name]))
+ " images are correctly detected "
+ "out of "
+ str(nt[name]))
]
)
else:
aic_connection.set_custom_info(
custom_info=[
MetricCustomInfo(name=names[name],
value=str(round(trainer.validator.confusion_matrix.array[name][name] * nt[name]))
+ " images are correctly detected "
+ "out of "
+ str(nt[name]))
]
)
Confusion Matrix for Result of Yolov8
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
26 | |
24 | |
20 | |
13 | |
10 | |
9 | |
9 | |
8 | |
8 | |
7 |