Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Mayer
CircularGreenSimCity
Commits
a5b5b189
Commit
a5b5b189
authored
Sep 20, 2024
by
Mayer
Browse files
Add new file
parent
28a37ce3
Changes
1
Hide whitespace changes
Inline
Side-by-side
python_scripts/DLM_Tree_Classification/DLM_training_script
0 → 100644
View file @
a5b5b189
import
os
import
gdown
from
glob
import
glob
import
cv2
from
PIL
import
Image
,
ImageDraw
,
ImageFont
from
IPython
.
display
import
display
from
ultralytics
import
YOLO
import
matplotlib
.
pyplot
as
plt
import
matplotlib
.
patches
as
patches
#
Download
Dataset
-
Download
and
unpack
a
dataset
consisting
of
a
train
,
val
and
test
split
.
Trees
are
labeled
(
using
the
YOLO
format
).
gdown
.
cached_download
(
"https://drive.google.com/file/d/1xkh8RYp15c0N4A9HFvcBeSmxhWaH5Ynw/view?usp=sharing"
,
"sorted_images_YOLO_formatted.zip"
,
fuzzy
=
True
,
postprocess
=
gdown
.
extractall
)
#
Setting
up
the
Framework
-
create
a
setup
file
named
yolov8
.
yaml
containing
required
parameters
%%
writefile
sorted_images_YOLO_formatted
/
data
/
yolov8
.
yaml
#
Train
/
val
/
test
sets
path
:
sorted_images_YOLO_formatted
/
data
/
#
dataset
root
dir
train
:
train
#
train
images
(
relative
to
'path'
)
val
:
val
#
val
images
(
relative
to
'path'
)
test
:
test
#
test
images
(
optional
)
#
number
of
classes
nc
:
2
#
class
names
names
:
[
'Großer Laubbaum'
,
'Kleiner Laubbaum'
]
#
Training
-
Train
the
model
on
the
train
dataset
.
yolov8n
.
pt
refers
to
the
smallest
model
size
#
Load
a
pretrained
model
model
=
YOLO
(
"yolov8n.pt"
)
#
Train
the
model
results
=
model
.
train
(
data
=
"sorted_images_YOLO_formatted/data/yolov8.yaml"
,
epochs
=
500
,
imgsz
=
200
,
cache
=
False
)
#
Model
evaluation
-
Evaluate
the
model
performance
on
the
validation
dataset
#
Validate
the
model
metrics
=
model
.
val
(
split
=
'val'
)
metrics
.
box
.
map
#
map50
-
95
metrics
.
box
.
map50
#
map50
metrics
.
box
.
map75
#
map75
metrics
.
box
.
maps
#
a
list
contains
map50
-
95
of
each
category
#
Display
performance
metrics
display
(
Image
.
open
(
'runs/detect/train/results.png'
))
display
(
Image
.
open
(
'runs/detect/train2/confusion_matrix_normalized.png'
))
display
(
Image
.
open
(
'runs/detect/train2/F1_curve.png'
))
display
(
Image
.
open
(
'runs/detect/train2/labels_correlogram.jpg'
))
display
(
Image
.
open
(
'runs/detect/train2/labels.jpg'
))
display
(
Image
.
open
(
'runs/detect/train/P_curve.png'
))
display
(
Image
.
open
(
'runs/detect/train/PR_curve.png'
))
display
(
Image
.
open
(
'runs/detect/train/R_curve.png'
))
#
Model
Inference
#
We
use
the
model
for
inference
on
a
list
of
images
.
#
First
,
we
load
the
model
checkpoint
with
the
best
performance
.
#
Load
trained
model
model
=
YOLO
(
'runs/detect/train2/weights/best.pt'
)
#
load
a
custom
trained
model
#
Export
the
model
#
model
.
export
(
format
=
'torchscript'
)
#
model
.
export
(
format
=
'onnx'
,
simplify
=
True
)
#
We
define
a
list
of
images
on
which
we
will
apply
the
model
to
identify
trees
.
#
imagefiles
=
[
#
"/content/ObjectDetectionDataset/data/test/513278_5404358_Base_A62_Luftbild_2021_EPSG25832.png"
,
#
"/content/ObjectDetectionDataset/data/test/513278_5404407_Base_A62_Luftbild_2021_EPSG25832.png"
,
#
"/content/ObjectDetectionDataset/data/test/513278_5404553_Base_A62_Luftbild_2021_EPSG25832.png"
#
]
#
Run
batched
inference
on
a
list
of
images
#
results
=
model
.
predict
(
imagefiles
)
#
Neue
Methodik
um
alle
Bilder
aus
/
content
/
ObjectDetectionDataset
/
data
/
test
vom
Modell
untersuchen
zu
lassen
#
Verzeichnis
mit
den
Testbildern
test_directory
=
"sorted_images_YOLO_formatted/data/test/"
imagefiles
=
glob
(
os
.
path
.
join
(
test_directory
,
"*.png"
))
#
Modellvorhersagen
ausf
ü
hren
results
=
model
.
predict
(
imagefiles
)
#
Benutzerdefinierte
Farben
f
ü
r
die
Klassen
(
basierend
auf
meinem
urspr
ü
nglichen
Skript
)
class_colors
=
{
'Großer Laubbaum'
:
'red'
,
'Kleiner Laubbaum'
:
'orange'
}
#
Klassen
-
IDs
und
Klassennamen
zuordnen
class_names
=
[
'Großer Laubbaum'
,
'Kleiner Laubbaum'
]
#
Following
2
Options
of
how
to
display
the
output
:
#
1
:
Output
with
200
x200
pixels
-
save
files
to
predictions
/
directory
-
no
readablie
labels
from
PIL
import
Image
,
ImageDraw
,
ImageFont
import
os
#
Ergebnisverzeichnis
f
ü
r
die
Vorhersagen
erstellen
,
falls
es
nicht
existiert
os
.
makedirs
(
'predictions/'
,
exist_ok
=
True
)
#
Benutzerdefinierte
Farben
f
ü
r
die
Klassen
class_colors
=
{
'Großer Laubbaum'
:
'red'
,
'Kleiner Laubbaum'
:
'orange'
}
#
Vorhersagen
plotten
und
Farben
anpassen
for
i
,
result
in
enumerate
(
results
):
#
Bild
laden
img
=
Image
.
open
(
imagefiles
[
i
])
#
Bild
um
50
%
gr
öß
er
skalieren
img
=
img
.
resize
((
int
(
img
.
width
*
1.5
),
int
(
img
.
height
*
1.5
)))
draw
=
ImageDraw
.
Draw
(
img
)
#
Bounding
-
Boxen
und
Klassen
plotten
for
box
in
result
.
boxes
:
#
Koordinaten
der
Bounding
-
Box
xmin
,
ymin
,
xmax
,
ymax
=
box
.
xyxy
[
0
].
numpy
()
#
Anpassung
der
Koordinaten
an
das
skalierte
Bild
xmin
,
ymin
,
xmax
,
ymax
=
[
coord
*
1.5
for
coord
in
[
xmin
,
ymin
,
xmax
,
ymax
]]
#
Klassennamen
anhand
der
Klassen
-
ID
holen
class_id
=
int
(
box
.
cls
)
class_name
=
class_names
[
class_id
]
#
Bounding
-
Box
zeichnen
mit
der
Farbe
aus
dem
Farbschema
draw
.
rectangle
([
xmin
,
ymin
,
xmax
,
ymax
],
outline
=
class_colors
[
class_name
],
width
=
3
)
#
Bild
ohne
wei
ß
en
Hintergrund
und
Achsen
speichern
img
.
save
(
os
.
path
.
join
(
'predictions'
,
os
.
path
.
split
(
imagefiles
[
i
])[
1
]))
print
(
f
"Processed: {imagefiles[i]}"
)
#
2
:
Output
with
200
x200
pixels
-
save
files
to
predictions
/
directory
-
readable
labels
from
PIL
import
Image
,
ImageDraw
,
ImageFont
import
os
#
Ergebnisverzeichnis
f
ü
r
die
Vorhersagen
erstellen
,
falls
es
nicht
existiert
os
.
makedirs
(
'predictions/'
,
exist_ok
=
True
)
#
Benutzerdefinierte
Farben
f
ü
r
die
Klassen
class_colors
=
{
'Großer Laubbaum'
:
'red'
,
'Kleiner Laubbaum'
:
'orange'
,
'Großer Nadelbaum'
:
'darkgreen'
,
'Kleiner Nadelbaum'
:
'lightgreen'
,
'Busch/Hecke (Laub/Hartlaub)'
:
'purple'
,
'Busch/Hecke (Nadel)'
:
'cornflowerblue'
,
'Unbekannt'
:
'white'
}
#
Schriftart
und
-
gr
öß
e
festlegen
(
falls
verf
ü
gbar
)
try
:
font
=
ImageFont
.
truetype
(
"arial.ttf"
,
40
)
#
Verwende
Arial
mit
Gr
öß
e
20
except
IOError
:
font
=
ImageFont
.
load_default
()
#
Fallback
auf
Standard
-
Schriftart
#
Vorhersagen
plotten
und
Farben
anpassen
for
i
,
result
in
enumerate
(
results
):
#
Bild
laden
img
=
Image
.
open
(
imagefiles
[
i
])
#
Bild
um
50
%
gr
öß
er
skalieren
img
=
img
.
resize
((
int
(
img
.
width
*
1.5
),
int
(
img
.
height
*
1.5
)))
draw
=
ImageDraw
.
Draw
(
img
)
#
Bounding
-
Boxen
und
Klassen
plotten
for
box
in
result
.
boxes
:
#
Koordinaten
der
Bounding
-
Box
xmin
,
ymin
,
xmax
,
ymax
=
box
.
xyxy
[
0
].
numpy
()
#
Anpassung
der
Koordinaten
an
das
skalierte
Bild
xmin
,
ymin
,
xmax
,
ymax
=
[
coord
*
1.5
for
coord
in
[
xmin
,
ymin
,
xmax
,
ymax
]]
#
Klassennamen
anhand
der
Klassen
-
ID
holen
class_id
=
int
(
box
.
cls
)
class_name
=
class_names
[
class_id
]
#
Bounding
-
Box
zeichnen
mit
der
Farbe
aus
dem
Farbschema
draw
.
rectangle
([
xmin
,
ymin
,
xmax
,
ymax
],
outline
=
class_colors
[
class_name
],
width
=
2
)
#
Gr
öß
e
des
Textes
berechnen
mit
textbbox
(
ersetzt
textsize
)
text_bbox
=
draw
.
textbbox
((
xmin
,
ymin
),
class_name
,
font
=
font
)
text_width
=
text_bbox
[
2
]
-
text_bbox
[
0
]
text_height
=
text_bbox
[
3
]
-
text_bbox
[
1
]
#
Hintergrund
f
ü
r
den
Text
(
halbtransparent
)
text_background
=
(
xmin
,
ymin
-
text_height
,
xmin
+
text_width
,
ymin
)
draw
.
rectangle
(
text_background
,
fill
=(
200
,
200
,
200
,
128
))
#
Schwarzer
halbtransparenter
Hintergrund
#
Klassennamen
ü
ber
die
Bounding
-
Box
schreiben
draw
.
text
((
xmin
,
ymin
-
text_height
),
class_name
,
font
=
font
,
fill
=
"red"
)
#
Wei
ß
er
Text
#
Bild
ohne
wei
ß
en
Hintergrund
und
Achsen
speichern
img
.
save
(
os
.
path
.
join
(
'predictions'
,
os
.
path
.
split
(
imagefiles
[
i
])[
1
]))
print
(
f
"Processed: {imagefiles[i]}"
)
#
Export
of
labels
as
.
txt
def
yolo_format
(
class_id
,
xmin
,
ymin
,
xmax
,
ymax
,
img_width
,
img_height
):
x_center
=
(
xmin
+
xmax
)
/
2.0
/
img_width
y_center
=
(
ymin
+
ymax
)
/
2.0
/
img_height
width
=
(
xmax
-
xmin
)
/
img_width
height
=
(
ymax
-
ymin
)
/
img_height
return
f
"{class_id} {x_center} {y_center} {width} {height}"
def
save_yolo_labels
(
results
,
output_dir
):
if
not
os
.
path
.
exists
(
output_dir
):
os
.
makedirs
(
output_dir
)
for
i
,
result
in
enumerate
(
results
):
boxes
=
result
.
boxes
#
Extract
boxes
from
result
img_width
,
img_height
=
result
.
orig_shape
#
Get
the
original
image
shape
image_path
=
result
.
path
image_id
=
os
.
path
.
splitext
(
os
.
path
.
basename
(
image_path
))[
0
]
with
open
(
os
.
path
.
join
(
output_dir
,
f
"{image_id}.txt"
),
'w'
)
as
f
:
for
box
in
boxes
:
class_id
=
int
(
box
.
cls
)
xmin
,
ymin
,
xmax
,
ymax
=
box
.
xyxy
[
0
].
numpy
()
#
Extract
box
coordinates
yolo_line
=
yolo_format
(
class_id
,
xmin
,
ymin
,
xmax
,
ymax
,
img_width
,
img_height
)
f
.
write
(
yolo_line
+
'\n'
)
#
Run
batched
inference
on
all
images
in
the
test
directory
results
=
model
.
predict
(
imagefiles
)
#
Save
the
YOLO
labels
output_dir
=
'predictions'
save_yolo_labels
(
results
,
output_dir
)
#
Display
results
#
display
all
predictions
result_directory
=
"predictions"
#
Get
a
list
of
all
image
files
in
the
result
directory
resultimages
=
glob
(
os
.
path
.
join
(
result_directory
,
"*.png"
))
for
image
in
resultimages
:
display
(
Image
.
open
(
image
))
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment