From 77ca839387d9526b13c04028877a886a410cd10f Mon Sep 17 00:00:00 2001 From: Aylen Ricca <aricca@fing.edu.uy> Date: Sat, 26 Jul 2014 13:37:35 -0300 Subject: [PATCH] detection of building board --- .../fing/chesstrack/ChessTrackActivity.java | 27 +++++----- .../edu/fing/chesstrack/ajedrez/Logica.java | 40 +++++++++++++++ .../fing/chesstrack/communication/Client.java | 39 +++++++-------- .../chesstrack/modulomodelador/Modelador.java | 50 +++++++++++++------ .../modulovision/DetectorOclusion.java | 33 +++++++----- .../fing/chesstrack/modulovision/Manager.java | 50 +++++++++++++------ 6 files changed, 159 insertions(+), 80 deletions(-) create mode 100644 ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/ajedrez/Logica.java diff --git a/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/ChessTrackActivity.java b/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/ChessTrackActivity.java index f5f128e..9672369 100644 --- a/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/ChessTrackActivity.java +++ b/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/ChessTrackActivity.java @@ -21,7 +21,8 @@ import android.view.SurfaceView; import android.view.WindowManager; import android.widget.EditText; -public class ChessTrackActivity extends Activity implements CvCameraViewListener { +public class ChessTrackActivity extends Activity implements + CvCameraViewListener { private static final String TAG = "CHESSTRACK::Activity"; private static final String IPV4_REGEX = "^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$"; @@ -38,10 +39,10 @@ public class ChessTrackActivity extends Activity implements CvCameraViewListener private Manager _manager; private MenuItem _mItemCalibrar; private MenuItem _mItemServer; - private MenuItem _mItemJugar; private int _estado; - private final BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) { + private final BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback( + this) { @Override public void onManagerConnected(int status) { @@ -50,11 +51,11 @@ public class ChessTrackActivity extends Activity implements CvCameraViewListener Log.i(TAG, "OpenCV loaded successfully"); _mOpenCvCameraView.enableView(); } - break; + break; default: { super.onManagerConnected(status); } - break; + break; } } }; @@ -62,7 +63,8 @@ public class ChessTrackActivity extends Activity implements CvCameraViewListener @Override public void onResume() { super.onResume(); - OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_9, this, mLoaderCallback); + OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_9, this, + mLoaderCallback); } @Override @@ -93,7 +95,8 @@ public class ChessTrackActivity extends Activity implements CvCameraViewListener _manager.setConnection("192.168.1.101", 5555); // FIXME DELETE // !!!! Editable value = input.getText(); - if (value == null || value.toString().equals("") || !value.toString().matches(IPV4_REGEX)) { + if (value == null || value.toString().equals("") + || !value.toString().matches(IPV4_REGEX)) { Log.i(TAG, "INPUT= not valid IP" + value.toString()); getServerIp(); } else { @@ -121,7 +124,8 @@ public class ChessTrackActivity extends Activity implements CvCameraViewListener public void onClick(DialogInterface dialog, int whichButton) { Editable value = input.getText(); Log.i(TAG, "INPUT=" + value.toString()); - if (value == null || value.toString().equals("") || !value.toString().matches(PORT_REGEX)) { + if (value == null || value.toString().equals("") + || !value.toString().matches(PORT_REGEX)) { Log.i(TAG, "INPUT= not valid PORT" + value.toString()); getServerPort(ip); } else { @@ -142,7 +146,6 @@ public class ChessTrackActivity extends Activity implements CvCameraViewListener Log.i(TAG, "called onCreateOptionsMenu"); _mItemCalibrar = menu.add("Calibrar.."); _mItemServer = menu.add("Conectar Server"); - _mItemJugar = menu.add("Jugar!!!"); return true; } @@ -155,9 +158,6 @@ public class ChessTrackActivity extends Activity implements CvCameraViewListener } } else if (item == _mItemServer) { getServerIp(); - } else if (item == _mItemJugar) { - _estado = JUGAR; - } return true; } @@ -196,8 +196,7 @@ public class ChessTrackActivity extends Activity implements CvCameraViewListener case CALIBRAR: Log.i(TAG, "calibrando..."); if (_manager.calibrar(inputFrame)) { - // _estado = JUGAR; - _estado = IDLE; + _estado = JUGAR; } else { _estado = IDLE; } diff --git a/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/ajedrez/Logica.java b/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/ajedrez/Logica.java new file mode 100644 index 0000000..e86db4f --- /dev/null +++ b/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/ajedrez/Logica.java @@ -0,0 +1,40 @@ +package uy.edu.fing.chesstrack.ajedrez; + +import org.opencv.core.Core; +import org.opencv.core.CvType; +import org.opencv.core.Mat; +import org.opencv.core.Size; + +public class Logica { + private Mat _tableroInicio; + private Mat _tableroAnterior; + + public Logica() { + double[] vectorONES = { 1, 1, 1, 1, 1, 1, 1, 1 }; + _tableroInicio = Mat.zeros(new Size(8, 8), CvType.CV_8UC1); + _tableroInicio.put(0, 0, vectorONES); + _tableroInicio.put(1, 0, vectorONES); + _tableroInicio.put(6, 0, vectorONES); + _tableroInicio.put(7, 0, vectorONES); + _tableroAnterior = _tableroInicio; + } + + public Mat getTableroInicio() { + return _tableroInicio; + } + + public boolean validarNuevoTablero(Mat actual) { + Mat result = new Mat(8, 8, CvType.CV_8UC1); + Core.absdiff(actual, _tableroAnterior, result); + if (Core.countNonZero(result) == 0) { + _tableroAnterior = actual; + } + return (Core.countNonZero(result) != 0); + } + + public boolean validarTableroArmado(Mat nuevo) { + Mat result = new Mat(8, 8, CvType.CV_8UC1); + Core.absdiff(nuevo, _tableroInicio, result); + return (Core.countNonZero(result) == 0); + } +} diff --git a/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/communication/Client.java b/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/communication/Client.java index 7816c24..13f9610 100644 --- a/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/communication/Client.java +++ b/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/communication/Client.java @@ -14,17 +14,17 @@ public class Client { private Socket serverSocket; private int _serverPort = 5556; - private String _serverIp = "192.168.1.101"; + private String _serverIp = "192.168.1.23"; - //private BufferedReader input; + // private BufferedReader input; private DataOutputStream output; - protected Client(){ + protected Client() { } - public static Client getInstance(){ - if(_clientInstance == null){ + public static Client getInstance() { + if (_clientInstance == null) { _clientInstance = new Client(); } return _clientInstance; @@ -32,8 +32,8 @@ public class Client { public void EstablishConnection(String serverIp, int serverPort) { Log.i(TAG, "init client-server communication"); - //this._serverIp = serverIp; - //this._serverPort = serverPort; + // this._serverIp = serverIp; + // this._serverPort = serverPort; try { Log.i(TAG, "Server on " + this._serverIp + ":" + _serverPort); @@ -41,10 +41,12 @@ public class Client { serverSocket = new Socket(serverAddr, _serverPort); // get stream to send data - this.output = new DataOutputStream(this.serverSocket.getOutputStream()); + this.output = new DataOutputStream( + this.serverSocket.getOutputStream()); // get stream to receive data - //this.input = new BufferedReader(new InputStreamReader(this.serverSocket.getInputStream())); + // this.input = new BufferedReader(new + // InputStreamReader(this.serverSocket.getInputStream())); } catch (IOException e) { e.printStackTrace(); } @@ -52,7 +54,7 @@ public class Client { public void SendData(String msg) { try { - Log.i(TAG, "sending="+ msg); + Log.i(TAG, "sending=" + msg); this.output.writeBytes(msg); } catch (IOException e) { e.printStackTrace(); @@ -60,21 +62,14 @@ public class Client { } /* - public String ReceiveData() { - try { - String read = input.readLine(); - Log.i(TAG, "received="+ read); - return read; - } catch (IOException e) { - e.printStackTrace(); - return null; - } - } - */ + * public String ReceiveData() { try { String read = input.readLine(); + * Log.i(TAG, "received="+ read); return read; } catch (IOException e) { + * e.printStackTrace(); return null; } } + */ public void Stop() { try { - //input.close(); + // input.close(); output.close(); serverSocket.close(); } catch (IOException e) { diff --git a/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulomodelador/Modelador.java b/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulomodelador/Modelador.java index fb1da06..18e00bd 100644 --- a/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulomodelador/Modelador.java +++ b/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulomodelador/Modelador.java @@ -15,7 +15,7 @@ import android.util.Log; public class Modelador { private static final String TAG = "CHESSTRACK::Modelador"; private final int CANT_FILAS = 8; - private final int CANT_SCAQUE = CANT_FILAS * CANT_FILAS; + // private final int CANT_SCAQUE = CANT_FILAS * CANT_FILAS; private final int MIN_CANT_PIX_WHITE = 30; private Mat tablero; // se cuentan de arrib a abajo y de izquierda a derecha @@ -34,7 +34,15 @@ public class Modelador { int largo = inputFrame.rows(); int ancho = inputFrame.cols(); // obtengo cuanto mide en ancho y largo un escaque - int largoEscaque = (int) Math.floor(largo / (CANT_FILAS + 2));// +2 porque se toma un escaque mas de borde + int largoEscaque = (int) Math.floor(largo / (CANT_FILAS + 2));// +2 + // porque + // se + // toma + // un + // escaque + // mas + // de + // borde int anchoEscaque = (int) Math.floor(ancho / (CANT_FILAS + 2)); Log.i(TAG, "largoEscaque= " + largoEscaque); Log.i(TAG, "anchoEscaque= " + anchoEscaque); @@ -61,7 +69,7 @@ public class Modelador { Core.convertScaleAbs(mIntermediateMat, mIntermediateMat, 10, 0); Imgproc.threshold(mIntermediateMat, mIntermediateMat, 70, 255, Imgproc.THRESH_BINARY); - int cant_pix = mIntermediateMat.cols() * mIntermediateMat.rows(); + // int cant_pix = mIntermediateMat.cols() * mIntermediateMat.rows(); int cant_pix_white = Core.countNonZero(mIntermediateMat); if (cant_pix_white > (MIN_CANT_PIX_WHITE)) { ret = 1; @@ -77,7 +85,7 @@ public class Modelador { tablero.put(i, j, getHayFichaEnEscaque(i, j)); } } - return tablero; + return tablero.t(); } public Mat dibujarEscaque() { @@ -125,15 +133,17 @@ public class Modelador { Imgproc.COLOR_GRAY2RGBA, 4); escaques[i][j].copyTo(subm); - Core.putText(tmp, Integer.toString(i) + "-" + Integer.toString(j), new Point(pos_x + 1, pos_y + 1), Core.FONT_HERSHEY_SIMPLEX, 0.3, new Scalar(255, 0, 0)); + Core.putText(tmp, + Integer.toString(i) + "-" + Integer.toString(j), + new Point(pos_x + 1, pos_y + 1), + Core.FONT_HERSHEY_SIMPLEX, 0.3, new Scalar(255, 0, 0)); } } return tmp; } public Mat dibujarEscaquesSobel(int version) { - Mat tmp = Mat.zeros(Calibracion.getInstance().getRectROI().size(), - CvType.CV_8UC4); + Mat tmp = Mat.zeros(Calibracion.getRectROI().size(), CvType.CV_8UC4); Mat subm; // tmp.submat(new Rect(new Point(0,0) // ,escaques[i][j].size())); // escaques[i][j].copyTo(subm); @@ -154,10 +164,14 @@ public class Modelador { Core.convertScaleAbs(mIntermediateMat, mIntermediateMat, 10, 0); Imgproc.threshold(mIntermediateMat, mIntermediateMat, 70, 255, Imgproc.THRESH_BINARY); - - Imgproc.erode(mIntermediateMat, mIntermediateMat, Imgproc.getStructuringElement(Imgproc.MORPH_RECT,new Size(1, 1))); - Imgproc.dilate(mIntermediateMat, mIntermediateMat, Imgproc.getStructuringElement(Imgproc.MORPH_RECT,new Size(1, 1))); - + + Imgproc.erode(mIntermediateMat, mIntermediateMat, Imgproc + .getStructuringElement(Imgproc.MORPH_RECT, new Size(1, + 1))); + Imgproc.dilate(mIntermediateMat, mIntermediateMat, Imgproc + .getStructuringElement(Imgproc.MORPH_RECT, new Size(1, + 1))); + int cant_pix = mIntermediateMat.cols() * mIntermediateMat.rows(); int cant_pix_white = Core.countNonZero(mIntermediateMat); @@ -166,19 +180,23 @@ public class Modelador { switch (version) { case 1: if (cant_pix_white > (MIN_CANT_PIX_WHITE)) { - Imgproc.cvtColor(mIntermediateMat, subm, Imgproc.COLOR_GRAY2RGBA, 4); + Imgproc.cvtColor(mIntermediateMat, subm, + Imgproc.COLOR_GRAY2RGBA, 4); } else { - Imgproc.cvtColor(escaques[i][j], subm, Imgproc.COLOR_GRAY2RGBA, 4); + Imgproc.cvtColor(escaques[i][j], subm, + Imgproc.COLOR_GRAY2RGBA, 4); } break; case 2: if (cant_pix_white > (MIN_CANT_PIX_WHITE)) { - Log.i(TAG, "NUEVA FICHA" + (i+1) + "-" + (j+1)); + Log.i(TAG, "NUEVA FICHA" + (i + 1) + "-" + (j + 1)); } - Imgproc.cvtColor(mIntermediateMat, subm, Imgproc.COLOR_GRAY2RGBA, 4); + Imgproc.cvtColor(mIntermediateMat, subm, + Imgproc.COLOR_GRAY2RGBA, 4); break; default: - Imgproc.cvtColor(escaques[i][j], subm, Imgproc.COLOR_GRAY2RGBA, 4); + Imgproc.cvtColor(escaques[i][j], subm, + Imgproc.COLOR_GRAY2RGBA, 4); break; } diff --git a/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/DetectorOclusion.java b/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/DetectorOclusion.java index 9ee8745..e1f89ed 100644 --- a/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/DetectorOclusion.java +++ b/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/DetectorOclusion.java @@ -30,7 +30,8 @@ public class DetectorOclusion { super(); Log.i(TAG, "constructor INI"); - _morphKernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT,new Size(3, 3)); + _morphKernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, + new Size(3, 3)); _fgMaskMOG2 = new Mat(4, 1, CvType.CV_8UC1); _pMOG2 = new BackgroundSubtractorMOG2(); _estadoACTUAL = START; @@ -48,9 +49,10 @@ public class DetectorOclusion { } public boolean hayNuevoTableroValido(Mat inputFrame) { - if (_estadoACTUAL == START){ - _pMOG2 = new BackgroundSubtractorMOG2(); // MOG2 approach - } + /* + * if (_estadoACTUAL == START){ _pMOG2 = new BackgroundSubtractorMOG2(); + * // MOG2 approach } + */ Log.i(TAG, "Procesar!"); Log.i(TAG, "Region SIZE=" + inputFrame.size()); @@ -60,7 +62,8 @@ public class DetectorOclusion { Imgproc.erode(_fgMaskMOG2, _fgMaskMOG2, _morphKernel); Log.i(TAG, "Apply erode"); - Imgproc.threshold(_fgMaskMOG2, _fgMaskMOG2, 200, 255,Imgproc.THRESH_BINARY); + Imgproc.threshold(_fgMaskMOG2, _fgMaskMOG2, 200, 255, + Imgproc.THRESH_BINARY); Log.i(TAG, "Apply threshold"); // Imgproc.dilate(_fgMaskMOG2, _fgMaskMOG2, _morphKernel); @@ -74,24 +77,30 @@ public class DetectorOclusion { Log.i(TAG, "VEO MANO !!!"); _estadoACTUAL = OCLUSION; - /*Core.putText(_fgMaskMOG2, "MANO !!!", new Point(20, 20), - Core.FONT_HERSHEY_SIMPLEX, 0.8, new Scalar(255, 255, 0));*/ + /* + * Core.putText(_fgMaskMOG2, "MANO !!!", new Point(20, 20), + * Core.FONT_HERSHEY_SIMPLEX, 0.8, new Scalar(255, 255, 0)); + */ } else { if (_estadoANTERIOR == OCLUSION) { - /*Core.putText(_fgMaskMOG2, "TRANSI !!!", new Point(20, 20), - Core.FONT_HERSHEY_SIMPLEX, 0.8, new Scalar(255, 255, 0));*/ + /* + * Core.putText(_fgMaskMOG2, "TRANSI !!!", new Point(20, 20), + * Core.FONT_HERSHEY_SIMPLEX, 0.8, new Scalar(255, 255, 0)); + */ Log.i(TAG, "VEO TRANSICION !!!"); _estadoACTUAL = TRANSICION; } if (_estadoANTERIOR == TRANSICION) { - /*Core.putText(_fgMaskMOG2, "ESTABLE !!!", new Point(20, 20), - Core.FONT_HERSHEY_SIMPLEX, 0.8, new Scalar(255, 255, 0));*/ + /* + * Core.putText(_fgMaskMOG2, "ESTABLE !!!", new Point(20, 20), + * Core.FONT_HERSHEY_SIMPLEX, 0.8, new Scalar(255, 255, 0)); + */ _estadoACTUAL = ENVIAR_TABLERO; _pMOG2 = new BackgroundSubtractorMOG2(); // MOG2 approach Log.i(TAG, "VEO ENVIAR !!!"); } - if (_estadoANTERIOR == ENVIAR_TABLERO){ + if (_estadoANTERIOR == ENVIAR_TABLERO) { _estadoACTUAL = ESTABLE; Log.i(TAG, "VEO ESTABLE !!!"); } diff --git a/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/Manager.java b/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/Manager.java index 5790a38..9d58966 100644 --- a/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/Manager.java +++ b/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/Manager.java @@ -3,6 +3,7 @@ package uy.edu.fing.chesstrack.modulovision; import org.opencv.core.CvType; import org.opencv.core.Mat; +import uy.edu.fing.chesstrack.ajedrez.Logica; import uy.edu.fing.chesstrack.communication.Client; import uy.edu.fing.chesstrack.modulomodelador.Modelador; import android.media.AudioManager; @@ -31,14 +32,17 @@ public class Manager { private static Client _client; private static DetectorOclusion _detectorOclusion; private static Modelador _modelador; + private static Logica _logica; private final boolean _debug; + private int _cantJugada; protected Manager() { - _estado = JUGANDO; + _estado = ARMANDO_TABLERO; _salida = NOT; _adquisicion = null; _client = null; _debug = false; + _cantJugada = 0; } public static Manager getInstance() { @@ -75,8 +79,8 @@ public class Manager { } try { _adquisicion = new Adquisicion(); - _detectorOclusion = new DetectorOclusion(); _modelador = new Modelador(); + _logica = new Logica(); } catch (Exception e) { e.printStackTrace(); return false; @@ -89,6 +93,20 @@ public class Manager { return false; } + public void iniciarJuego() { + _estado = JUGANDO; + // beep + _detectorOclusion = new DetectorOclusion(); + ToneGenerator toneG = new ToneGenerator(AudioManager.STREAM_ALARM, 50); + toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 200); // ms + + if (_salida == OK) { + Mat tableroInicio = _logica.getTableroInicio(); + _client.SendData("TableroINICIO!\n"); + _client.SendData(" ".concat(tableroInicio.dump().concat("\n"))); + } + } + public Mat processFrame(Mat inputFrame) { Log.i(TAG, "Acondicionamiento"); Mat region = _adquisicion.processFrame(inputFrame); @@ -99,14 +117,10 @@ public class Manager { switch (_estado) { case ARMANDO_TABLERO: Log.i(TAG, "Armando Tablero"); - // respuesta: {PRONTO - NOPRONTO} - // SI pornto --> beep + estado JUGANDO - // SINO --> nada - // Modelador -> genera la imagen 0-1 y se la pasa al manager - // Modelador.Validar - // - // cuando paso a estado jugando mando al socket si salida==OK - + Mat nuevo = _modelador.getMatrizFichas(region); + if (_logica.validarTableroArmado(nuevo)) { + iniciarJuego(); + } break; case JUGANDO: Log.i(TAG, "Jugando"); @@ -114,12 +128,16 @@ public class Manager { Log.i(TAG, "Tablero Valido"); // llamar al modelador Mat aux = _modelador.getMatrizFichas(region); - Log.i(TAG, "MATRIZ=" + aux.dump()); - //region = _modelador.dibujarEscaquesSobel(2); - - if (_salida == OK) { - _client.SendData("Nuevo Tablero Valido!\n"); - _client.SendData(" ".concat(aux.dump().concat("\n"))); + // Log.i(TAG, "MATRIZ=" + aux.dump()); + // region = _modelador.dibujarEscaquesSobel(2); + + if (_logica.validarNuevoTablero(aux)) { + if (_salida == OK) { + _client.SendData("Nuevo Tablero Valido = \n" + + String.valueOf(_cantJugada)); + _cantJugada++; + _client.SendData(" ".concat(aux.dump().concat("\n"))); + } } } break; -- GitLab