Source code for detector_aedes.detector_aedes

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""One liner

Description....
"""

from __future__ import unicode_literals
from __future__ import print_function
from __future__ import with_statement


import matplotlib.pyplot as plt
import os
import numpy as np
import warnings
from analyzers import StickAnalizerHough, EllipseFinder


[docs]class AedesDetector(): """Detector de Huevos en Ovisensores. `AedesDetector(input_connector, output_connector)` Algoritmos de vision computacional para reconocer la presencia de huevos en fotos de ovisensores. Args: input_connector (:obj:): Conector a la fuente de imagenes a analizar. output_connector (:obj:): Conector a la salida de los resulados del análisis. """ def __init__(self, input_connector, output_connector=None): self.input_connector = input_connector self.output_connector = output_connector self.stick_analizer = StickAnalizerHough() self.egg_finder = EllipseFinder()
[docs] def process(self, image_id=None, show_results=False, start_from=0, ): """Función principal para procesar las imágenes disponibles. Args: image_id (str, optional): Este parametro debe corresponder al ID de una imagen. Si está definido se procesa solo esa imagen. show_results (bool, optional): Mostrar un gráfico del procesamiento para cada imagen a medida que se procesan. start_from (int, optional): Comienza a analizar a partir de la imagen `start_from`-ésima imagen. """ if image_id: self._process_one_image(image_id) if show_results: self.plot_classification() else: image_ids = self.input_connector.get_image_ids() for image_id in image_ids[start_from:]: print('Procesando {:s}'.format(image_id)) self._process_one_image(image_id) if show_results: self.plot_classification()
def _process_one_image(self, image_id): """ Función interna para procesar una sola imagen. _process_one_image(self, image_id) Args: image_id (str): Debe corresponder a un ID de imagen en el `input_connector` """ image = self.input_connector.get_image(image_id) self.image = image if image is None: warnings.warn("La imagen {:s} no pudo ser cargada" .format(image_id)) self.stick_analizer.set_current_image(image) self.stick_status, self.stick_limits = self.stick_analizer.get_limits() if self.stick_status != 'Sin bajalenguas': finder_status, egg_props = self.egg_finder.find_in(image, limits=self.stick_limits, show_settings=True) self.finder_status = finder_status if finder_status in ['Status OK', 'Early stop']: self.egg_props = egg_props self.classify(method='Thresholds') else: self.egg_count = None self.doubt_count = None self.output_connector.write_output(image_id, self.stick_status + ' / ' + finder_status, self.egg_count, self.doubt_count) print(self.egg_count) else: print(self.stick_status) self.output_connector.write_output(image_id, self.stick_status, None, None)
[docs] def classify(self, method='Threshods'): centroids_i, centroids_j, correlations, contrasts, aspects = self.egg_props.T self.centroids = zip(centroids_i, centroids_j) self.good_points = (correlations > 0.8) & (contrasts > 0.3) self.semi_points = (correlations > 0.8) & (contrasts <= 0.3) self.egg_count = np.sum(self.good_points) self.doubt_count = np.sum(self.semi_points)
# FUNCION DE ENTRENAMIENTO DEL CLASIFICADOR (DEPRECADO) # def train_model(self, trainsamples=None, show_mask=False): # self.egg_finder.start_trainning() # if isinstance(trainsamples, list): # samples = trainsamples # else: # im_ids = self.input_connector.get_image_ids() # if len(im_ids) < trainsamples: # raise ValueError('No hay suficientes imagenes para entrenar.\ # (Nfiles=%i)' % len(im_ids)) # samples = np.random.choice(im_ids, trainsamples, # replace=False) # Imagenes al azar # for im_id in samples: # image = self.input_connector.get_image(im_id) # self.stick_analizer.set_current_image(image) # self.clipped_image = self.stick_analizer.get_clipped_image() # self.egg_finder.find_in(self.clipped_image) # self.plot_selector(show_mask=show_mask) # self.egg_finder.save_model() def _handle_fig_event(self, event): "Función interna para manejar eventos de ventanas en modo interactivo." if event.key != 'n': self.next_figure = False else: self.next_figure = True def _onpick(self, event): "Función interna para manejar eventos de ventanas en modo interactivo." event.artist._edgecolors[event.ind, :] = (0, 0, 1, 1) self.temp_targets[event.ind] = 1
[docs] def plot_classification(self): "Graficar la clasificacion par una dada imágen" if self.stick_status == 'Sin bajalenguas': print("No puedo graficar: " + self.stick_status) return if self.finder_status != 'Status OK': print("No puedo graficar: " + self.finder_status) return if not hasattr(self, 'fig'): self.fig = plt.figure() self.fig.canvas.mpl_connect('key_press_event', self._handle_fig_event) self.fig.canvas.mpl_connect('button_press_event', self._handle_fig_event) self.next_figure = False self.fig.clf() ax = self.fig.add_subplot(121) ax.set_title('Presione N para continuar analizando la proxima foto.') ax.imshow(self.image) if self.stick_limits: count = -1 for angle, dist in zip(*self.stick_limits): count += 1 dist = dist * np.amin(self.image.shape[:2]) y0 = (dist - 0 * np.cos(angle)) / np.sin(angle) y1 = (dist - self.image.shape[1] * np.cos(angle)) / np.sin(angle) ax.plot((0, self.image.shape[1]), (y0, y1), '-', color=['r', 'g'][count], linewidth=0.5) if len(self.centroids) > 0: centers = np.vstack(self.centroids) ax.scatter(centers[self.good_points, 1], centers[self.good_points, 0], s=80, marker='x', color='r') ax.scatter(centers[self.semi_points, 1], centers[self.semi_points, 0], s=80, marker='x', color='y') # for c, q, cont in zip(centers, self.good_points, self.egg_props[2]): # if q: # ax.text(c[1], c[0], cont) ax2 = self.fig.add_subplot(122) ax2.plot(self.egg_props[:, 2], self.egg_props[:, 3], '.') self.fig.canvas.draw() while not self.next_figure: self.fig.waitforbuttonpress()
[docs] def plot_selector(self, show_mask=False): """Graficar los puntos candidatos y permitir al usuario elegir los positivos. USO: - Hacer click sobre todos los candidatos considerados positivos (van a cambiar de color). - Apretar N para pasar a la imagen siguiente """ self.temp_targets = np.zeros(len(self.egg_finder.measures)) if not hasattr(self, 'fig'): self.fig = plt.figure() self.fig.canvas.mpl_connect('key_press_event', self._handle_fig_event) self.fig.canvas.mpl_connect('button_press_event', self._handle_fig_event) self.fig.canvas.mpl_connect('pick_event', self._onpick) self.fig.suptitle(('Haga click en los objetivos. Apriete N para', 'pasar a la siguiente imagen.')) self.next_figure = False self.good_points = [] self.fig.clf() ax = self.fig.add_subplot(111) ax.imshow(self.clipped_image) if show_mask: ax.imshow(self.egg_finder.mask, alpha=0.5) colors = np.array(['r', 'y']) ax.scatter(self.egg_finder.measures[:, -2], self.egg_finder.measures[:, -1], facecolors='none', s=80, alpha=0.5, color=colors[self.egg_finder.type], picker=5 ) self.fig.canvas.draw() while not self.next_figure: self.fig.waitforbuttonpress() self.fig.canvas.draw() self.egg_finder.push_user_input(self.egg_finder.measures, self.temp_targets)