Search in sources :

Example 6 with MatOfPoint

use of org.opencv.core.MatOfPoint in project kifu-recorder by leonardost.

the class RegistrarPartidaActivity method processarCantosDoTabuleiro.

private void processarCantosDoTabuleiro() {
    posicaoDoTabuleiroNaImagem = new Mat(4, 1, CvType.CV_32FC2);
    posicaoDoTabuleiroNaImagem.put(0, 0, cantosDoTabuleiro[0], cantosDoTabuleiro[1], cantosDoTabuleiro[2], cantosDoTabuleiro[3], cantosDoTabuleiro[4], cantosDoTabuleiro[5], cantosDoTabuleiro[6], cantosDoTabuleiro[7]);
    Point[] cantos = new Point[4];
    cantos[0] = new Point(cantosDoTabuleiro[0], cantosDoTabuleiro[1]);
    cantos[1] = new Point(cantosDoTabuleiro[2], cantosDoTabuleiro[3]);
    cantos[2] = new Point(cantosDoTabuleiro[4], cantosDoTabuleiro[5]);
    cantos[3] = new Point(cantosDoTabuleiro[6], cantosDoTabuleiro[7]);
    contornoDoTabuleiro = new MatOfPoint(cantos);
}
Also used : Mat(org.opencv.core.Mat) MatOfPoint(org.opencv.core.MatOfPoint) Point(org.opencv.core.Point) MatOfPoint(org.opencv.core.MatOfPoint)

Example 7 with MatOfPoint

use of org.opencv.core.MatOfPoint in project kifu-recorder by leonardost.

the class DetectorDeTabuleiro method detectarTabuleiro.

private MatOfPoint detectarTabuleiro(List<MatOfPoint> quadrilateros) {
    HierarquiaDeQuadrilateros hierarquiaDeQuadrilateros = new HierarquiaDeQuadrilateros(quadrilateros);
    MatOfPoint contornoMaisProximoDoTabuleiro = null;
    int numeroDeFilhos = 9999;
    // Tem que ter pelo menos esse número de quadriláteros folha dentro
    int threshold = 10;
    for (MatOfPoint contorno : hierarquiaDeQuadrilateros.externos) {
        if (hierarquiaDeQuadrilateros.hierarquia.get(contorno).size() < numeroDeFilhos && hierarquiaDeQuadrilateros.hierarquia.get(contorno).size() > threshold) {
            contornoMaisProximoDoTabuleiro = contorno;
            numeroDeFilhos = hierarquiaDeQuadrilateros.hierarquia.get(contorno).size();
        }
    }
    return contornoMaisProximoDoTabuleiro;
}
Also used : MatOfPoint(org.opencv.core.MatOfPoint) Point(org.opencv.core.Point) MatOfPoint(org.opencv.core.MatOfPoint)

Example 8 with MatOfPoint

use of org.opencv.core.MatOfPoint in project kifu-recorder by leonardost.

the class DetectorDeTabuleiro method detectarContornos.

private List<MatOfPoint> detectarContornos(Mat imagemComBordasEmEvidencia) {
    // Os contornos delimitados pelas linhas são encontrados
    List<MatOfPoint> contornos = new ArrayList<>();
    Mat hierarquia = new Mat();
    Imgproc.findContours(imagemComBordasEmEvidencia, contornos, hierarquia, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE, new Point(0, 0));
    Log.d("kifu-recorder", "Número de contornos encontrados: " + contornos.size());
    // Remove os contornos muito pequenos, que provavelmente são ruído
    for (Iterator<MatOfPoint> it = contornos.iterator(); it.hasNext(); ) {
        MatOfPoint contorno = it.next();
        // O ideal seria fazer isto aqui como uma razão sobre a área da imagem
        if (Imgproc.contourArea(contorno) < 700) {
            it.remove();
        }
    }
    // A imagem é convertida para um formato colorido novamente
    Imgproc.cvtColor(imagemComBordasEmEvidencia, imagem, Imgproc.COLOR_GRAY2BGR, 4);
    imagemComBordasEmEvidencia.release();
    return contornos;
}
Also used : Mat(org.opencv.core.Mat) ArrayList(java.util.ArrayList) MatOfPoint(org.opencv.core.MatOfPoint) Point(org.opencv.core.Point) MatOfPoint(org.opencv.core.MatOfPoint)

Example 9 with MatOfPoint

use of org.opencv.core.MatOfPoint in project kifu-recorder by leonardost.

the class DetectorDeTabuleiro method detectarQuadrilateros.

private List<MatOfPoint> detectarQuadrilateros(List<MatOfPoint> contornos) {
    List<MatOfPoint> quadrilateros = new ArrayList<>();
    for (MatOfPoint contorno : contornos) {
        MatOfPoint2f contour2f = new MatOfPoint2f();
        MatOfPoint2f approx2f = new MatOfPoint2f();
        contorno.convertTo(contour2f, CvType.CV_32FC2);
        // * 0.02 e * 0.03 também têm resultados interessantes
        // Aparentemente, quanto maior o epsilon, mais curvas que não se encaixam perfeitamente nos contornos
        // são consideradas. Contudo, esse parâmetro parece ser bastante sensível.
        // Imgproc.approxPolyDP(contour2f, approx2f, Imgproc.arcLength(contour2f, true) * 0.04, true);
        // Imgproc.approxPolyDP(contour2f, approx2f, Imgproc.arcLength(contour2f, true) * 0.008, true);  // perde muitos quadrados
        // Imgproc.approxPolyDP(contour2f, approx2f, Imgproc.arcLength(contour2f, true) * 0.01, true);  // borda do tabuleiro encontrada bem, mas quadrados internos sofrem. Talvez seja melhor usar este por detectar melhor o quadrado externo
        // Imgproc.approxPolyDP(contour2f, approx2f, Imgproc.arcLength(contour2f, true) * 0.015, true);  // melhores resultados até agora
        Imgproc.approxPolyDP(contour2f, approx2f, Imgproc.arcLength(contour2f, true) * 0.012, true);
        // Imgproc.approxPolyDP(contour2f, approx2f, Imgproc.arcLength(contour2f, true) * 0.008, true);
        MatOfPoint approx = new MatOfPoint();
        approx2f.convertTo(approx, CvType.CV_32S);
        double contourArea = Math.abs(Imgproc.contourArea(approx2f));
        // Se tem 4 lados, é convexo e não é muito pequeno, é um quadrado válido
        if (approx2f.toList().size() == 4 && contourArea > 400 && Imgproc.isContourConvex(approx)) {
            quadrilateros.add(approx);
        }
    }
    Log.d("kifu-recorder", "Número de quadriláteros encontrados: " + quadrilateros.size());
    return quadrilateros;
}
Also used : MatOfPoint2f(org.opencv.core.MatOfPoint2f) ArrayList(java.util.ArrayList) MatOfPoint(org.opencv.core.MatOfPoint)

Example 10 with MatOfPoint

use of org.opencv.core.MatOfPoint in project kifu-recorder by leonardost.

the class DetectorDeTabuleiro method processar.

/**
 * Processa a imagem fornecida. Retorna verdadeiro se o processamento completo ocorreu com
 * sucesso, ou seja, se um tabuleiro de Go foi detectado na imagem. Retorna falso, caso
 * contrário.
 *
 * @return boolean
 */
public boolean processar() {
    if (imagem == null) {
        // lançar erro
        return false;
    }
    Mat imagemComBordasEmEvidencia = detectarBordas();
    // Se quiser ver a saída do detector de bordas Cammy
    // Imgproc.cvtColor(imagemComBordasEmEvidencia, imagemDePreview, Imgproc.COLOR_GRAY2BGR, 4); if (true) return false;
    // imagemDePreview = imagemComBordasEmEvidencia; if (true) return false;
    List<MatOfPoint> contornos = detectarContornos(imagemComBordasEmEvidencia);
    if (contornos.isEmpty()) {
        Log.i(TestesActivity.TAG, "> Processamento de imagem: contornos não foram encontrados.");
        return false;
    }
    // Se quiser ver a saída do detector de contornos
    // Imgproc.drawContours(imagemDePreview, contornos, -1, new Scalar(0, 0, 255), 2); if (true) return false;
    List<MatOfPoint> quadrilateros = detectarQuadrilateros(contornos);
    if (quadrilateros.isEmpty()) {
        Log.i(TestesActivity.TAG, "> Processamento de imagem: quadriláteros não foram encontrados.");
        return false;
    }
    // Se quiser ver a saída do detector de quadriláteros
    // for (MatOfPoint quadrilatero : quadrilateros) { List<MatOfPoint> listaContorno = new ArrayList<MatOfPoint>(); listaContorno.add(quadrilatero); Imgproc.drawContours(imagemDePreview, listaContorno, -1, new Scalar(255, 0, 0), 3); } if (true) return false;
    MatOfPoint quadrilateroDoTabuleiro = detectarTabuleiro(quadrilateros);
    if (quadrilateroDoTabuleiro == null) {
        Log.i(TestesActivity.TAG, "> Processamento de imagem: quadrilátero do tabuleiro não foi encontrado.");
        return false;
    }
    HierarquiaDeQuadrilateros hierarquiaDeQuadrilateros = new HierarquiaDeQuadrilateros(quadrilateros);
    double areaMedia = 0;
    for (MatOfPoint quadrilatero : hierarquiaDeQuadrilateros.hierarquia.get(quadrilateroDoTabuleiro)) {
        areaMedia += Imgproc.contourArea(quadrilatero);
    }
    areaMedia /= hierarquiaDeQuadrilateros.hierarquia.get(quadrilateroDoTabuleiro).size();
    double areaDoTabuleiro = Imgproc.contourArea(quadrilateroDoTabuleiro);
    double razao = areaMedia / areaDoTabuleiro;
    // com a área do quadrado do tabuleiro
    if (razao <= 1.0 / 324.0) {
        // 18 quadrados por 18
        dimensaoDoTabuleiro = 19;
    } else if (razao <= 1.0 / 144.0) {
        // 12 quadrados por 12
        dimensaoDoTabuleiro = 13;
    } else {
        dimensaoDoTabuleiro = 9;
    }
    List<Point> cantosDoTabuleiro = ordenarCantos(quadrilateroDoTabuleiro);
    if (desenharPreview) {
        // Desenhista.desenhaInterseccoesECantosDoTabuleiro(imagemDePreview, intersecoes, cantosDoTabuleiro);
        Desenhista.desenharContornoDoTabuleiro(imagemDePreview, quadrilateroDoTabuleiro);
    }
    posicaoDoTabuleiroNaImagem = new Mat(4, 1, CvType.CV_32FC2);
    posicaoDoTabuleiroNaImagem.put(0, 0, (int) cantosDoTabuleiro.get(0).x, (int) cantosDoTabuleiro.get(0).y, (int) cantosDoTabuleiro.get(1).x, (int) cantosDoTabuleiro.get(1).y, (int) cantosDoTabuleiro.get(2).x, (int) cantosDoTabuleiro.get(2).y, (int) cantosDoTabuleiro.get(3).x, (int) cantosDoTabuleiro.get(3).y);
    /*
        for (int i = 0; i < posicaoDoTabuleiroNaImagem.rows(); ++i) {
            for (int j = 0; j < posicaoDoTabuleiroNaImagem.cols(); ++j) {
                double[] valor = posicaoDoTabuleiroNaImagem.get(i, j);
                Log.d(TestesActivity.TAG, "(" + i + ", " + j + ") = " + valor[0] + ", " + valor[1]);
            }
        }
        */
    processadoComSucesso = true;
    return true;
}
Also used : Mat(org.opencv.core.Mat) MatOfPoint(org.opencv.core.MatOfPoint) Point(org.opencv.core.Point) MatOfPoint(org.opencv.core.MatOfPoint)

Aggregations

MatOfPoint (org.opencv.core.MatOfPoint)15 Point (org.opencv.core.Point)12 Mat (org.opencv.core.Mat)9 ArrayList (java.util.ArrayList)6 MatOfPoint2f (org.opencv.core.MatOfPoint2f)4 Scalar (org.opencv.core.Scalar)4 Rect (org.opencv.core.Rect)3 Size (org.opencv.core.Size)3 KeyPoint (org.opencv.core.KeyPoint)1 MatOfKeyPoint (org.opencv.core.MatOfKeyPoint)1