예제 #1
0
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
예제 #2
0
 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
예제 #3
0
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
예제 #4
0
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)
예제 #5
0
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
예제 #6
0
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
예제 #7
0
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
예제 #8
0
    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')
예제 #9
0
 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
예제 #10
0
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
예제 #11
0
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='')
예제 #12
0
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()
예제 #13
0
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')
예제 #14
0
    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)
예제 #15
0
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)
예제 #16
0
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')
예제 #17
0
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)