Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • aricca/chessTrack
  • nicolas.furquez/chessTrack
2 results
Show changes
Commits on Source (24)
Showing
with 1151 additions and 148 deletions
This diff is collapsed.
......@@ -201,8 +201,8 @@ public class ChessTrackActivity extends Activity implements
break;
case JUGAR:
Log.i(TAG, "jugando...");
return _manager.processFrame(inputFrame);
// break;
_manager.processFrame(inputFrame);
break;
case IDLE:
break;
}
......
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 static final String TAG = "CHESSTRACK::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);
}
}
......@@ -13,18 +13,18 @@ public class Client {
private static Client _clientInstance;
private Socket serverSocket;
private int _serverPort;
private String _serverIp;
private int _serverPort = 5556;
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) {
......
......@@ -6,6 +6,7 @@ import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
import uy.edu.fing.chesstrack.modulovision.Calibracion;
......@@ -13,122 +14,196 @@ 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[][] tablero;
private final int CANT_FILAS = 8;
// 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
private final Mat[][] escaques;
private static Modelador instance;
// private static Modelador instance;
private Modelador(){
tablero = new int[CANT_FILAS][CANT_FILAS];
public Modelador() {
tablero = Mat.zeros(new Size(8, 8), CvType.CV_8UC1);
escaques = new Mat[CANT_FILAS][CANT_FILAS];
//TODO init tablero
}
public static Modelador getInstance(){
if (instance == null){
instance = new Modelador();
public void dividirTablero(Mat inputFrame) {
Imgproc.cvtColor(inputFrame, inputFrame, Imgproc.COLOR_RGBA2GRAY, 4);
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 anchoEscaque = (int) Math.floor(ancho / (CANT_FILAS + 2));
Log.i(TAG, "largoEscaque= " + largoEscaque);
Log.i(TAG, "anchoEscaque= " + anchoEscaque);
for (int i = 0; i < CANT_FILAS; i++) {
for (int j = 0; j < CANT_FILAS; j++) {
int rowStart = (int) Math.floor(largoEscaque) + i
* largoEscaque + 4;
int rowEnd = (int) Math.floor(largoEscaque) + i * largoEscaque
+ largoEscaque - 4;
int colStart = (int) Math.floor(anchoEscaque) + j
* anchoEscaque + 4;
int colEnd = (int) Math.floor(anchoEscaque) + j * anchoEscaque
+ anchoEscaque - 4;
escaques[i][j] = inputFrame.submat(colStart, colEnd, rowStart,
rowEnd);
}
}
return instance;
}
public void dividirTablero(Mat inputFrame){
private int getHayFichaEnEscaque(int i, int j) {
int ret = 0;
Mat mIntermediateMat = new Mat();
Imgproc.Sobel(escaques[i][j], mIntermediateMat, CvType.CV_8U, 1, 1);
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_white = Core.countNonZero(mIntermediateMat);
if (cant_pix_white > (MIN_CANT_PIX_WHITE)) {
ret = 1;
}
return ret;
}
Rect roi = Calibracion.getInstance().getRectROI();
Mat proccesFrame = inputFrame.submat(roi);
int largo = proccesFrame.rows();
int ancho = proccesFrame.cols();
// obtengo cuanto mide en ancho y largo un escaque
int largoEscaque = (int) Math.floor(largo /(CANT_FILAS+2) );//+1 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);
for (int i = 0; i < CANT_FILAS; i++){
for (int j = 0; j < CANT_FILAS; j++){
int rowStart=(int)Math.floor(largoEscaque)+ i*largoEscaque+4;
int rowEnd = (int)Math.floor(largoEscaque)+i*largoEscaque + largoEscaque-4;
int colStart = (int)Math.floor(anchoEscaque)+j*anchoEscaque+4;
int colEnd = (int)Math.floor(anchoEscaque)+j*anchoEscaque + anchoEscaque-4;
escaques[i][j]= inputFrame.submat(colStart, colEnd,rowStart, rowEnd);
public Mat getMatrizFichas(Mat frame) {
dividirTablero(frame);
tablero = Mat.zeros(new Size(8, 8), CvType.CV_8UC1);
for (int i = 0; i < CANT_FILAS; i++) {
for (int j = 0; j < CANT_FILAS; j++) {
tablero.put(i, j, getHayFichaEnEscaque(i, j));
}
}
return tablero.t();
}
public Mat dibujarEscaque(){
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);
public Mat dibujarEscaque() {
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;
int pos_y = 0;
for (int i = 0; i < CANT_FILAS; i++){
for (int j = 0; j < CANT_FILAS; j++){
pos_x = (int) (escaques[i][j].size().width*i);
pos_y = (int) (escaques[i][j].size().height*j);
subm = tmp.submat(new Rect(new Point(pos_x,pos_y) ,escaques[i][j].size()));
for (int i = 0; i < CANT_FILAS; i++) {
for (int j = 0; j < CANT_FILAS; j++) {
pos_x = (int) (escaques[i][j].size().width * i);
pos_y = (int) (escaques[i][j].size().height * j);
subm = tmp.submat(new Rect(new Point(pos_x, pos_y),
escaques[i][j].size()));
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 dibujarEscaquesCanny(){
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);
public Mat dibujarEscaquesCanny() {
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();
int pos_x = 0;
int pos_y = 0;
for (int i = 0; i < CANT_FILAS; i++){
for (int j = 0; j < CANT_FILAS; j++){
pos_x = (int) (escaques[i][j].size().width*i);
pos_y = (int) (escaques[i][j].size().height*j);
subm = tmp.submat(new Rect(new Point(pos_x,pos_y) ,escaques[i][j].size()));
for (int i = 0; i < CANT_FILAS; i++) {
for (int j = 0; j < CANT_FILAS; j++) {
pos_x = (int) (escaques[i][j].size().width * i);
pos_y = (int) (escaques[i][j].size().height * j);
subm = tmp.submat(new Rect(new Point(pos_x, pos_y),
escaques[i][j].size()));
Imgproc.Canny(escaques[i][j], mIntermediateMat, 80, 90);
Imgproc.cvtColor(mIntermediateMat, subm, Imgproc.COLOR_GRAY2RGBA,4);
Imgproc.cvtColor(mIntermediateMat, subm,
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));
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));
}
}
return tmp;
}
public Mat dibujarEscaquesSobel(){
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);
public Mat dibujarEscaquesSobel(int version) {
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);
Mat mIntermediateMat = new Mat();
int pos_x = 0;
int pos_y = 0;
for (int i = 0; i < CANT_FILAS; i++){
for (int j = 0; j < CANT_FILAS; j++){
pos_x = (int) (escaques[i][j].size().width*i);
pos_y = (int) (escaques[i][j].size().height*j);
subm = tmp.submat(new Rect(new Point(pos_x,pos_y) ,escaques[i][j].size()));
Imgproc.cvtColor(escaques[i][j] ,mIntermediateMat, Imgproc.COLOR_RGBA2GRAY,4);
Imgproc.Sobel(mIntermediateMat, mIntermediateMat, CvType.CV_8U, 1, 1);
Log.i(TAG, "cant_pix_INI");
for (int i = 0; i < CANT_FILAS; i++) {
for (int j = 0; j < CANT_FILAS; j++) {
pos_x = (int) (escaques[i][j].size().width * i);
pos_y = (int) (escaques[i][j].size().height * j);
subm = tmp.submat(new Rect(new Point(pos_x, pos_y),
escaques[i][j].size()));
// Imgproc.cvtColor(escaques[i][j] ,mIntermediateMat,
// Imgproc.COLOR_RGBA2GRAY,4);
Imgproc.Sobel(escaques[i][j], mIntermediateMat, CvType.CV_8U,
1, 1);
Core.convertScaleAbs(mIntermediateMat, mIntermediateMat, 10, 0);
Imgproc.threshold(mIntermediateMat, mIntermediateMat, 70, 255, Imgproc.THRESH_BINARY);
int cant_pix = mIntermediateMat.cols()*mIntermediateMat.rows();
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)));
int cant_pix = mIntermediateMat.cols()
* mIntermediateMat.rows();
int cant_pix_white = Core.countNonZero(mIntermediateMat);
Log.i(TAG, "cant_pix=" + cant_pix);
Log.i(TAG, "cant_pix_white=" + cant_pix_white);
switch (version) {
case 1:
if (cant_pix_white > (MIN_CANT_PIX_WHITE)) {
Imgproc.cvtColor(mIntermediateMat, subm,
Imgproc.COLOR_GRAY2RGBA, 4);
} else {
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));
}
Imgproc.cvtColor(mIntermediateMat, subm,
Imgproc.COLOR_GRAY2RGBA, 4);
break;
default:
Imgproc.cvtColor(escaques[i][j], subm,
Imgproc.COLOR_GRAY2RGBA, 4);
break;
if (cant_pix_white > (50) ){
Imgproc.cvtColor(mIntermediateMat, subm, Imgproc.COLOR_GRAY2RGBA,4);
}else{
escaques[i][j].copyTo(subm);
}
}
}
Log.i(TAG, "cant_pix_FIN");
return tmp;
}
}
package uy.edu.fing.chesstrack.modulovision;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
import org.opencv.video.BackgroundSubtractorMOG2;
import android.util.Log;
public class DetectorOclusion {
private static final String TAG = "CHESSTRACK::BackgroundSupress";
private static final int OCLUSION = 0;
private static final int ESTABLE = 1;
private static final int TRANSICION = 2;
private static final int ENVIAR_TABLERO = 3;
private static final int START = -1;
private final Mat _fgMaskMOG2;
private Mat _resultado;
private BackgroundSubtractorMOG2 _pMOG2;
private final Mat _morphKernel;
private int _estadoANTERIOR;
private int _estadoACTUAL;
public DetectorOclusion() {
super();
Log.i(TAG, "constructor INI");
_morphKernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT,
new Size(3, 3));
_fgMaskMOG2 = new Mat(4, 1, CvType.CV_8UC1);
_pMOG2 = new BackgroundSubtractorMOG2();
_estadoACTUAL = START;
_resultado = new Mat();
Log.i(TAG, "constructor FIN");
}
public Mat get_resultado() {
return _resultado;
}
public void set_resultado(Mat _resultado) {
this._resultado = _resultado;
}
public boolean hayNuevoTableroValido(Mat inputFrame) {
/*
* if (_estadoACTUAL == START){ _pMOG2 = new BackgroundSubtractorMOG2();
* // MOG2 approach }
*/
Log.i(TAG, "Procesar!");
Log.i(TAG, "Region SIZE=" + inputFrame.size());
_pMOG2.apply(inputFrame, _fgMaskMOG2);
Imgproc.erode(_fgMaskMOG2, _fgMaskMOG2, _morphKernel);
Log.i(TAG, "Apply erode");
Imgproc.threshold(_fgMaskMOG2, _fgMaskMOG2, 200, 255,
Imgproc.THRESH_BINARY);
Log.i(TAG, "Apply threshold");
// Imgproc.dilate(_fgMaskMOG2, _fgMaskMOG2, _morphKernel);
// Log.i(TAG, "Apply dilate");
Scalar suma = Core.sumElems(_fgMaskMOG2);
Log.i(TAG, "SUMA = " + suma);
_estadoANTERIOR = _estadoACTUAL;
if (suma.val[0] > 1250000) {
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));
*/
} else {
if (_estadoANTERIOR == OCLUSION) {
/*
* 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));
*/
_estadoACTUAL = ENVIAR_TABLERO;
_pMOG2 = new BackgroundSubtractorMOG2(); // MOG2 approach
Log.i(TAG, "VEO ENVIAR !!!");
}
if (_estadoANTERIOR == ENVIAR_TABLERO) {
_estadoACTUAL = ESTABLE;
Log.i(TAG, "VEO ESTABLE !!!");
}
}
Log.i(TAG, "END");
Imgproc.cvtColor(_fgMaskMOG2, _resultado, Imgproc.COLOR_GRAY2RGBA, 4);
return (_estadoACTUAL == ENVIAR_TABLERO);
}
}
/*
* double maxArea = 0; MatOfPoint largestContour = null;
* Imgproc.findContours(_fgMaskMOG2, contours, new Mat(), Imgproc.RETR_LIST,
* Imgproc.CHAIN_APPROX_TC89_L1); for (MatOfPoint contour : contours) { double
* area = Imgproc.contourArea(contour); if (area > maxArea) { maxArea = area;
* largestContour = contour; } } Log.i(TAG, "ESTABLE !!!" + maxArea); if
* ((largestContour != null) && (maxArea > 10000)){ Log.i(TAG, "MANO !!!" +
* maxArea); Rect boundingRect = Imgproc.boundingRect(largestContour);
* ToneGenerator toneG = new ToneGenerator(AudioManager.STREAM_ALARM, 50);
* toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 200); // 200 is
* duration in ms }
*/
/*
* Imgproc.findContours(_fgMaskMOG2, contours, new Mat(), Imgproc.RETR_LIST,
* Imgproc.CHAIN_APPROX_NONE);
*
* for(int idx = 0; idx < contours.size(); idx++) { double area =
* Imgproc.contourArea(contours.get(idx)); Log.i(TAG, "CONTOUR = AREA: " +
* area); if ((area > 15000) && (area < 70000)){ Log.i(TAG, "DRAW !!! : " +
* area); Scalar color = new Scalar(255,127,127); Rect r =
* Imgproc.boundingRect(contours.get(idx)); Log.i(TAG,
* "3 at backgroundS "+(_fgMaskMOG2.type() == CvType.CV_8UC1));
* Core.rectangle(_fgMaskMOG2, r.tl(), r.br(), color, 2, 8, 0);
* //Imgproc.drawContours(_fgMaskMOG2, contours, idx, color); } }
*
* contours.clear();
*/
\ No newline at end of file
......@@ -3,10 +3,12 @@ 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;
import android.media.ToneGenerator;
import android.util.Log;
import uy.edu.fing.chesstrack.communication.Client;
public class Manager {
......@@ -20,7 +22,7 @@ public class Manager {
+ "--------------------------------------------------------------------------\n"
+ " .:: CHESSTRACK ::. seguimiento de una partida de Ajedrez\n"
+ "\n"
+ " TImag 2014\n"
+ " TImag 2014\n"
+ " Nicolas Furquez - Aylen Ricca\n"
+ "--------------------------------------------------------------------------\n";
......@@ -29,14 +31,18 @@ public class Manager {
private static Adquisicion _adquisicion;
private static Client _client;
private static DetectorOclusion _detectorOclusion;
private boolean _debug;
private static Modelador _modelador;
private static Logica _logica;
private final boolean _debug;
private int _cantJugada;
protected Manager() {
_estado = ARMANDO_TABLERO;
_salida = NOT;
_adquisicion = null;
_client = null;
_debug = true;
_debug = false;
_cantJugada = 0;
}
public static Manager getInstance() {
......@@ -62,46 +68,6 @@ public class Manager {
_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
//
region = _detectorOclusion.procesarImagen(region);
// 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)) {
......@@ -109,11 +75,12 @@ public class Manager {
50);
toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 200); // ms
if (_salida == OK) {
_client.SendData("FIN calibrar\n . . . armando tablero!");
_client.SendData("FIN calibrar\n . . . armando tablero!\n");
}
try {
_adquisicion = new Adquisicion();
_detectorOclusion = new DetectorOclusion();
_modelador = new Modelador();
_logica = new Logica();
} catch (Exception e) {
e.printStackTrace();
return false;
......@@ -126,6 +93,66 @@ 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);
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");
Mat nuevo = _modelador.getMatrizFichas(region);
if (_logica.validarTableroArmado(nuevo)) {
iniciarJuego();
}
break;
case JUGANDO:
Log.i(TAG, "Jugando");
if (_detectorOclusion.hayNuevoTableroValido(region)) {
Log.i(TAG, "Tablero Valido");
// llamar al modelador
Mat aux = _modelador.getMatrizFichas(region);
// Log.i(TAG, "MATRIZ=" + aux.dump());
// region = _modelador.dibujarEscaquesSobel(2);
if (_logica.validarNuevoTablero(aux)) {
if (_salida == OK) {
_client.SendData("Nuevo Tablero Valido = ["
+ String.valueOf(_cantJugada) + "]\n");
_cantJugada++;
_client.SendData(" ".concat(aux.dump().concat("\n")));
}
}
}
break;
}
if (_debug) {
Log.i(TAG, "DEBUG");
Mat tmp = Mat.zeros(inputFrame.size(), CvType.CV_8UC4);
Mat matTMP = tmp.submat(Calibracion.getRectROI());
region.copyTo(matTMP);
return tmp;
}
return inputFrame;
}
public void destroy() {
if (_client != null) {
_client.Stop();
......
......@@ -72,17 +72,20 @@ public class Homografia implements ImgProcInterface {
@Override
public Mat procesarImagen(Mat inputFrame) {
Log.i(TAG, "processing Frame - INI");
double x = inputFrame.size().width;
double y = inputFrame.size().height;
if (x < _rectROI.size().width){
x = _rectROI.size().width;
}
if (y < _rectROI.size().height){
y = _rectROI.size().height;
}
Mat aux = new Mat();
// hace la homografia con la matriz calculada en un ppio
Imgproc.warpPerspective(inputFrame,inputFrame, _matrizTransformada, inputFrame.size());
// Mat subMat = inputFrame.submat(_rectROI);
// Mat tmp = Mat.zeros(inputFrame.size(), CvType.CV_8UC4);
// Mat matTMP = tmp.submat(_rectROI);
// subMat.copyTo(matTMP);
Imgproc.warpPerspective(inputFrame,aux, _matrizTransformada, new Size(x,y));
Mat tmp = Mat.zeros(_rectROI.size(), CvType.CV_8UC4);
(inputFrame.submat(_rectROI)).copyTo(tmp);
(aux.submat(_rectROI)).copyTo(tmp);
Log.i(TAG, "processing Frame - FIN");
return tmp;
......
......@@ -3,3 +3,6 @@ project( SubsBackground )
find_package( OpenCV REQUIRED )
add_executable( SubsBackground SubsBackground.cpp )
target_link_libraries( SubsBackground ${OpenCV_LIBS} )
project( Corners )
add_executable( Corners Corners.cpp )
target_link_libraries( Corners ${OpenCV_LIBS} )
#include <string>
#include <iostream>
#include <vector>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
//----------------------------------------------------------
// MAIN
//----------------------------------------------------------
int main(int argc, char* argv[])
{
// src image
Mat src;
// dst image
Mat dst;
// Image loading
namedWindow("result");
namedWindow("src");
src=imread("image.png",0);
cv::cvtColor(src,dst,cv::COLOR_GRAY2BGR);
Mat corners;
cv::goodFeaturesToTrack(src,corners,100,0.01,20.0);
for(int i=0;i<corners.rows;++i)
{
circle(dst,cv::Point(corners.at<float>(i,0),corners.at<float>(i,1)),3,Scalar(255,0,0),-1,CV_AA);
}
imshow("src",src);
imshow("result",dst);
//----------------------------------------------------------
// Wait key press
//----------------------------------------------------------
while (waitKey(0) != 'q');
destroyAllWindows();
return 0;
}
......@@ -45,6 +45,7 @@ h5 {
}
p {
margin-bottom: 20px;
font-size: 15px;
}
.lead {
font-size: 14px;
......
This diff is collapsed.
<!DOCTYPE html>
<html lang="en">
<head>
<title>ChessTrack.::.Introducción</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Your description">
<meta name="keywords" content="Your keywords">
<meta name="author" content="Your name">
<link rel="icon" href="img/favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="img/favicon.ico" type="image/x-icon" />
<link rel="stylesheet" href="css/bootstrap.css" type="text/css" media="screen">
<link rel="stylesheet" href="css/responsive.css" type="text/css" media="screen">
<link rel="stylesheet" href="css/camera.css" type="text/css" media="screen">
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen">
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,600,700' rel='stylesheet' type='text/css'>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/jquery.easing.1.3.js"></script>
<script type="text/javascript" src="js/camera.js"></script>
<script src="js/jquery.ui.totop.js" type="text/javascript"></script>
</head>
<body>
<!--==============================header=================================-->
<header class="p0">
<div class="container">
<div class="row">
<div class="span12">
<div class="header-block clearfix">
<div class="clearfix header-block-pad">
<h1 class="brand"><a href="index.html"><img src="img/logo.png" alt=""></a><span>Seguimiento de una Partida de Ajedrez.</span></h1>
<span class="contacts">Integrantes:<br>
<span>&nbsp;&nbsp;&nbsp;Aylen Ricca (<a href="mailto:aricca@fing.edu.uy">aricca@fing.edu.uy</a>)<br>&nbsp;&nbsp;&nbsp;Nicolás Furquez (<a href="mailto:nfurquez@fing.edu.uy">nfurquez@fing.edu.uy</a>)</span>
<br>Tutor:<br>
<span>&nbsp;&nbsp;&nbsp;Álvaro Gómez (<a href="mailto:agomez@fing.edu.uy">agomez@fing.edu.uy</a>)</span>
</span>
<span class="contacts">
<img src="img/chess0.png" alt="">
</span>
</div>
<div class="navbar navbar_ clearfix">
<div class="navbar-inner navbar-inner_">
<div class="container">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse_">MENU</a>
<div class="nav-collapse nav-collapse_ collapse">
<ul class="nav sf-menu">
<li class="active li-first"><a href="index.html"><em class="hidden-phone"></em><span class="visible-phone">Home</span></a></li>
<li class="sub-menu"><a href="#">Introducción</a>
<ul>
<li><a href="descripcion_del_proyecto.html">Descripción del Proyecto</a></li>
<li class="sub-menu"><a href="#">Documentos</a>
<ul>
<li><a href="documentos/presentacion_inicial.pdf" target="_blank">Presentación Inicial</a></li>
<li><a href="documentos/plan_de_trabajo.pdf">Plan de Trabajo</a></li>
<li><a href="documentos/presentacion_final.pdf">Presentación Final</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="desarrollo.html">Desarrollo</a></li>
<li><a href="trabajo_a_futuro.html">Trabajo a Futuro</a></li>
<li><a href="links_de_interes.html">Links de Interés</a></li>
<li><a href="galeria_de_imagenes.html">Galería de Imágenes</a></li>
<li><a href="videos.html">Videos</a></li>
</ul>
</div>
<ul class="social-icons">
<li><a href="http://www.fing.edu.uy/"><img src="img/icon-1.png" alt=""></a></li>
<li><a href="http://www.universidad.edu.uy/"><img src="img/icon-2.png" alt=""></a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</header>
<!--==============================content=================================-->
<section id="content">
<div class="sub-content">
<div class="container">
<div class="row">
<div class="span6 float2">
<br><br><br><br><br>
<p>Como antecedentes se cuenta con un proyecto de la asignatura llevado a cabo en 2013, 8x8CAM, el cual es similar en características pero desarrollado para PC y sólo se tomaban fotogramas del tablero antes y después del movimiento, en nuestro caso el procesamiento es en tiempo real y es de sumo interés poder identificar cuándo obtener frames con tableros válidos.</p>
<p>El tablero utilizado será uno profesional como los de la figura, proporcionado por el tutor; se utilizará un ambiente donde la iluminación será controlada y la partida será “lenta”, con esto se quiere decir que se dará tiempo al dispositivo a procesar la partida entre movimiento y movimiento.</p>
<figure>
<img src="galeria/img_desc_03.png" class="img-radius" alt="Tablero Profesional" style="width: 250px">
&nbsp;&nbsp;
<img src="galeria/img_desc_04.png" class="img-radius" alt="Tablero Profesional" style="width: 250px">
</figure>
<p>Como objetivo opcional, se plantea la posibilidad de transcribir la partida a voz para jugadores no videntes.</p>
<p>Dado que una partida normal de ajedrez es muy rica en movimientos, en un principio se plantea la detección de una partida con movimientos básicos, en la segunda iteración se incluirá la detección de jake y jake mate, valiéndose de las <a href="http://es.wikipedia.org/wiki/Reglamento_del_ajedrez">reglas</a> oficiales de ajedrez, si el tiempo lo permite se tratará de detectar enroques, coronaciones (promociones) y captura al paso, igualmente se tendrá en cuenta en el diseño de la arquitectura estos casos especiales para una futura extensión.</p>
<p>Para procesar las capturas de una forma más eficiente se usará la biblioteca <a href="http://docs.opencv.org/doc/tutorials/introduction/android_binary_package/O4A_SDK.html">OpenCV4Android</a> dado que cuenta con una gran cantidad de utilitarios para el procesamiento de imágenes.</p>
</div>
<div class="span6 float">
<h4>Descripción del Proyecto.</h4>
<p><strong class="clr">En los siguientes párrafos se describen los lineamientos del proyecto.</strong><br>
El trabajo que se aborda es el procesamiento en tiempo real de una partida lenta de ajedrez desde un dipositivo móvil mediante tratamiento de imágenes. A su vez, contar con la persistencia y/o transmisión de la partida en <a href="http://es.wikipedia.org/wiki/Notaci%C3%B3n_algebraica">notación algebraica</a>.</p>
<figure>
<a href="https://www.youtube.com/v/GdQmgzBK0Jo"><img src="galeria/img_desc_01.png" class="img-radius" alt="Reproducción de partida" style="width: 300px"></a>
&nbsp;&nbsp;&nbsp;&nbsp;
<img src="galeria/img_desc_02.png" class="img-radius" alt="Notación algebraica" style="height: 300px">
</figure>
<p>Las restricciones que se plantean para esta realidad son la utilización de un tablero profesional, su ubicación en una posicion fija, iluminación controlada y el dispositivo móvil colocado de tal manera que pueda captar con su cámara la totalidad del tablero.</p>
<p>EL proyecto se en marca dentro del proyecto final la asignatura <a href="https://eva.fing.edu.uy/course/view.php?id=520">Tratamiendo de Imágenes por Computador</a> del <a href="http://iie.fing.edu.uy/">Instituto de Ingeniería Eléctrica</a> de la Facultad de Ingeniería de la Universidad de la República. El mismo, como se mencionó anteriormente consiste en reconocer el movimiento de las piezas dentro de una partida de ajedrez. El problema es interesante desde el punto de vista del tratamiento de imágenes, dado que posee una complejidad rica en problemas comunes en el proceso de racionalizar una imagen, desde detectar dónde se ubica cada ficha en todo momento y reconocer su recorrido, hasta saber cuando no se debe de procesar una imagen ya que el jugador está moviendo las piezas en ese momento.</p>
<p>El problema planteado se presenta en el marco de una partida de ajedrez clásica, en donde interesa transcribir a notación algebraica la partida, en tiempo real, para ser enviada a un servidor o un jugador remoto. Como hoy en día es muy accesible tener un celular con la potencia para procesar imágenes, el proyecto se llava a cabo con la tecnología <a href="http://developer.android.com/index.html">Android</a>.</p>
</div>
</div>
</div>
</div>
</section>
<!--==============================footer=================================-->
<footer>
<div class="container">
<div class="row">
<div class="span4 float2">
Proyecto de fin de curso 2014 de Tratamiento de Imágenes por Computadora dictado en la Facultad de Ingeniería de la Universidad de la República, Uruguay
<br>Sitio web del curso: <a href="https://eva.fing.edu.uy/course/view.php?id=520">Tratamiento de Imágenes por Computadora</a>
</div>
<div class="span8 float">
<ul class="footer-menu">
<li><a href="descripcion_del_proyecto.html">Descripción del Proyecto</a>|</li>
<li><a href="desarrollo.html">Desarrollo</a>|</li>
<li><a href="trabajo_a_futuro.html">Trabajo a Futuro</a>|</li>
<li><a href="links_de_interes.html">Links de Interés</a></li>
<li><a href="galeria_de_imagenes.html">Galería de Imágenes</a></li>
<li><a href="videos.html">Videos</a></li>
</ul>
Stylish 2014 | <a href="mailto:aricca8@gmail.com">@yle</a>
</div>
</div>
</div>
</footer>
<script type="text/javascript" src="js/bootstrap.js"></script>
</body>
</html>
\ No newline at end of file
File added
File added
web/galeria/config0.png

37 KiB

web/galeria/config1.png

35.9 KiB

web/galeria/config2.png

37.1 KiB

web/galeria/config3.png

36.3 KiB