/* Draws the outline of a blob in the specified color. * @param b the blob * @param c the color to paint */ void Ball::drawBlob(Blob b, int c) { #ifdef OFFLINE thresh->drawLine(b.getLeftTopX(), b.getLeftTopY(), b.getRightTopX(), b.getRightTopY(), c); thresh->drawLine(b.getLeftTopX(), b.getLeftTopY(), b.getLeftBottomX(), b.getLeftBottomY(), c); thresh->drawLine(b.getLeftBottomX(), b.getLeftBottomY(), b.getRightBottomX(), b.getRightBottomY(), c); thresh->drawLine(b.getRightTopX(), b.getRightTopY(), b.getRightBottomX(), b.getRightBottomY(), c); #endif }
/* When we're looking for balls it is helpful if they are surrounded by green. * The best place to look is underneath. So let's do that. * @param b the potential ball * @return did we find some green? */ bool Ball::greenCheck(Blob b) { const int ERROR_TOLERANCE = 5; const int EXTRA_LINES = 10; const int MAX_BAD_PIXELS = 4; if (b.getRightBottomY() >= IMAGE_HEIGHT - 1 || b.getLeftBottomY() >= IMAGE_HEIGHT-1) return true; if (b.width() > IMAGE_WIDTH / 2) return true; int w = b.width(); int y = 0; int x = b.getLeftBottomX(); stop scan; for (int i = 0; i < w; i+= 2) { y = b.getLeftBottomY(); vertScan(x + i, y, 1, ERROR_TOLERANCE, GREEN, GREEN, scan); if (scan.good > 1) return true; } // try one more in case its a white line int bad = 0; for (int i = 0; i < EXTRA_LINES && bad < MAX_BAD_PIXELS; i++) { int pix = thresh->thresholded[min(IMAGE_HEIGHT - 1, b.getLeftBottomY() + i)][x]; if (pix == GREEN) return true; if (pix != WHITE) bad++; } return false; }
/* Print debugging information for a blob. * @param b the blob */ void Robots::printBlob(Blob b) { #if defined OFFLINE cout << "Outputting blob" << endl; cout << b.getLeftTopX() << " " << b.getLeftTopY() << " " << b.getRightTopX() << " " << b.getRightTopY() << endl; cout << b.getLeftBottomX() << " " << b.getLeftBottomY() << " " << b.getRightBottomX() << " " << b.getRightBottomY() << endl; #endif }
/** * Update the robot values from the blob * * @param b The blob to update our object from. */ void VisualRobot::updateRobot(Blob b) { setLeftTopX(b.getLeftTopX()); setLeftTopY(b.getLeftTopY()); setLeftBottomX(b.getLeftBottomX()); setLeftBottomY(b.getLeftBottomY()); setRightTopX(b.getRightTopX()); setRightTopY(b.getRightTopY()); setRightBottomX(b.getRightBottomX()); setRightBottomY(b.getRightBottomY()); setX(b.getLeftTopX()); setY(b.getLeftTopY()); setWidth(dist(b.getRightTopX(), b.getRightTopY(), b.getLeftTopX(), b.getLeftTopY())); setHeight(dist(b.getLeftTopX(), b.getLeftTopY(), b.getLeftBottomX(), b.getLeftBottomY())); setCenterX(getLeftTopX() + ROUND2(getWidth() / 2)); setCenterY(getRightTopY() + ROUND2(getHeight() / 2)); setDistance(1); }
/* When we're looking for balls it is helpful if they are surrounded by green. * The best place to look is underneath, but that doesn't always work. So let's * try the other sides. * @param b the potential ball * @return did we find some green? */ bool Ball::greenSide(Blob b) { const int ERROR_TOLERANCE = 5; const int X_EXTRA = 8; int x = b.getRightBottomX(); int y = b.getRightBottomY(); stop scan; for (int i = y; i > (b.height()) / 2; i = i - 2) { horizontalScan(x, i, 1, ERROR_TOLERANCE, GREEN, GREEN, x - 1, x + X_EXTRA, scan); if (scan.good > 0) return true; } x = b.getLeftBottomX(); y = b.getLeftBottomY(); for (int i = y; i > (b.height()) / 2; i = i - 2) { horizontalScan(x, i, -1, ERROR_TOLERANCE, GREEN, GREEN, x - X_EXTRA, x + 1, scan); if (scan.good == 0) return true; } return false; }
/* When we process blobs we start them with BAD_VALUE such that we can easily * tell if whatever processing we did worked out. Here we make that check. * @param b the blob we worked on. * @return true when the processing worked, false otherwise */ bool Ball::blobOk(Blob b) { if (b.getLeftTopX() > BAD_VALUE && b.getLeftBottomX() > BAD_VALUE && b.width() > 2) return true; return false; }