Files
cours-ai-tutorials/Tensorflow/tutoriel27/common.py
2026-03-31 13:28:59 +02:00

202 lines
6.7 KiB
Python

import tensorflow as tf
from tensorflow.keras import layers, models
import json
import random
import cv2
import numpy as np
import math
import config
def sigmoid(x):
x=np.clip(x, -50, 50)
return 1/(1+np.exp(-x))
def softmax(x):
e=np.exp(x)
e_sum=np.sum(e)
return e/e_sum
def prepare_image(image, labels, grille=True):
img=image.copy()
if grille is True:
for x in range(config.r_x, config.largeur+config.r_x, config.r_x):
for y in range(config.r_y, config.hauteur+config.r_y, config.r_y):
cv2.line(img, (0, y), (x, y), (0, 0, 0), 1)
cv2.line(img, (x, 0), (x, y), (0, 0, 0), 1)
for y in range(config.cellule_y):
for x in range(config.cellule_x):
for box in range(config.nbr_boxes):
if labels[y, x, box, 4]:
ids=np.argmax(labels[y, x, box, 5:])
x_center=int(labels[y, x, box, 0]*config.r_x)
y_center=int(labels[y, x, box, 1]*config.r_y)
w_2=int(labels[y, x, box, 2]*config.r_x/2)
h_2=int(labels[y, x, box, 3]*config.r_y/2)
x_min=x_center-w_2
y_min=y_center-h_2
x_max=x_center+w_2
y_max=y_center+h_2
cv2.rectangle(img, (x_min, y_min), (x_max, y_max), list(config.dict.values())[ids], 1)
cv2.circle(img, (x_center, y_center), 1, list(config.dict.values())[ids], 2)
return img
def bruit(image):
h, w, c=image.shape
n=np.random.randn(h, w, c)*random.randint(5, 30)
return np.clip(image+n, 0, 255).astype(np.uint8)
def gamma(image, alpha=1.0, beta=0.0):
return np.clip(alpha*image+beta, 0, 255).astype(np.uint8)
def intersection_over_union(boxA, boxB):
xA=np.maximum(boxA[0], boxB[0])
yA=np.maximum(boxA[1], boxB[1])
xB=np.minimum(boxA[2], boxB[2])
yB=np.minimum(boxA[3], boxB[3])
interArea=np.maximum(0, xB-xA)*np.maximum(0, yB-yA)
boxAArea=(boxA[2]-boxA[0])*(boxA[3]-boxA[1])
boxBArea=(boxB[2]-boxB[0])*(boxB[3]-boxB[1])
return interArea/(boxAArea+boxBArea-interArea)
def prepare_labels(fichier_image, objects, coeff=None):
image=cv2.imread(fichier_image)
######################
trophozoite=0
for o in objects:
if config.dict2.index(o['category'])==4:
trophozoite=1
break
if trophozoite==0:
return None, None, None
######################
if coeff is None:
coeff=random.uniform(1.1, 2.5)
image_r=cv2.resize(image, (int(coeff*config.largeur), int(coeff*config.hauteur)))
image_r=gamma(image_r, random.uniform(0.7, 1.3), np.random.randint(60)-30)
image_r=bruit(image_r)
if coeff==1:
shift_x=0
shift_y=0
else:
shift_x=np.random.randint(image_r.shape[1]-config.largeur)
shift_y=np.random.randint(image_r.shape[0]-config.hauteur)
ratio_x=coeff*config.largeur/image.shape[1]
ratio_y=coeff*config.hauteur/image.shape[0]
flip=np.random.randint(4)
if flip!=3:
image_r=cv2.flip(image_r, flip-1)
label =np.zeros((config.cellule_y, config.cellule_x, config.nbr_boxes, 5+config.nbr_classes), dtype=np.float32)
label2=np.zeros((config.max_objet, 7), dtype=np.float32)
nbr_objet=0
for o in objects:
id_class=config.dict2.index(o['category'])
box=o['bounding_box']
if flip==3:
x_min=int(box['minimum']['c']*ratio_x)
y_min=int(box['minimum']['r']*ratio_y)
x_max=int(box['maximum']['c']*ratio_x)
y_max=int(box['maximum']['r']*ratio_y)
if flip==2:
x_min=int((image.shape[1]-box['maximum']['c'])*ratio_x)
y_min=int(box['minimum']['r']*ratio_y)
x_max=int((image.shape[1]-box['minimum']['c'])*ratio_x)
y_max=int(box['maximum']['r']*ratio_y)
if flip==1:
x_min=int(box['minimum']['c']*ratio_x)
y_min=int((image.shape[0]-box['maximum']['r'])*ratio_y)
x_max=int(box['maximum']['c']*ratio_x)
y_max=int((image.shape[0]-box['minimum']['r'])*ratio_y)
if flip==0:
x_min=int((image.shape[1]-box['maximum']['c'])*ratio_x)
y_min=int((image.shape[0]-box['maximum']['r'])*ratio_y)
x_max=int((image.shape[1]-box['minimum']['c'])*ratio_x)
y_max=int((image.shape[0]-box['minimum']['r'])*ratio_y)
if x_min<shift_x or y_min<shift_y or x_max>(shift_x+config.largeur) or y_max>(shift_y+config.hauteur):
continue
x_min=(x_min-shift_x)/config.r_x
y_min=(y_min-shift_y)/config.r_y
x_max=(x_max-shift_x)/config.r_x
y_max=(y_max-shift_y)/config.r_y
area=(x_max-x_min)*(y_max-y_min)
label2[nbr_objet]=[x_min, y_min, x_max, y_max, area, 1, id_class]
x_centre=int(x_min+(x_max-x_min)/2)
y_centre=int(y_min+(y_max-y_min)/2)
x_cell=int(x_centre)
y_cell=int(y_centre)
a_x_min=x_centre-config.anchors[:, 0]/2
a_y_min=y_centre-config.anchors[:, 1]/2
a_x_max=x_centre+config.anchors[:, 0]/2
a_y_max=y_centre+config.anchors[:, 1]/2
id_a=0
best_iou=0
for i in range(len(config.anchors)):
iou=intersection_over_union([x_min, y_min, x_max, y_max], [a_x_min[i], a_y_min[i], a_x_max[i], a_y_max[i]])
if iou>best_iou:
best_iou=iou
id_a=i
label[y_cell, x_cell, id_a, 0]=(x_max+x_min)/2
label[y_cell, x_cell, id_a, 1]=(y_max+y_min)/2
label[y_cell, x_cell, id_a, 2]=x_max-x_min
label[y_cell, x_cell, id_a, 3]=y_max-y_min
label[y_cell, x_cell, id_a, 4]=1.
label[y_cell, x_cell, id_a, 5+id_class]=1.
nbr_objet=nbr_objet+1
if nbr_objet==config.max_objet:
print("Nbr objet max atteind !!!!!")
break
######################
trophozoite=0
for y in range(config.cellule_y):
for x in range(config.cellule_x):
for b in range(config.nbr_boxes):
if np.argmax(label[y, x, b, 5:])==4:
trophozoite=1
if not trophozoite:
return None, None, None
######################
return image_r[shift_y:shift_y+config.hauteur, shift_x:shift_x+config.largeur], label, label2
def read_json(file, nbr=1, nbr_fichier=None):
images=[]
labels=[]
labels2=[]
with open(file) as json_file:
data=json.load(json_file)
id=0
for p in data:
print(id, p['image']['pathname'])
id+=1
for i in range(nbr):
image, label, label2=prepare_labels("./{}".format(p['image']['pathname']), p['objects'])
if image is not None:
images.append(image)
labels.append(label)
labels2.append(label2)
if nbr_fichier is not None:
if id==nbr_fichier:
break
images=np.array(images)
labels=np.array(labels)
labels2=np.array(labels2)
return images, labels, labels2