diff --git a/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/ChessTrackActivity.java b/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/ChessTrackActivity.java index 190c8c66330dbb985432399fc417d795d8e9cc86..2631d289e49dfa8e9d460e5994a7faa96caa949e 100644 --- a/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/ChessTrackActivity.java +++ b/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/ChessTrackActivity.java @@ -8,16 +8,10 @@ import org.opencv.android.LoaderCallbackInterface; import org.opencv.android.OpenCVLoader; import org.opencv.core.Mat; -import uy.edu.fing.chesstrack.communication.Client; -import uy.edu.fing.chesstrack.modulomodelador.Modelador; -import uy.edu.fing.chesstrack.modulovision.Adquisicion; -import uy.edu.fing.chesstrack.modulovision.Calibracion; -import uy.edu.fing.chesstrack.modulovision.imgproc.BackgroundSupress; +import uy.edu.fing.chesstrack.modulovision.Manager; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; -import android.media.AudioManager; -import android.media.ToneGenerator; import android.os.Bundle; import android.text.Editable; import android.util.Log; @@ -27,32 +21,28 @@ 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})$"; private static final String PORT_REGEX = "^(\\d{4,5})$"; - private static final String WELCOME_MSG = "" - + "--------------------------------------------------------------------------\n" - + " .:: CHESSTRACK ::. seguimiento de una partida de Ajedrez\n" - + "\n" - + " TImag 2014\n" - + " Nicolas Furquez - Aylen Ricca\n" - + "--------------------------------------------------------------------------\n"; + + // estados + private static final int IDLE = 0; + private static final int CALIBRAR = 1; + private static final int JUGAR = 2; private CameraBridgeViewBase _mOpenCvCameraView; // private JavaCameraView _mOpenCvCameraView; - private Adquisicion _adquisicion; - private BackgroundSupress _analizador; - private Client _client; + private Manager _manager; private MenuItem _mItemCalibrar; private MenuItem _mItemServer; - private Mat _frame; - private boolean _isUsed; - private boolean _isCalibrada; + private int _estado; - private final BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) { + private final BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback( + this) { @Override public void onManagerConnected(int status) { @@ -73,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 @@ -87,10 +78,7 @@ public class ChessTrackActivity extends Activity implements CvCameraViewListener _mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE); _mOpenCvCameraView.setCvCameraViewListener(this); - Modelador.getInstance(); - //_analizador = new BackgroundSupress(); - _isUsed = false; - _isCalibrada = false; + _manager = Manager.getInstance(); } public void getServerIp() { @@ -143,9 +131,7 @@ public class ChessTrackActivity extends Activity implements CvCameraViewListener int port = Integer.parseInt(value.toString()); Log.i(TAG, "PORT=" + port); - _client = Client.getInstance(); - _client.EstablishConnection(ip, port); - _client.SendData(WELCOME_MSG); + _manager.setConnection(ip, port); } } }); @@ -165,24 +151,9 @@ public class ChessTrackActivity extends Activity implements CvCameraViewListener public boolean onOptionsItemSelected(MenuItem item) { Log.i(TAG, "Menu Item selected " + item); if (item == _mItemCalibrar) { - _isUsed = true; - if (_frame != null) { - if (Calibracion.getInstance().calibrar(_frame)) { - - ToneGenerator toneG = new ToneGenerator(AudioManager.STREAM_ALARM, 50); - toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD,200); //ms - try { - this._adquisicion = new Adquisicion(); - } catch (Exception e) { - e.printStackTrace(); - } - _isCalibrada = true; - } else { - ToneGenerator toneG = new ToneGenerator(AudioManager.STREAM_ALARM, 50); - toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD,700); - } + if (_estado == IDLE) { + _estado = CALIBRAR; } - _isUsed = false; } else if (item == _mItemServer) { getServerIp(); } @@ -203,8 +174,8 @@ public class ChessTrackActivity extends Activity implements CvCameraViewListener if (_mOpenCvCameraView != null) { _mOpenCvCameraView.disableView(); } - if (this._client != null) { - this._client.Stop(); + if (_manager != null) { + _manager.destroy(); } } @@ -218,18 +189,23 @@ public class ChessTrackActivity extends Activity implements CvCameraViewListener @Override public Mat onCameraFrame(Mat inputFrame) { - // TODO MANEJAR ESTADOS - if (!_isUsed) { - _frame = inputFrame; // FIXME - para qe lo guardo ?? - } - - if (_isCalibrada) { - Log.i(TAG, "new _frame - calibrada"); - - inputFrame = _adquisicion.processFrame(inputFrame); - //Modelador.getInstance().dividirTablero(inputFrame); - //return Modelador.getInstance().dibujarEscaquesSobel(); - return inputFrame; + if (inputFrame != null) { + switch (_estado) { + case CALIBRAR: + Log.i(TAG, "calibrando..."); + if (_manager.calibrar(inputFrame)) { + _estado = JUGAR; + } else { + _estado = IDLE; + } + break; + case JUGAR: + Log.i(TAG, "jugando..."); + return _manager.processFrame(inputFrame); + // break; + case IDLE: + break; + } } return inputFrame; } 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 6be7aa40343f99728a5a2858ea0d4a23bc096132..693c44bf1f49af54891e98c380e8a6ada3b7f414 100644 --- a/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulomodelador/Modelador.java +++ b/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulomodelador/Modelador.java @@ -37,7 +37,7 @@ public class Modelador { public void dividirTablero(Mat inputFrame){ - Rect roi = Calibracion.getInstance().getRectPOI(); + Rect roi = Calibracion.getInstance().getRectROI(); Mat proccesFrame = inputFrame.submat(roi); int largo = proccesFrame.rows(); int ancho = proccesFrame.cols(); @@ -58,7 +58,7 @@ public class Modelador { } public Mat dibujarEscaque(){ - Mat tmp = Mat.ones(Calibracion.getInstance().getImagenCalibrada().size(), CvType.CV_8UC4); + Mat tmp = Mat.ones(Calibracion.getInstance().get_sizeFrame(), CvType.CV_8UC4); Mat subm ; //tmp.submat(new Rect(new Point(0,0) ,escaques[i][j].size())); //escaques[i][j].copyTo(subm); int pos_x = 0; @@ -76,7 +76,7 @@ public class Modelador { } public Mat dibujarEscaquesCanny(){ - Mat tmp = Mat.zeros(Calibracion.getInstance().getImagenCalibrada().size(), CvType.CV_8UC4); + Mat tmp = Mat.zeros(Calibracion.getInstance().get_sizeFrame(), CvType.CV_8UC4); Mat subm ; //tmp.submat(new Rect(new Point(0,0) ,escaques[i][j].size())); //escaques[i][j].copyTo(subm); Mat mIntermediateMat = new Mat(); @@ -99,7 +99,7 @@ public class Modelador { } public Mat dibujarEscaquesSobel(){ - Mat tmp = Mat.zeros(Calibracion.getInstance().getImagenCalibrada().size(), CvType.CV_8UC4); + Mat tmp = Mat.zeros(Calibracion.getInstance().get_sizeFrame(), CvType.CV_8UC4); Mat subm ; //tmp.submat(new Rect(new Point(0,0) ,escaques[i][j].size())); //escaques[i][j].copyTo(subm); Mat mIntermediateMat = new Mat(); diff --git a/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/Adquisicion.java b/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/Adquisicion.java index dbf8a067d6e06542873a8fc57df7427aabf14d27..507c9bed2c398565a0dc40edd7e66f776a759e5e 100644 --- a/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/Adquisicion.java +++ b/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/Adquisicion.java @@ -1,20 +1,14 @@ package uy.edu.fing.chesstrack.modulovision; - - import java.util.ArrayList; import java.util.List; import org.opencv.core.Mat; -import uy.edu.fing.chesstrack.modulovision.imgproc.BackgroundSupress; -import uy.edu.fing.chesstrack.modulovision.imgproc.EcualizarImagen; import uy.edu.fing.chesstrack.modulovision.imgproc.Homografia; import uy.edu.fing.chesstrack.modulovision.imgproc.ImgProcInterface; import android.util.Log; - - public class Adquisicion { private static final String TAG = "CHESSTRACK::Adquisicion"; @@ -27,7 +21,7 @@ public class Adquisicion { _listProc.add(new Homografia()); //_listProc.add(new EcualizarImagen()); - _listProc.add(new BackgroundSupress()); + //_listProc.add(new BackgroundSupress()); } /** diff --git a/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/Calibracion.java b/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/Calibracion.java index 9e7d6ab8263ffc2d58c6f0e929dfcd06f6af9212..b1c396d97aaab7a93976a764fafce58b600e4496 100644 --- a/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/Calibracion.java +++ b/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/Calibracion.java @@ -11,10 +11,9 @@ import android.util.Log; public class Calibracion { private static final String TAG = "CHESSTRACK::Calibracion"; - private Mat _imagenCalibrada; - private Mat _imagenOriginal; - private MatOfPoint2f _vertices; - private static Rect _rectPOI = null; + private Size _sizeFrame = null; + private MatOfPoint2f _vertices = null; + private static Rect _rectROI = null; private static Calibracion _instance; @@ -31,26 +30,27 @@ public class Calibracion { public boolean calibrar(Mat img) { Log.i(TAG, "INI calibrando"); - _imagenOriginal = img; - _imagenCalibrada = img; + Size patternSize = new Size(7, 7); MatOfPoint2f corners = new MatOfPoint2f(); - boolean ret = Calib3d.findChessboardCorners(_imagenOriginal,patternSize, corners); + boolean ret = Calib3d.findChessboardCorners(img, patternSize, corners); if (ret) { Log.i(TAG, "Encontro = " + corners.total()); - //Calib3d.drawChessboardCorners(_imagenCalibrada, patternSize, corners, ret); // only for debug + // Calib3d.drawChessboardCorners(img, patternSize, corners, ret); + // only for debug _vertices = corners; + _sizeFrame = img.size(); } Log.i(TAG, "FIN calibrando = " + ret); return ret; } - public Mat getImagenCalibrada() { // por que no guardar solo el size.. es lo unico qe se necesita - return _imagenCalibrada; + public Size get_sizeFrame() { + return _sizeFrame; } - public void setImagenCalibrada(Mat imagenCalibrada) { - this._imagenCalibrada = imagenCalibrada; + public void set_sizeFrame(Size _sizeFrame) { + this._sizeFrame = _sizeFrame; } public MatOfPoint2f getVertices() { @@ -61,12 +61,11 @@ public class Calibracion { this._vertices = vertices; } - public static Rect getRectPOI() { - return _rectPOI; + public static Rect getRectROI() { + return _rectROI; } - public static void setRectPOI(Rect rectPOI) { - Calibracion._rectPOI = rectPOI; + public static void setRectROI(Rect rectROI) { + Calibracion._rectROI = rectROI; } - } 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 b465c169f6083dcc27950d3339c9abea0e53d612..b931b8918789c4e3c33e919aee38dec811c4c735 100644 --- a/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/Manager.java +++ b/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/Manager.java @@ -1,13 +1,41 @@ package uy.edu.fing.chesstrack.modulovision; +import org.opencv.core.CvType; +import org.opencv.core.Mat; + +import android.media.AudioManager; +import android.media.ToneGenerator; +import android.util.Log; +import uy.edu.fing.chesstrack.communication.Client; + public class Manager { - private static final String TAG = "MANAGER"; + private static final String TAG = "CHESSTRACK::MANAGER"; private static Manager _instance; + private static final int ARMANDO_TABLERO = 0; + private static final int JUGANDO = 1; + private static final int OK = 1; + private static final int NOT = 0; + private static final String WELCOME_MSG = "" + + "--------------------------------------------------------------------------\n" + + " .:: CHESSTRACK ::. seguimiento de una partida de Ajedrez\n" + + "\n" + + " TImag 2014\n" + + " Nicolas Furquez - Aylen Ricca\n" + + "--------------------------------------------------------------------------\n"; + private static int _estado; + private static int _salida; + private static Adquisicion _adquisicion; + private static Client _client; + private boolean _debug; protected Manager() { - + _estado = ARMANDO_TABLERO; + _salida = NOT; + _adquisicion = null; + _client = null; + _debug = true; } public static Manager getInstance() { @@ -25,4 +53,80 @@ public class Manager { Manager._estado = _estado; } + public void setConnection(String ip, int port) { + Log.i(TAG, "Setting connection"); + _client = Client.getInstance(); + _client.EstablishConnection(ip, port); + _client.SendData(WELCOME_MSG); + _salida = OK; + } + + public Mat processFrame(Mat inputFrame) { + Log.i(TAG, "Acondicionamiento"); + Mat region = _adquisicion.processFrame(inputFrame); + + Log.i(TAG, "TYPE=" + (inputFrame.type()==CvType.CV_8UC4)); + Log.i(TAG, "CHANNEL=" + (inputFrame.channels()==4)); + + 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 + break; + case JUGANDO: + Log.i(TAG, "Jugando"); + // respuesta: {MANO - NO MANO} + // SI mano --> nada + // SINO matriz-0-1 + + // BackgoundSupress -> busca la mano y retorna si o no + // Modelador -> genera la imagen 0-1 y se la pasa al manager + // mando al cliente la MATRIZ !! + break; + } + + if (_debug) { + Mat tmp = Mat.zeros(inputFrame.size(), CvType.CV_8UC4); + Mat matTMP = tmp.submat(Calibracion.getRectROI()); + region.copyTo(matTMP); + return tmp; + } + return inputFrame; + } + + public boolean calibrar(Mat frame) { + Log.i(TAG, "Calibrando"); + if (Calibracion.getInstance().calibrar(frame)) { + ToneGenerator toneG = new ToneGenerator(AudioManager.STREAM_ALARM, + 50); + toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 200); // ms + if (_salida == OK) { + _client.SendData("FIN calibrar\n . . . armando tablero!"); + } + try { + _adquisicion = new Adquisicion(); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + return true; + } + Log.i(TAG, "No calibrado"); + ToneGenerator toneG = new ToneGenerator(AudioManager.STREAM_ALARM, 50); + toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 700); + return false; + } + + public void destroy() { + if (_client != null) { + _client.Stop(); + } + } } diff --git a/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/imgproc/BackgroundSupress.java b/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/imgproc/BackgroundSupress.java index b952e1e235db1991aec6461aeb10b9ea9b223ff2..8220e2207450b4eef469a20e51f3bdb28ca094ce 100644 --- a/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/imgproc/BackgroundSupress.java +++ b/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/imgproc/BackgroundSupress.java @@ -54,8 +54,8 @@ public class BackgroundSupress implements ImgProcInterface { public Mat procesarImagen(Mat inputFrame) { Log.i(TAG, "procesar "); - Mat ret = Mat.zeros(Calibracion.getInstance().getImagenCalibrada().size(), CvType.CV_8UC4); - Rect roi = Calibracion.getRectPOI(); + Mat ret = Mat.zeros(Calibracion.getInstance().get_sizeFrame(), CvType.CV_8UC4); + Rect roi = Calibracion.getRectROI(); Log.i(TAG, "ROI" + roi.size()); Mat region = ret.submat(roi); diff --git a/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/imgproc/EcualizarImagen.java b/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/imgproc/EcualizarImagen.java index 8508a76f794bb1f207df31aeb25f6a888074ce8c..dad06f2e4073aa98cfe0b6da9324d9ed6dd67abe 100644 --- a/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/imgproc/EcualizarImagen.java +++ b/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/imgproc/EcualizarImagen.java @@ -31,5 +31,4 @@ public class EcualizarImagen implements ImgProcInterface { Log.i(TAG, "processing Frame - FIN"); return img_hist_equalized; } - } diff --git a/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/imgproc/Homografia.java b/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/imgproc/Homografia.java index 2ce69129ad9074c56bec21ad583b3e7ade850716..b79be6f0a45585eaad0737bc06489d1d1140907f 100644 --- a/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/imgproc/Homografia.java +++ b/ProyectoAndroid/ChessTrack/src/uy/edu/fing/chesstrack/modulovision/imgproc/Homografia.java @@ -16,7 +16,7 @@ public class Homografia implements ImgProcInterface { private static final String TAG = "CHESSTRACK::Homografia"; private final Mat _matrizTransformada; - private final Rect _rectPOI; + private final Rect _rectROI; private int _media; private int _offset; @@ -29,9 +29,9 @@ public class Homografia implements ImgProcInterface { Mat dst = new Mat(4,1,CvType.CV_32FC2); Point p1, p2, p3, p4; - Point[] ret = getBestPoints(vertices, Calibracion.getInstance().getImagenCalibrada().size()); + Point[] ret = getBestPoints(vertices, Calibracion.getInstance().get_sizeFrame()); - Log.i(TAG, "Best Points= " + ret); + Log.i(TAG, "Best Points= " + ret.toString()); p1 = ret[0]; p2 = ret[1]; p3 = ret[2]; @@ -46,7 +46,7 @@ public class Homografia implements ImgProcInterface { _media = (int) Math.floor( Math.round((d12+d23+d34+d14)/4)); // El offset es el tamaño de dos celdas (para abarcar el primer casillero y dejar un borde al tablero - _offset = (_media/6); + _offset = 2*(_media/6); Log.i(TAG, "media= " + _media); Log.i(TAG, "offset= " + _offset); @@ -54,11 +54,11 @@ public class Homografia implements ImgProcInterface { src.put(0,0, (int)p1.x,(int)p1.y, (int)p2.x,(int)p2.y, (int)p3.x,(int)p3.y, (int)p4.x,(int)p4.y); dst.put(0,0, _offset,_offset, _offset+_media,_offset, _offset+_media,_offset+_media, _offset,_offset+_media ); - _rectPOI = new Rect(new Point(0,0), new Point(2*_offset+_media,2*_offset+_media)); + _rectROI = new Rect(new Point(0,0), new Point(2*_offset+_media,2*_offset+_media)); Calibracion.getInstance(); - Calibracion.setRectPOI(_rectPOI); + Calibracion.setRectROI(_rectROI); - Log.i(TAG, "rectPOI size= " + _rectPOI.size()); + Log.i(TAG, "rectROI size= " + _rectROI.size()); _matrizTransformada = Imgproc.getPerspectiveTransform(src,dst); } else { @@ -75,10 +75,14 @@ public class Homografia implements ImgProcInterface { // hace la homografia con la matriz calculada en un ppio Imgproc.warpPerspective(inputFrame,inputFrame, _matrizTransformada, inputFrame.size()); - Mat subMat = inputFrame.submat(_rectPOI); - Mat tmp = Mat.zeros(inputFrame.size(), CvType.CV_8UC4); - Mat matTMP = tmp.submat(_rectPOI); - subMat.copyTo(matTMP); + +// Mat subMat = inputFrame.submat(_rectROI); +// Mat tmp = Mat.zeros(inputFrame.size(), CvType.CV_8UC4); +// Mat matTMP = tmp.submat(_rectROI); +// subMat.copyTo(matTMP); + + Mat tmp = Mat.zeros(_rectROI.size(), CvType.CV_8UC4); + (inputFrame.submat(_rectROI)).copyTo(tmp); Log.i(TAG, "processing Frame - FIN"); return tmp;