@ -1,41 +1,42 @@
"""
Tool to load model and binarize a given image .
"""
import argparse
import sys
from glob import glob
from os import environ , devnull
from os. path import join
from warnings import catch_warnings , simplefilter
from pathlib import Path
from typing import Union
import numpy as np
from PIL import Image
import cv2
import numpy as np
environ [ ' TF_CPP_MIN_LOG_LEVEL ' ] = ' 3 '
stderr = sys . stderr
sys . stderr = open ( devnull , ' w ' )
import tensorflow as tf
from tensorflow . keras . models import load_model
from tensorflow . python . keras import backend as tensorflow_backend
sys . stderr = stderr
sys . stderr = stderr
import logging
def resize_image ( img_in , input_height , input_width ) :
return cv2 . resize ( img_in , ( input_width , input_height ) , interpolation = cv2 . INTER_NEAREST )
class SbbBinarizer :
def __init__ ( self , model_dir , logger = None ) :
self . model_dir = model_dir
def __init__ ( self , model_dir : Union [ str , Path ] , logger = None ) :
model_dir = Path( model_dir)
self . log = logger if logger else logging . getLogger ( ' SbbBinarizer ' )
self . start_new_session ( )
self . model_files = glob ( ' %s /*.h5 ' % self . model_dir )
self . model_files = list ( [ str ( p . absolute ( ) ) for p in model_dir . rglob ( " *.h5 " ) ] )
if not self . model_files :
raise ValueError ( f " No models found in { self . model_dir } " )
raise ValueError ( f " No models found in { str ( model_dir ) } " )
self . models = [ ]
for model_file in self . model_files :
@ -53,8 +54,8 @@ class SbbBinarizer:
self . session . close ( )
del self . session
def load_model ( self , model_ name ) :
model = load_model ( model_ name , compile = False )
def load_model ( self , model_ path: str ) :
model = load_model ( model_ path , compile = False )
model_height = model . layers [ len ( model . layers ) - 1 ] . output_shape [ 1 ]
model_width = model . layers [ len ( model . layers ) - 1 ] . output_shape [ 2 ]
n_classes = model . layers [ len ( model . layers ) - 1 ] . output_shape [ 3 ]
@ -97,11 +98,8 @@ class SbbBinarizer:
index_start_w = 0
img_padded = np . copy ( img )
img = np . copy ( img_padded )
if use_patches :
margin = int ( 0.1 * model_width )
@ -109,7 +107,6 @@ class SbbBinarizer:
width_mid = model_width - 2 * margin
height_mid = model_height - 2 * margin
img = img / float ( 255.0 )
img_h = img . shape [ 0 ]
@ -225,8 +222,6 @@ class SbbBinarizer:
mask_true [ index_y_d + margin : index_y_u - margin , index_x_d + margin : index_x_u - margin ] = seg
prediction_true [ index_y_d + margin : index_y_u - margin , index_x_d + margin : index_x_u - margin , : ] = seg_color
prediction_true = prediction_true [ index_start_h : index_start_h + img_org_h , index_start_w : index_start_w + img_org_w , : ]
prediction_true = prediction_true . astype ( np . uint8 )
@ -245,14 +240,13 @@ class SbbBinarizer:
return prediction_true [ : , : , 0 ]
def run ( self , image = None , image_path = None , save = None , use_patches = False ) :
if ( image is not None and image_path is not None ) or \
( image is None and image_path is None ) :
if ( image is not None and image_path is not None ) or ( image is None and image_path is None ) :
raise ValueError ( " Must pass either a opencv2 image or an image_path " )
if image_path is not None :
image = cv2 . imread ( image_path )
img_last = 0
for n , ( model , model_file ) in enumerate ( zip ( self . models , self . model_files ) ) :
self . log . info ( ' Predicting with model %s [ %s / %s ] ' % ( model_file , n + 1 , len ( self . model_files ) ) )
self . log . info ( f" Predicting with model { model_file } [ { n + 1 } / { len ( self . model_files ) } ] " )
res = self . predict ( model , image , use_patches )
@ -272,5 +266,7 @@ class SbbBinarizer:
img_last [ : , : ] [ img_last [ : , : ] > 0 ] = 255
img_last = ( img_last [ : , : ] == 0 ) * 255
if save :
# Create the output directory (and if necessary it's parents) if it doesn't exist already
Path ( save ) . parent . mkdir ( parents = True , exist_ok = True )
cv2 . imwrite ( save , img_last )
return img_last