Esempio n. 1
0
  /**
   * Determines which pieces are kings
   *
   * @param in Mat image of board
   */
  public void determineKings(Mat in) {
    int playSquares = 32;

    Mat dst = new Mat(in.rows(), in.cols(), in.type());
    in.copyTo(dst);

    Imgproc.cvtColor(dst, dst, Imgproc.COLOR_BGR2GRAY); // change to single color

    Mat canny = new Mat();
    Imgproc.Canny(dst, canny, 100, 200); // make image a canny image that is only edges; 2,4
    // lower threshold values find more edges
    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    Mat hierarchy = new Mat(); // holds nested contour information
    Imgproc.findContours(
        canny,
        contours,
        hierarchy,
        Imgproc.RETR_LIST,
        Imgproc.CHAIN_APPROX_SIMPLE); // Imgproc.RETR_LIST, TREE

    // draw contour image
    Mat mask = new Mat();
    mask = Mat.zeros(dst.size(), dst.type());
    Imgproc.drawContours(
        mask, contours, -1, new Scalar(255, 255, 255), 1, 8, hierarchy, 2, new Point());
    Highgui.imwrite("contours.jpg", mask);

    ArrayList occupied = new ArrayList<Integer>();
    for (int i = 0; i < playSquares; i++) {
      if (board[i] != 0) occupied.add(i);
    }

    for (int i = 0; i < contours.size(); i++) // assuming only contours are checker pieces
    {
      // determine if it should be a king
      // use Rect r = Imgproc.boundingRect then find height of it by r.height

      // Get bounding rect of contour
      Rect bound = Imgproc.boundingRect(contours.get(i));

      if (bound.height > in.rows() / 8) {
        // board[(int) occupied.get(0)]++; // make it a king
        // occupied.remove(0);
      }
    }

    // or apply to each region of interest

    /*
    // keep track of starting row square
    int parity = 0; // 0 is even, 1 is odd, tied to row number
    int count = 0; // row square
    int rowNum = 0; // row number, starting at 0

    int vsegment = in.rows() / 8; // only accounts 8 playable
    int hsegment = in.cols() / 12; // 8 playable, 2 capture, 2 extra
    int offset = hsegment * 2; // offset for playable board

    // For angle of camera
    int dx = 48;
    hsegment -= 8;


    // Go through all playable squares
    for (int i = 0; i < playSquares; i++)
    {
    	// change offset depending on the row
    	if (parity == 0) // playable squares start on immediate left
    		offset = hsegment * 3 + dx;
    	else // playable squares start on 2nd square from left
    		offset = hsegment * 2 + dx;

    	// find where roi should be
    	Point p1 = new Point(offset + count * hsegment, rowNum * vsegment); // top left point of rectangle (x,y)
    	Point p2 = new Point(offset + (count + 1) * hsegment, (rowNum + 1) * vsegment); // bottom right point of rectangle (x,y)

    	// create rectangle that is board square
    	Rect bound = new Rect(p1, p2);

    	// frame only includes rectangle
    	Mat roi = new Mat(in, bound);

           Imgproc.cvtColor(roi, roi, Imgproc.COLOR_BGR2GRAY); // change to single color

           Mat canny = new Mat();
           Imgproc.Canny(roi, canny, 2, 4); // make image a canny image that is only edges; 2,4
           // lower threshold values find more edges
           List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
           Mat hierarchy = new Mat(); // holds nested contour information
           Imgproc.findContours(canny, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); // Imgproc.RETR_LIST, TREE

           // Get bounding rect of contour
              Rect rect = Imgproc.boundingRect(contours.get(0));

              if (rect.height > in.rows() / 8)
    	{
    		board[i]++; // make it a king
    	}

    	count += 2;
    	if (count == 8)
    	{
    		parity = ++parity % 2; // change odd or even
    		count = 0;
    		rowNum++;
    		hsegment += 1;
    		dx -= 6;
    	}
    }*/
  }
Esempio n. 2
0
  public void processWithContours(Mat in, Mat out) {
    int playSquares = 32; // number of playable game board squares

    // keep track of starting row square
    int parity = 0; // 0 is even, 1 is odd, tied to row number
    int count = 0; // row square
    int rowNum = 0; // row number, starting at 0

    int vsegment = in.rows() / 8; // only accounts 8 playable
    int hsegment = in.cols() / 10; // 8 playable, 2 capture
    int hOffset = hsegment * 2; // offset for playable board
    int vOffset = vsegment + 40;

    // For angle of camera
    int dx = 80;
    int ddx = 0;
    hsegment -= 16;

    int dy = 20;
    vsegment -= 24;
    int ddy = 0;

    // Go through all playable squares
    for (int i = 0; i < playSquares; i++) {
      // change offset depending on the row
      if (parity == 0) // playable squares start on 2nd square from left
      {
        if (rowNum >= 5) dx -= 3;
        hOffset = hsegment * 2 + dx;
      } else // playable squares start on immediate left
      {
        if (rowNum >= 5) dx -= 3;
        hOffset = hsegment + dx;
      }

      if (rowNum == 0) ddy = 5;
      if (rowNum == 4) if (count == 6) ddx = 10;
      if (rowNum == 5) {
        if (count == 0) ddx = -6;
        else if (count == 2) ddx = 6;
        else if (count == 4) ddx = 12;
        else if (count == 6) ddx = 20;
      }
      if (rowNum == 6) {
        if (count == 0) ddx = 0;
        else if (count == 2) ddx = 16;
        else if (count == 4) ddx = 32;
        else if (count == 6) ddx = 40;
      }
      if (rowNum == 7) {
        if (count == 0) ddx = 6;
        else if (count == 2) ddx = 24;
        else if (count == 4) ddx = 40;
        else ddx = 52;
      }

      // find where roi should be
      // System.out.println("" + vOffset);
      Point p1 =
          new Point(
              hOffset + count * hsegment + ddx + 5,
              vOffset + rowNum * vsegment - dy - 5 - ddy); // top left point of rectangle (x,y)
      Point p2 =
          new Point(
              hOffset + (count + 1) * hsegment + ddx - 5,
              vOffset
                  + (rowNum + 1) * vsegment
                  - dy
                  - 5
                  - ddy); // bottom right point of rectangle (x,y)

      // create rectangle that is board square
      Rect bound = new Rect(p1, p2);

      Mat roi;
      char color;
      if (i == 0) {
        // frame only includes rectangle
        roi = new Mat(in, bound);

        // get the color
        color = identifyColor(roi);

        // copy input image to output image
        in.copyTo(out);
      } else {
        // frame only includes rectangle
        roi = new Mat(out, bound);

        // get the color
        color = identifyColor(roi);
      }

      Imgproc.cvtColor(roi, roi, Imgproc.COLOR_BGR2GRAY); // change to single color

      Mat canny = new Mat();
      Imgproc.Canny(roi, canny, 20, 40); // make image a canny image that is only edges; 2,4
      // lower threshold values find more edges
      List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
      Mat hierarchy = new Mat(); // holds nested contour information
      Imgproc.findContours(
          canny,
          contours,
          hierarchy,
          Imgproc.RETR_LIST,
          Imgproc.CHAIN_APPROX_SIMPLE); // Imgproc.RETR_LIST, TREE

      System.out.println(++test + "\t" + contours.size());

      if (contours.size() > 3) // or error value for color is below 1
      {
        switch (color) {
          case COLOR_BLUE:
            // Imgproc.rectangle(out, p1, p2, new Scalar(255, 0, 0), 2);
            Core.rectangle(out, p1, p2, new Scalar(255, 0, 0), 2);
            board[i] = CheckersBoard.BLACK; // end user's piece
            break;
          case COLOR_ORANGE:
            // Imgproc.rectangle(out, p1, p2, new Scalar(0, 128, 255), 2);
            Core.rectangle(out, p1, p2, new Scalar(0, 128, 255), 2);
            board[i] = CheckersBoard.WHITE; // system's piece
            break;
          case COLOR_WHITE:
            // Imgproc.rectangle(out, p1, p2, new Scalar(255, 255, 255), 2);
            Core.rectangle(out, p1, p2, new Scalar(255, 255, 255), 2);
            board[i] = CheckersBoard.EMPTY;
            break;
          case COLOR_BLACK: // this is black
            // Imgproc.rectangle(out, p1, p2, new Scalar(0, 0, 0), 2);
            Core.rectangle(
                out,
                p1,
                p2,
                new Scalar(0, 0, 0),
                2); // maybe add 8, 0 as line type and fractional bits
            board[i] = CheckersBoard.EMPTY;
            break;
        }
      }

      System.out.println("in color switch " + board[i]);
      count += 2;
      if (count == 8) {
        parity = ++parity % 2; // change odd or even
        count = 0;
        rowNum++;
        hsegment += 2;
        dx -= 10;
        dy += 10;
        vsegment += 3;
        ddy = 0;
      }
    }
  }
Esempio n. 3
0
  /**
   * Processes the board image
   *
   * @param in image captured of board
   * @param out processed image of board
   */
  public void processFrame(Mat in, Mat out) {
    // multiple regions of interest

    int playSquares = 32; // number of playable game board squares

    // keep track of starting row square
    int parity = 0; // 0 is even, 1 is odd, tied to row number
    int count = 0; // row square
    int rowNum = 0; // row number, starting at 0

    int vsegment = in.rows() / 8; // only accounts 8 playable
    int hsegment = in.cols() / 10; // 8 playable, 2 capture
    int hOffset = hsegment * 2; // offset for playable board
    int vOffset = vsegment + 40;

    // For angle of camera
    int dx = 80;
    int ddx = 0;
    hsegment -= 16;

    int dy = 20;
    vsegment -= 24;

    // Go through all playable squares
    for (int i = 0; i < playSquares; i++) {
      // change offset depending on the row
      if (parity == 0) // playable squares start on 2nd square from left
      {
        if (rowNum >= 5) dx -= 3;
        hOffset = hsegment * 2 + dx;
      } else // playable squares start on immediate left
      {
        if (rowNum >= 5) dx -= 3;
        hOffset = hsegment + dx;
      }

      if (rowNum == 4) if (count == 6) ddx = 10;
      if (rowNum == 5) {
        if (count == 0) ddx = -6;
        else if (count == 2) ddx = 6;
        else if (count == 4) ddx = 12;
        else if (count == 6) ddx = 20;
      }
      if (rowNum == 6) {
        if (count == 0) ddx = 0;
        else if (count == 2) ddx = 16;
        else if (count == 4) ddx = 32;
        else if (count == 6) ddx = 40;
      }
      if (rowNum == 7) {
        if (count == 0) ddx = 0;
        else if (count == 2) ddx = 24;
        else if (count == 4) ddx = 40;
        else ddx = 52;
      }

      // find where roi should be
      // System.out.println("" + vOffset);
      Point p1 =
          new Point(
              hOffset + count * hsegment + ddx,
              vOffset + rowNum * vsegment - dy); // top left point of rectangle (x,y)
      Point p2 =
          new Point(
              hOffset + (count + 1) * hsegment + ddx,
              vOffset + (rowNum + 1) * vsegment - dy); // bottom right point of rectangle (x,y)

      // create rectangle that is board square
      Rect bound = new Rect(p1, p2);

      char color;
      if (i == 0) {
        // frame only includes rectangle
        Mat roi = new Mat(in, bound);

        // get the color
        color = identifyColor(roi);

        // copy input image to output image
        in.copyTo(out);
      } else {
        // frame only includes rectangle
        Mat roi = new Mat(out, bound);

        // get the color
        color = identifyColor(roi);
      }

      // annotate the output image
      // scalar values as (blue, green, red)
      switch (color) {
        case COLOR_BLUE:
          // Imgproc.rectangle(out, p1, p2, new Scalar(255, 0, 0), 2);
          Core.rectangle(out, p1, p2, new Scalar(255, 0, 0), 2);
          board[i] = CheckersBoard.BLACK; // end user's piece
          break;
        case COLOR_ORANGE:
          // Imgproc.rectangle(out, p1, p2, new Scalar(0, 128, 255), 2);
          Core.rectangle(out, p1, p2, new Scalar(0, 128, 255), 2);
          board[i] = CheckersBoard.WHITE; // system's piece
          break;
        case COLOR_WHITE:
          // Imgproc.rectangle(out, p1, p2, new Scalar(255, 255, 255), 2);
          Core.rectangle(out, p1, p2, new Scalar(255, 255, 255), 2);
          board[i] = CheckersBoard.EMPTY;
          break;
        case COLOR_BLACK: // this is black
          // Imgproc.rectangle(out, p1, p2, new Scalar(0, 0, 0), 2);
          Core.rectangle(
              out,
              p1,
              p2,
              new Scalar(0, 0, 0),
              2); // maybe add 8, 0 as line type and fractional bits
          board[i] = CheckersBoard.EMPTY;
          break;
      }

      count += 2;
      if (count == 8) {
        parity = ++parity % 2; // change odd or even
        count = 0;
        rowNum++;
        hsegment += 2;
        dx -= 10;
        dy += 10;
        vsegment += 3;
      }
    }
  }