def save_output_image(image_np, image_path, coil_id): """ Saves the analyzed image into the output coil folder (containing the analyzed coil info) args: image_np: analyzed image in a numpy array image_path: path not-yet-analyzed image. From this the name of the image is obtained coil_id: name of the coil to which the image belongs. Used to generate the output folder name and path returns: True if the image was successfully saved False in opposite case. """ if not os.path.isdir( get_current_config_json()['config']['path_to_output_folders']): os.makedirs( get_current_config_json()['config']['path_to_output_folders']) output_image_name = os.path.basename(image_path) output_folder_path = os.path.join( get_current_config_json()['config']['path_to_output_folders'], os.path.basename(os.path.dirname(image_path)) + get_current_config_json()['config']['output_folder_suffix']) output_image_path = os.path.join(output_folder_path, output_image_name) if not os.path.isdir(output_folder_path): os.makedirs(output_folder_path) if cv2.imwrite(output_image_path, image_np): print(f'\nImage {output_image_name} SAVED in {output_image_path}') return True else: print(f'Error while saving {output_image_name} in {output_image_path}') return False
def save_post_json_and_save_in_output_folder(): post_json['coil'] = coil.__dict__ path_to_post_json_folder = os.path.join( get_current_config_json()['config']['path_to_output_folders'], os.path.basename(coil.path) + get_current_config_json()['config']['output_folder_suffix']) path_to_post_json = os.path.join(path_to_post_json_folder, 'post.json') if not os.path.isdir(path_to_post_json_folder): os.makedirs(path_to_post_json_folder) with open(path_to_post_json, 'w') as f: json.dump(post_json, f, indent=2) return path_to_post_json
def get_unregistered_coils_in_path( path=get_current_config_json()['config']['path_coils_folder']): """ Returns a dict containing the coils in the passed path, that are not in the register arg: path to the folder that contains coil folders returns None if there are no unregistered coils""" coils_in_register_list = get_coils_in_register() coils_in_path_list = get_coils_in_folder( get_current_config_json()['config']['path_coils_folder']) unregistered_coils_list = [ coil_path for coil_path in coils_in_path_list if all(coil_path.id != register_coil.id for register_coil in coils_in_register_list) ] return unregistered_coils_list if len(unregistered_coils_list) else None
def load_default_thresholds(): path_to_labels_json = get_current_config_json( )['config']['path_to_labels_json'] default_thresholds_dict = defaultdict(lambda: defaultdict()) with open(path_to_labels_json) as f: labels_json = json.load(f) for item in labels_json['items']: default_thresholds_dict[item['name']] = 1 * 10**9 with open(get_current_config_json()['config'] ['path_to_current_config_json']) as f: current_config_json = json.load(f) current_config_json['thresholds'] = default_thresholds_dict with open( get_current_config_json()['config']['path_to_current_config_json'], 'w') as g: json.dump(current_config_json, g, indent=2)
def analyze_single_image(image_path): # global detection_graph, category_index image = Image.open(image_path).convert('RGB') # res_w = 800 # res_h = 595 # image = image.resize((res_w, res_h)) # the array based representation of the image will be used later in order to prepare the # result image with boxes and labels on it. image_np = load_image_into_numpy_array(image) # Expand dimensions since the model expects images to have shape: [1, None, None, 3] image_np_expanded = np.expand_dims(image_np, axis=0) # Actual detection. output_dict = run_inference_for_single_image(image_np_expanded, detection_graph) # Visualization of the results of a detection. image_np, image_boxes_json = vis_util.visualize_boxes_and_labels_on_image_array( image_np, output_dict['detection_boxes'], output_dict['detection_classes'], output_dict['detection_scores'], category_index, instance_masks=output_dict.get('detection_masks'), use_normalized_coordinates=True, line_thickness=8, const_cm=get_current_config_json()['config']['const_px_cm']) print(f'Analyzed {image_path}') return image_np, image_boxes_json
def update_coil_register(coil_list): """ Create a JSON file containing the coils that are in the folder before the analysis starts. Those coils are not supposed to be analyzed args: Coil object list return: True if succeed in creating register""" if not os.path.isdir(get_current_config_json()['config'] ['path_to_current_coil_register_folder']): os.makedirs(get_current_config_json()['config'] ['path_to_current_coil_register_folder']) with open( get_current_config_json()['config'] ['path_to_current_coil_register_json'], 'w') as f: json.dump(coil_list_to_json(coil_list), f, indent=2) return True
def get_images_paths_in_path(path): """ return the paths of the images in the path. Possible extensions are specified in input_images_formats lists""" images_in_path = [ os.path.join(path, file) for file in os.listdir(path) if any( file.endswith(ext) for ext in eval( get_current_config_json()['config']['input_images_formats'])) ] return images_in_path if len(images_in_path) else None
def scan_path(): def check_folder_date_conditions(coil_folder): """ Return True if the coil folder date satisfies the minor date in the config. Retrun False otherwise """ folder_dd, folder_mm, folder_yyyy = [ int(d) for d in item.split('-')[1].split('_') ] folder_hour, folder_min, folder_sec = [ int(d) for d in item.split('-')[1].split('_') ] if folder_dd >= config_dd and folder_mm >= config_mm and folder_yyyy >= config_yyyy and folder_hour >= config_hour and folder_min >= config_min and folder_sec >= config_sec: return True else: return False # start print(f'Scanning {path} ...') # dates to compare with config_yyyy, config_mm, config_dd = [ int(element) for element in get_current_config_json()['config'] ['starting_date'].split('/') ] config_hour, config_min, config_sec = [ int(element) for element in get_current_config_json()['config'] ['starting_time'].split(':') ] # elements to evaluate (coil folders if they are so) elements_in_path = os.listdir(path) cant = len(elements_in_path) # path evaluation -> web inspector formatted & minimum date condition for i, item in enumerate(elements_in_path): if check_web_inspector_format( item) and check_folder_date_conditions(item): status = i * 100 / cant coil_list.append( create_coil_from_coil_path(os.path.join(path, item))) if not i % 100: print(f'Scan Status {int(status)}%\tFiles: {i} of {cant}') if status >= 100: print('Finish Scan')
def evaluate_thresholds(): for category in coil.areas: if coil.areas[category] > get_current_config_json( )['thresholds'][category]: overpassed_categories.append(category) if overpassed_categories: return True else: return False
def get_coils_in_register(): """ Reads the register and returns a list with the coils in it args: register path (default register is set) return: coil object list """ with open(get_current_config_json()['config'] ['path_to_current_coil_register_json']) as f: register = json.load(f) coils_in_register = json_to_coil_list(register) if register else [] return coils_in_register # list of Coil-type elements
def send_email_if_corresponds(coil): """ Evaluate thresholds and send email if overpassed """ overpassed_categories = [] def evaluate_thresholds(): for category in coil.areas: if coil.areas[category] > get_current_config_json( )['thresholds'][category]: overpassed_categories.append(category) if overpassed_categories: return True else: return False if evaluate_thresholds(): receivers = [rx for rx in get_current_config_json()['emails']] message = f"Area Limite de los defectos: {overpassed_categories} superado." + f"{[categ + ' area: ' + str(int(coil.areas[categ])) + ' cm2 and the limit is: ' + str(get_current_config_json()['thresholds'][categ]) for categ in coil.areas]} " for mail_to in get_current_config_json()['emails'].split(','): send_report(subject='Aviso de limite de superficie superado', body=message, fromaddr='*****@*****.**', toaddr=mail_to, filename='', attachment_path='')
def start_app(): """ Contains the app flow """ current_config_json = get_current_config_json() unregistered_coils_list = get_unregistered_coils_in_path( current_config_json['config']['path_coils_folder']) if unregistered_coils_list: print( f'New unregistered folders {[coil.id for coil in unregistered_coils_list]}' ) analyze_coil_list(unregistered_coils_list) else: print('No new coils') app_timer = threading.Timer( current_config_json['config']['scan_timer_delay'], start_app).start()
def home(data=None): def get_categories_and_areas(): area_dicts_for_all_coilposts = [ eval(el.areas) for el in Coil_post.query.order_by(Coil_post.date_posted.desc()) ] categories = [[categ for categ in area_dict] for area_dict in area_dicts_for_all_coilposts] areas = [[int(mydict[val]) for val in mydict] for mydict in area_dicts_for_all_coilposts] return categories, areas page = request.args.get('page', 1, type=int) post_per_page = get_current_config_json()['config']['post_per_page'] posts = Coil_post.query.order_by(Coil_post.date_posted.desc()).paginate( page=page, per_page=post_per_page) categories_per_coil, areas_per_coil = get_categories_and_areas() data = {} data['title'] = 'Chart' return render_template('home.html', data=data, posts=posts, title='Defect Analyzer')
def analyze_coil_if_coildate_greaterthan_starting_date(): # converting format to datetime date_to_compare_list = get_current_config_json( )['config']['starting_date'].split('/') coil_date_to_compare_list = coil.date.split('/') d_comp = datetime.datetime(day=int(date_to_compare_list[2]), month=int(date_to_compare_list[1]), year=int(date_to_compare_list[0])) d_coil = datetime.datetime(day=int(coil_date_to_compare_list[0]), month=int(coil_date_to_compare_list[1]), year=int(coil_date_to_compare_list[2])) # comparison if d_coil >= d_comp: if coil.image_list: for image_path in coil.image_list: # analyze image output_image_np, image_boxes_json = analyze_single_image( image_path) # update areas update_area_by_defect(image_boxes_json) # save image if len(image_boxes_json['detections']): save_output_image(output_image_np, image_path, coil.id)
def init_register(): create_folder_if_missing( get_current_config_json()['config']['path_coils_folder']) coils_in_folder = get_coils_in_folder( get_current_config_json()['config']['path_coils_folder']) update_coil_register(coils_in_folder)
def edit_backend_config( ): # no argument config_id argument because the idea is edit the ONLY config form = BackendConfigForm() if form.validate_on_submit(): new_config = Backend_config( input_images_formats=form.input_images_formats.data, path_coils_folder=form.path_coils_folder.data, output_folder_suffix=form.output_folder_suffix.data, scan_timer_delay=form.scan_timer_delay.data, path_to_labels=form.path_to_labels.data, path_to_frozen_graph=form.path_to_frozen_graph.data, path_to_current_coil_register_folder=form. path_to_current_coil_register_folder.data, path_to_current_coil_register_json=form. path_to_current_coil_register_json.data, path_to_output_folders=form.path_to_output_folders.data, path_to_current_config_folder=form.path_to_current_config_folder. data, path_to_current_config_json=form.path_to_current_config_json.data, path_to_previous_config_folder=form.path_to_previous_config_folder. data, path_to_previous_config_file=form.path_to_previous_config_file. data, path_to_default_config_folder=form.path_to_default_config_folder. data, path_to_default_config_json=form.path_to_default_config_json.data, post_per_page=form.post_per_page.data, starting_date=form.starting_date.data, starting_time=form.starting_time.data, const_px_cm=form.const_px_cm.data, emails=form.emails.data, thresholds=form.thresholds.data) update_config(new_config.__dict__) flash('The configuration has been updated', 'success') return redirect(url_for('backend_config_blueprint.backend_config')) current_config_json = get_current_config_json() form.input_images_formats.data = current_config_json['config'][ 'input_images_formats'] form.path_coils_folder.data = current_config_json['config'][ 'path_coils_folder'] form.output_folder_suffix.data = current_config_json['config'][ 'output_folder_suffix'] form.scan_timer_delay.data = current_config_json['config'][ 'scan_timer_delay'] form.path_to_labels.data = current_config_json['config']['path_to_labels'] form.path_to_frozen_graph.data = current_config_json['config'][ 'path_to_frozen_graph'] form.path_to_current_coil_register_folder.data = current_config_json[ 'config']['path_to_current_coil_register_folder'] form.path_to_current_coil_register_json.data = current_config_json[ 'config']['path_to_current_coil_register_json'] form.path_to_output_folders.data = current_config_json['config'][ 'path_to_output_folders'] form.path_to_current_config_folder.data = current_config_json['config'][ 'path_to_current_config_folder'] form.path_to_current_config_json.data = current_config_json['config'][ 'path_to_current_config_json'] form.path_to_previous_config_folder.data = current_config_json['config'][ 'path_to_previous_config_folder'] form.path_to_previous_config_file.data = current_config_json['config'][ 'path_to_previous_config_file'] form.path_to_default_config_folder.data = current_config_json['config'][ 'path_to_default_config_folder'] form.path_to_default_config_json.data = current_config_json['config'][ 'path_to_default_config_json'] form.post_per_page.data = current_config_json['config']['post_per_page'] form.starting_date.data = current_config_json['config']['starting_date'] form.starting_time.data = current_config_json['config']['starting_time'] form.const_px_cm.data = current_config_json['config']['const_px_cm'] form.emails.data = current_config_json['emails'] form.thresholds.data = current_config_json['thresholds'] return render_template('edit_backend_config.html', title='Edit Config', form=form, legend='Edit Config')
import numpy as np import tensorflow.compat.v1 as tf from PIL import Image from Defect_analyzer_back.resources.object_detection.utils import label_map_util import Defect_analyzer_back.resources.visualization_utils_fb as vis_util from Defect_analyzer_back.resources.config.configs_utils import get_current_config_json from Defect_analyzer_back.resources.object_detection.utils import ops as utils_ops import os current_config_json = get_current_config_json() detection_graph = tf.Graph() with detection_graph.as_default(): od_graph_def = tf.GraphDef() #od_graph_def = tf.compat.v1.GraphDef() #with tf.compat.v2.io.gfile.GFile(current_config_json['config']['path_to_frozen_graph'], 'rb') as fid: with tf.gfile.GFile(current_config_json['config']['path_to_frozen_graph'], 'rb') as fid: serialized_graph = fid.read() od_graph_def.ParseFromString(serialized_graph) tf.import_graph_def(od_graph_def, name='') category_index = label_map_util.create_category_index_from_labelmap( current_config_json['config']['path_to_labels'], use_display_name=True) def load_image_into_numpy_array(image): (im_width, im_height) = image.size return np.array(image.getdata()).reshape( (im_height, im_width, 3)).astype(np.uint8)