/** * Recursively check all neighbouring cells if they belong to the same * object. While doing this, the dimensions (in terms of width and height) * of the object are calculated. * * \param x X coordinate of a covered cell belonging to the object. * \param y Y coordinate of a covered cell belonging to the object. * \param currentBorder The current dimensions of the bounding box of the object so far. * * \return The new dimensions of the bounding box if neighbouring covered cells are found. */ Border AreaDetector::checkNeighbours(unsigned int x, unsigned int y, Border currentBorder) { unsigned int currentIndex = x + y * width; unsigned int leftIndex = x - 1 + y * width; unsigned int rightIndex = x + 1 + y * width; unsigned int topIndex = x + (y + 1) * width; unsigned int bottomIndex = x + (y - 1) * width; workMatrix[currentIndex] = true; if (x > currentBorder.maxX) currentBorder.maxX = x; if (x < currentBorder.minX) currentBorder.minX = x; if (y > currentBorder.maxY) currentBorder.maxY = y; if (y < currentBorder.minY) currentBorder.minY = y; Border result = currentBorder; if ((x > 0) && env->getMatrix()[leftIndex] && !workMatrix[leftIndex]) { Border leftBorder = checkNeighbours(x - 1, y, currentBorder); if (leftBorder.maxX > result.maxX) result.maxX = leftBorder.maxX; if (leftBorder.minX < result.minX) result.minX = leftBorder.minX; if (leftBorder.maxY > result.maxY) result.maxY = leftBorder.maxY; if (leftBorder.minY < result.minY) result.minY = leftBorder.minY; } if ((x < width - 1) && env->getMatrix()[rightIndex] && !workMatrix[rightIndex]) { Border rightBorder = checkNeighbours(x + 1, y, currentBorder); if (rightBorder.maxX > result.maxX) result.maxX = rightBorder.maxX; if (rightBorder.minX < result.minX) result.minX = rightBorder.minX; if (rightBorder.maxY > result.maxY) result.maxY = rightBorder.maxY; if (rightBorder.minY < result.minY) result.minY = rightBorder.minY; } if ((y > 0) && env->getMatrix()[bottomIndex] && !workMatrix[bottomIndex]) { Border bottomBorder = checkNeighbours(x, y - 1, currentBorder); if (bottomBorder.maxX > result.maxX) result.maxX = bottomBorder.maxX; if (bottomBorder.minX < result.minX) result.minX = bottomBorder.minX; if (bottomBorder.maxY > result.maxY) result.maxY = bottomBorder.maxY; if (bottomBorder.minY < result.minY) result.minY = bottomBorder.minY; } if ((y < height - 1) && env->getMatrix()[topIndex] && !workMatrix[topIndex]) { Border topBorder = checkNeighbours(x, y + 1, currentBorder); if (topBorder.maxX > result.maxX) result.maxX = topBorder.maxX; if (topBorder.minX < result.minX) result.minX = topBorder.minX; if (topBorder.maxY > result.maxY) result.maxY = topBorder.maxY; if (topBorder.minY < result.minY) result.minY = topBorder.minY; } return result; }
void LifeManager::update() { if(rule == NULL) { qDebug() << "no rules added"; return; } checkNeighbours(); killOrCreate(); }
/*********************************************************************** * Map * buildLight ***********************************************************************/ void Map::buildLight() { sf::Vector2i from(0, 0); sf::Vector2i to(MAP_SIZE_X, MAP_SIZE_Y); for (int i = from.x; i < to.x; i++) for (int j = from.y; j < to.y; j++) initIntensity(&tiles[i][j]); for (int i = LIGHT_MAX_LIGHTLEVEL - 1; i >= 0; i--) for (int j = 0; j < lightCounts[i]; j++) { if (lightTiles[i][j]->intensity != i + 1) continue; checkNeighbours(lightTiles[i][j]); } }
/** * Discover the properties (width, height, exact position) of the object * detected at a certain cell of the matrix. * * \param x X coordinate of the object (covered cell). * \param y Y coordinate of the object (covered cell). * * \return The properties of the identified object. */ AreaObject AreaDetector::identifyObject(unsigned int x, unsigned int y) { AreaObject result; Border initialBorder; initialBorder.maxX = 0; initialBorder.minX = width - 1; initialBorder.maxY = 0; initialBorder.minY = height - 1; // Recursively discover all connected cells that belong to the object. Border objectBorder = checkNeighbours(x, y, initialBorder); result.width = objectBorder.maxX - objectBorder.minX; result.height = objectBorder.maxY - objectBorder.minY; result.x = objectBorder.minX + result.width / 2; result.y = objectBorder.minY + result.height / 2; return result; }
/* * TODO: Maybe move toCheck in own function */ vector<PR::Object> PatternRecognitioner::segmentImage(Mat _img, int minObjSize) { vector<PR::Object> segments; // Get grey values cvtColor(_img, _img, CV_BGR2GRAY); // Binarise _img = binarise(_img,128); // Open to remove distortions _img = open(_img); //Prepare object matrix vector<vector<bool>> objectMatrix; for(int i = 0; i < _img.cols; i++){ vector<bool> v; objectMatrix.push_back(v); for(int j = 0; j < _img.rows; j++){ objectMatrix[i].push_back(false); } } vector<PR::Point> objectPoints; vector<PR::Point> toCheck; for(int y = 0; y < _img.rows; y++) { for (int x = 0; x < _img.cols; x++) { uchar inP = _img.at<uchar>(cv::Point(x, y)); if(inP == 255) continue; if(objectMatrix[x][y]) continue; objectMatrix[x][y] = true; objectPoints.clear(); objectPoints.push_back(PR::Point(x,y)); toCheck.clear(); toCheck.push_back(PR::Point(x,y)); for(int a = 0; a < toCheck.size(); a++){ checkNeighbours(_img,objectMatrix,objectPoints,toCheck,a); /*for(int i = -1; i < 2; i++) { for (int j = -1; j < 2; j++) { if (i == 0 && j == 0) continue; if (toCheck[a].y + i < 0 || toCheck[a].x + j < 0) continue; if (toCheck[a].y + i >= _img.rows || toCheck[a].x + j >= _img.cols) continue; uchar inP = _img.at<uchar>(cv::Point(toCheck[a].x + j, toCheck[a].y + i)); if (inP == 255) continue; if (objectMatrix[toCheck[a].x + j][toCheck[a].y + i]) continue; objectMatrix[toCheck[a].x + j][toCheck[a].y + i] = true; objectPoints.push_back(PR::Point(toCheck[a].x+j,toCheck[a].y+i)); toCheck.push_back(PR::Point(toCheck[a].x+j, toCheck[a].y+i)); } }*/ } if(objectPoints.size() < 1) continue; PR::Object obj = PR::Object(objectPoints); cout << "Added Object " << obj.getWidth() << "x" << obj.getHeight() << endl; segments.push_back(obj); } } vector<PR::Object> objects; // Filter out small objects for(int i = 0; i < segments.size(); i++){ if(segments[i].getWidth() < _img.rows/(100/minObjSize) && segments[i].getHeight() < _img.cols/(100/minObjSize)){ continue; } objects.push_back(segments[i]); } cout << "Found " << objects.size() << " objects!" << endl; // Order Objects by Y-position bool swapped = true; while(swapped){ swapped = false; for(int j = 0; j < objects.size()-1; j++){ PR::Object current = objects[j]; if(objects[j].leftStart() > objects[j+1].leftStart()){ objects[j] = objects[j+1]; objects[j+1] = current; swapped = true; } } } segments.clear(); int i; int del = 0; //Combine splitted elements of letters //Caution: So only one-line texts work //TODO: you can do that better for(i = 0; i < objects.size() - 1; i++){ if(objects[i+1].leftStart() < objects[i].leftStart() + objects[i].getWidth() ){ for(int z = 0; z < objects[i+1].points().size(); z++){ objects[i].points().push_back(objects[i+1].points()[z]); } del = i+1; segments.push_back(objects[i]); i++; continue; } segments.push_back(objects[i]); } if(del != objects.size() - 1 || objects.size() == 1) segments.push_back(objects.back()); cout << "Combined to " << segments.size() << " Objects!" << endl; return segments; }
//Update the cell void Cell::update(std::vector<std::vector<Cell>> & read_grid,std::vector<std::vector<Cell>> & write_grid) { checkNeighbours(read_grid, write_grid); }