Package components.gps.imagebased

Source Code of components.gps.imagebased.ImageBasedGPS

package components.gps.imagebased;

import java.awt.Color;
import java.awt.image.BufferedImage;

import utils.Semaphore;
import utils.defines.Defines;
import utils.images.ImageUtils;
import utils.images.ImageUtilsException;
import utils.images.RecognizedShape;

import components.gps.GPS;
import components.gps.GPSException;
import components.gps.RecognizedItems;
import components.imagecollector.ImageCollector;
import components.imagecollector.webcam.WebcamImageCollector;
import components.robot.RobotState;

import core.simulation.Simulation;



/**
* Esta clase implementa un <i>GPS</i> basado en im�genes. Es decir,
* un sistema de posicionamiento que es capaz de obtener la posici�n
* de los objetos en base a un procesamiento de la imagen del escenario
* en ese instante.<br>
* Puede ser usado tanto en simulaciones reales como en virtuales.
*/
public class ImageBasedGPS extends GPS
{
 
  // Atributos
  private  BufferedImage          image;
  private ImageUtils            imageUtils;
  private ImageCollector           ic;
  private RecognizedShape          robot;
  private RecognizedShape[]        newRobot;
  private Semaphore            gpsSemaphore;
  private double              xOld, yOld;
  private boolean              realSimulation;
 
  // Constructor privado (por ser un singleton)
  public ImageBasedGPS()
  {
    super("WebCam GPS", "GPS a traves de una WebCam");
   
    imageUtils    = new ImageUtils();
    gpsSemaphore  = new Semaphore( 1 );
    robot      = null;
    xOld      = 0.0;
    yOld      = 0.0;
   
    realSimulation = Defines.REAL_SIMULATION == Simulation.getCurrent().getType() ;
  }
 
 
  public synchronized BufferedImage getImage()
  {
    if ( image == null  ||  ic instanceof WebcamImageCollector )
      loadImage()// Para obtener una imagen "fresca"
    return image;
  }
 
 
  public synchronized void disposeImage()
  {
    image = null;
  }
 
 
  /**
   * Reconoce en la imagen corriente el robot representado por el
   * color (R,G,B) pasado por par�metro, y lo agrega a la lista de
   * robots reconocidos.
   * @param r        componente rojo.
   * @param g        componente verde.
   * @param b        componente azul.
   * @throws GPSException  si no se reconoce ning�n robot con dicho color,
   *             o si se reconoce m�s de uno.
   */
  public synchronized int recognizeRobot(int r, int g, int b) throws GPSException
  {
    loadImage()// Para obtener una imagen "fresca"
   
    if ( image == null )
      throw new GPSException("Null image.");
   
    try
    {
      if ( Simulation.getCurrent().getType() == Defines.REAL_SIMULATION )
        newRobot = imageUtils.recognizeShapes( r, g, b, 100, 999999, ImageUtils.HIGH_ACCURACY );
      else
        newRobot = imageUtils.recognizeShapes( r, g, b, 100, 999999, ImageUtils.NORMAL_ACCURACY );
     
      if ( newRobot == null  ||  newRobot.length == 0 )
        throw new GPSException("No se pudo reconocer el robot.");
     
      if (newRobot.length > 1)
        throw new GPSException"Se reconoci� m�s de un objeto con el mismo color. "  +
                    "Seleccione un color un�voco para el robot."      );

      gpsSemaphore.WAIT();
      newRobot[0].xOld  = xOld;
      newRobot[0].yOld  = yOld;
      robot        = newRobot[0];
      xOld        = robot.x;
      yOld        = robot.y;
      gpsSemaphore.SIGNAL();
     
      return 1;
    }
    catch (ImageUtilsException e)
    {
      throw new GPSException( e.getMessage() );
    }
   
  }

  /**
   * Reconoce en la imagen corriente los �conos coloreados representados por
   * el color (R,G,B) pasado por par�metro (y los agrega a la lista de
   * �conos coloreados reconocidos).
   * @param r        componente rojo.
   * @param g        componente verde.
   * @param b        componente azul.
   * @param name      nombre del �cono coloreado.
   * @throws GPSException  si no se reconoce ning�n �cono con dicho color.
   */
  public synchronized int recognizeColoredIcons(int r, int g, int b, String name, int x, int y, int w, int h) throws GPSException
  {
    loadImage()// Para obtener una imagen "fresca"
   
    if ( image == null )
      throw new GPSException("Null image.");

    try
    {
      //Si el �cono ya fue reconocido, se lo borra y se lo vuelve a reconocer
      if ( isColoredIconJustRecognized( r , g , b ) )
        removeRecongnizedColoredIcon( r , g , b );
     
      // [EB2] Cuando la simulacion es real, no reconocemos shapes sino que
      // buscamos los colores para mapearlos
      RecognizedShape[] newIcons;
     
      if(realSimulation) {
        /*
               double x, double y,
              double bx, double by,
              double area, Color color,
              int[] xp, int[] yp, int np
         */
        int paramW = w;
       
        if(w<0) {
          paramW = x-Math.abs(w);
        }
       
        int paramH = h;
        if(h<0) {
          paramH = y-Math.abs(h);
        }
       
        int[] polygonVerticesX = new int[4];
        int[] polygonVerticesY = new int[4];
       
        // Arriba, Izq
        polygonVerticesX[0]=x;
        polygonVerticesY[0]=y;
        // Arriba, Der
        polygonVerticesX[1]=x+paramW;
        polygonVerticesY[1]=y;
        // Abajo, Der
        polygonVerticesX[2]=x+paramW;
        polygonVerticesY[2]=y+paramH;
        // Abajo, Izq
        polygonVerticesX[3]=x;
        polygonVerticesY[3]=y+paramH;
       
        int bx = Math.min(polygonVerticesX[0],polygonVerticesX[2]), by = Math.max(polygonVerticesY[0],polygonVerticesY[2]);
       
        float centroidX, centroidY;
        centroidX = (float)(polygonVerticesX[0] + polygonVerticesX[2])/2;
        centroidY = (float)(polygonVerticesY[0] + polygonVerticesY[2])/2;
       
        int area = Math.abs(polygonVerticesX[2] - polygonVerticesX[0]) * (polygonVerticesY[2] - polygonVerticesY[0]);
       
        newIcons = new RecognizedShape[1];
        newIcons[0] = new RecognizedShape(centroidX,centroidY,bx,by,area,new Color(r,g,b),polygonVerticesX,polygonVerticesY,4);
      } else {
        imageUtils.recognizeShapes( r, g, b, 1000, 999999, ImageUtils.HIGH_ACCURACY );       
        newIcons = imageUtils.getRecognizedShapes();
      }
     
      if ( newIcons == null  ||  newIcons.length == 0 )
        throw new GPSException("Not colored icons were recognized.");
     
      // Se agrega el nuevo �cono reconocido al final del arreglo
      RecognizedShape[] tempRecognizedColoredIcons = sceneItems.recognizedColoredIcons;
      sceneItems.recognizedColoredIcons = new RecognizedShape[sceneItems.recognizedColoredIcons.length + newIcons.length];
      int i,j;
      for (i=0; i<tempRecognizedColoredIcons.length; i++)
        sceneItems.recognizedColoredIcons[i] = tempRecognizedColoredIcons[i];
      for (j=0; j<newIcons.length; j++)
      {
        // A todos los iconos del mismo color se les pone el mismo nombre
        newIcons[j].shapeId = name;
        sceneItems.recognizedColoredIcons[j+i] = newIcons[j];
      }
     
      return newIcons.length;
    }
    catch (ImageUtilsException e)
    {
      throw new GPSException( e.getMessage() );
    }
  }


  /**
   * Carga la imagen SWT y realiza el procesamiento de reconocimiento
   * de paredes.
   * @param r    componentes <i>red</i> del color promedio de las paredes.
   * @param g    componentes <i>green</i> del color promedio de las paredes.
   * @param b    componentes <i>blue</i> del color promedio de las paredes.
   * @throws GPSException  si no hay una imagen establecida, o el procesamiento
   *             no pudo realizarse.
   */
  public synchronized RecognizedItems recognizeWalls(int r, int g, int b) throws GPSException
  {
    loadImage()// Para obtener una imagen "fresca"
     
    if ( image == null )
      throw new GPSException("Null image.");
   
    try
    {
      // Remuevo todas las paredes y las reconozco nuevamente
      removeAllRecognizedWalls();
      imageUtils.recognizeShapes(r, g, b, 2000, 999999, ImageUtils.HIGH_ACCURACY);
      sceneItems.recognizedWalls = imageUtils.getRecognizedShapes();
    }
    catch (ImageUtilsException e)
    {
      throw new GPSException( e.getMessage() );
    }

    return sceneItems;
  }

 
  /**
   * Elimina el robot reconocido identificado por el nombre pasado por
   * par�metro.
   * @param name  nombre (un�voco) del robot a eliminar.
   */ 
  public void removeRecognizedRobot(String name)
  {
    robot = null;
  }


  /**
   * Verifica si el �cono con color (r,g,b) ya fue reconocido.
   * @param name  color (r,g,b) del �cono.
   * @return    <code>true</code> si el �cono ya fue reconocido, o
   *         <code>false</code> en caso contrario.
   */
  private boolean isColoredIconJustRecognized(int r, int g, int b)
  {
    for (int i=0; i<sceneItems.recognizedColoredIcons.length; i++)
      if (sceneItems.recognizedColoredIcons[i].color.equals(new Color(r,g,b)) )
        return true;
   
    return false;
  }
 
 
  /**
   * Remueve los �conos coloreados identificados con el color pasado por
   * parametro.
   * @param r    componentes <i>red</i> del color.
   * @param g    componentes <i>green</i> del color.
   * @param b    componentes <i>blue</i> del color.
   */
  public void removeRecongnizedColoredIcon(int r, int g, int b)
  {
    int count = 0;
    int i , j;
   
    // Cuenta cu�ntos �conos fueron reconocidos con el mismo color.
    for (i=0; i<sceneItems.recognizedColoredIcons.length; i++)
      if (sceneItems.recognizedColoredIcons[i].color.equals(new Color(r,g,b)) )
        count++;
   
    // Achica el arreglo.
    RecognizedShape[] newArray = new RecognizedShape[sceneItems.recognizedColoredIcons.length - count] ;
   
    // Copia todos los dem�s
    for (i=0, j=0; i<sceneItems.recognizedColoredIcons.length; i++)
      if ( !sceneItems.recognizedColoredIcons[i].color.equals(new Color(r,g,b)) )
        // Distinto => lo copia.
        newArray[j++]=sceneItems.recognizedColoredIcons[i];
       
    sceneItems.recognizedColoredIcons = newArray;
  }
 
 
  public void renameRecongnizedColoredIcon(int r, int g, int b, String newName)
  {
    for (int i=0; i<sceneItems.recognizedColoredIcons.length; i++)
      if ( sceneItems.recognizedColoredIcons[i].color.equals(new Color(r,g,b)) )
        sceneItems.recognizedColoredIcons[i].shapeId = newName;
  }


  public void setImageCollector(ImageCollector ic)
  {
    this.ic = ic;
  }


  public ImageCollector getImageCollector()
  {
    return ic;
  }

 
  private synchronized void loadImage()
  {
    if ( ic != null )
      image = ic.grabImage();
 
    if ( image != null )
      imageUtils.setImage( image );
  }

 
  public RobotState getRobotState(int r, int g, int b) throws GPSException
  {
    RobotState state = null;
   
    try
    {
      recognizeRobotr , g , b );
    }
    catch (GPSException e)
    {
      throw new GPSException( e.getMessage() );
    }
   
    gpsSemaphore.WAIT();
    if ( robot != null )
    {
      state      = new RobotState();
      state.position  = new double[] { robot.x , robot.y };
      state.course  = Math.atan2( robot.y-robot.yOld , robot.x-robot.xOld );
    }
    gpsSemaphore.SIGNAL();
   
    return state;
  }

 

  public void setXMLConfigFile()
  {
    // TODO Auto-generated method stub
  }


  public void close()
  {
    if ( ic != null  &&  !ic.isClosed() )
      ic.close();
  }


 
}
TOP

Related Classes of components.gps.imagebased.ImageBasedGPS

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.