mirror of
https://github.com/azaion/annotations.git
synced 2026-04-22 10:46:30 +00:00
fix loader bug with _CACHED_HW_INFO
put tile size to name and set it dynamically for AI recognition
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
cdef class AIRecognitionConfig:
|
||||
|
||||
cdef public double frame_recognition_seconds
|
||||
cdef public int frame_period_recognition
|
||||
cdef public double probability_threshold
|
||||
@@ -8,6 +9,7 @@ cdef class AIRecognitionConfig:
|
||||
cdef public double tracking_intersection_threshold
|
||||
|
||||
cdef public int big_image_tile_overlap_percent
|
||||
cdef public int tile_size
|
||||
|
||||
cdef public bytes file_data
|
||||
cdef public list[str] paths
|
||||
|
||||
@@ -9,11 +9,13 @@ cdef class AIRecognitionConfig:
|
||||
tracking_distance_confidence,
|
||||
tracking_probability_increase,
|
||||
tracking_intersection_threshold,
|
||||
big_image_tile_overlap_percent,
|
||||
|
||||
file_data,
|
||||
paths,
|
||||
model_batch_size
|
||||
model_batch_size,
|
||||
|
||||
big_image_tile_overlap_percent,
|
||||
tile_size
|
||||
):
|
||||
self.frame_period_recognition = frame_period_recognition
|
||||
self.frame_recognition_seconds = frame_recognition_seconds
|
||||
@@ -22,12 +24,14 @@ cdef class AIRecognitionConfig:
|
||||
self.tracking_distance_confidence = tracking_distance_confidence
|
||||
self.tracking_probability_increase = tracking_probability_increase
|
||||
self.tracking_intersection_threshold = tracking_intersection_threshold
|
||||
self.big_image_tile_overlap_percent = big_image_tile_overlap_percent
|
||||
|
||||
self.file_data = file_data
|
||||
self.paths = paths
|
||||
self.model_batch_size = model_batch_size
|
||||
|
||||
self.big_image_tile_overlap_percent = big_image_tile_overlap_percent
|
||||
self.tile_size = tile_size
|
||||
|
||||
def __str__(self):
|
||||
return (f'frame_seconds : {self.frame_recognition_seconds}, distance_confidence : {self.tracking_distance_confidence}, '
|
||||
f'probability_increase : {self.tracking_probability_increase}, '
|
||||
@@ -48,9 +52,11 @@ cdef class AIRecognitionConfig:
|
||||
unpacked.get("t_dc", 0.0),
|
||||
unpacked.get("t_pi", 0.0),
|
||||
unpacked.get("t_it", 0.0),
|
||||
unpacked.get("ov_p", 20),
|
||||
|
||||
unpacked.get("d", b''),
|
||||
unpacked.get("p", []),
|
||||
unpacked.get("m_bs")
|
||||
unpacked.get("m_bs"),
|
||||
|
||||
unpacked.get("ov_p", 20),
|
||||
unpacked.get("tile_size", 550),
|
||||
)
|
||||
@@ -18,8 +18,6 @@ cdef class Inference:
|
||||
cdef str model_input
|
||||
cdef int model_width
|
||||
cdef int model_height
|
||||
cdef int tile_width
|
||||
cdef int tile_height
|
||||
|
||||
cdef bytes get_onnx_engine_bytes(self)
|
||||
cdef init_ai(self)
|
||||
@@ -30,7 +28,7 @@ cdef class Inference:
|
||||
cdef _process_video(self, RemoteCommand cmd, AIRecognitionConfig ai_config, str video_name)
|
||||
cdef _process_images(self, RemoteCommand cmd, AIRecognitionConfig ai_config, list[str] image_paths)
|
||||
cdef _process_images_inner(self, RemoteCommand cmd, AIRecognitionConfig ai_config, list frame_data)
|
||||
cdef split_to_tiles(self, frame, path, overlap_percent)
|
||||
cdef split_to_tiles(self, frame, path, tile_size, overlap_percent)
|
||||
cdef stop(self)
|
||||
|
||||
cdef preprocess(self, frames)
|
||||
|
||||
@@ -58,8 +58,6 @@ cdef class Inference:
|
||||
self.model_input = None
|
||||
self.model_width = 0
|
||||
self.model_height = 0
|
||||
self.tile_width = 0
|
||||
self.tile_height = 0
|
||||
self.engine = None
|
||||
self.is_building_engine = False
|
||||
self.ai_availability_status = AIAvailabilityStatus()
|
||||
@@ -107,15 +105,11 @@ cdef class Inference:
|
||||
self.is_building_engine = False
|
||||
|
||||
self.model_height, self.model_width = self.engine.get_input_shape()
|
||||
#todo: temporarily, send it from the client
|
||||
self.tile_width = 550
|
||||
self.tile_height = 550
|
||||
except Exception as e:
|
||||
self.ai_availability_status.set_status(AIAvailabilityEnum.ERROR, <str>str(e))
|
||||
self.is_building_engine = False
|
||||
|
||||
|
||||
|
||||
cdef preprocess(self, frames):
|
||||
blobs = [cv2.dnn.blobFromImage(frame,
|
||||
scalefactor=1.0 / 255.0,
|
||||
@@ -277,7 +271,7 @@ cdef class Inference:
|
||||
if img_h <= 1.5 * self.model_height and img_w <= 1.5 * self.model_width:
|
||||
frame_data.append((frame, original_media_name, f'{original_media_name}_000000'))
|
||||
else:
|
||||
res = self.split_to_tiles(frame, path, ai_config.big_image_tile_overlap_percent)
|
||||
res = self.split_to_tiles(frame, path, ai_config.tile_size, ai_config.big_image_tile_overlap_percent)
|
||||
frame_data.extend(res)
|
||||
if len(frame_data) > self.engine.get_batch_size():
|
||||
for chunk in self.split_list_extend(frame_data, self.engine.get_batch_size()):
|
||||
@@ -287,31 +281,31 @@ cdef class Inference:
|
||||
self._process_images_inner(cmd, ai_config, chunk)
|
||||
|
||||
|
||||
cdef split_to_tiles(self, frame, path, overlap_percent):
|
||||
cdef split_to_tiles(self, frame, path, tile_size, overlap_percent):
|
||||
constants_inf.log(<str>f'splitting image {path} to tiles...')
|
||||
img_h, img_w, _ = frame.shape
|
||||
stride_w = int(self.tile_width * (1 - overlap_percent / 100))
|
||||
stride_h = int(self.tile_height * (1 - overlap_percent / 100))
|
||||
stride_w = int(tile_size * (1 - overlap_percent / 100))
|
||||
stride_h = int(tile_size * (1 - overlap_percent / 100))
|
||||
|
||||
results = []
|
||||
original_media_name = Path(<str> path).stem.replace(" ", "")
|
||||
for y in range(0, img_h, stride_h):
|
||||
for x in range(0, img_w, stride_w):
|
||||
x_end = min(x + self.tile_width, img_w)
|
||||
y_end = min(y + self.tile_height, img_h)
|
||||
x_end = min(x + tile_size, img_w)
|
||||
y_end = min(y + tile_size, img_h)
|
||||
|
||||
# correct x,y for the close-to-border tiles
|
||||
if x_end - x < self.tile_width:
|
||||
if img_w - (x - stride_w) <= self.tile_width:
|
||||
if x_end - x < tile_size:
|
||||
if img_w - (x - stride_w) <= tile_size:
|
||||
continue # the previous tile already covered the last gap
|
||||
x = img_w - self.tile_width
|
||||
if y_end - y < self.tile_height:
|
||||
if img_h - (y - stride_h) <= self.tile_height:
|
||||
x = img_w - tile_size
|
||||
if y_end - y < tile_size:
|
||||
if img_h - (y - stride_h) <= tile_size:
|
||||
continue # the previous tile already covered the last gap
|
||||
y = img_h - self.tile_height
|
||||
y = img_h - tile_size
|
||||
|
||||
tile = frame[y:y_end, x:x_end]
|
||||
name = f'{original_media_name}{constants_inf.SPLIT_SUFFIX}{x:04d}_{y:04d}!_000000'
|
||||
name = f'{original_media_name}{constants_inf.SPLIT_SUFFIX}{tile_size:04d}{x:04d}_{y:04d}!_000000'
|
||||
results.append((tile, original_media_name, name))
|
||||
return results
|
||||
|
||||
@@ -337,14 +331,15 @@ cdef class Inference:
|
||||
cdef remove_tiled_duplicates(self, Annotation annotation):
|
||||
right = annotation.name.rindex('!')
|
||||
left = annotation.name.index(constants_inf.SPLIT_SUFFIX) + len(constants_inf.SPLIT_SUFFIX)
|
||||
x_str, y_str = annotation.name[left:right].split('_')
|
||||
tile_size_str, x_str, y_str = annotation.name[left:right].split('_')
|
||||
tile_size = int(tile_size_str)
|
||||
x = int(x_str)
|
||||
y = int(y_str)
|
||||
|
||||
for det in annotation.detections:
|
||||
x1 = det.x * self.tile_width
|
||||
y1 = det.y * self.tile_height
|
||||
det_abs = Detection(x + x1, y + y1, det.w * self.tile_width, det.h * self.tile_height, det.cls, det.confidence)
|
||||
x1 = det.x * tile_size
|
||||
y1 = det.y * tile_size
|
||||
det_abs = Detection(x + x1, y + y1, det.w * tile_size, det.h * tile_size, det.cls, det.confidence)
|
||||
detections = self._tile_detections.setdefault(annotation.original_media_name, [])
|
||||
if det_abs in detections:
|
||||
annotation.detections.remove(det)
|
||||
|
||||
@@ -37,7 +37,7 @@ cdef class CommandProcessor:
|
||||
continue
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
constants_inf.log('EXIT!')
|
||||
constants_inf.log(<str>'EXIT!')
|
||||
|
||||
cdef on_command(self, RemoteCommand command):
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user