void calculateContour(const cv::Mat& image, std::vector<std::vector<geo::Vec2i> >& contours) { cv::Mat contour_map(image.rows, image.cols, CV_8UC1, cv::Scalar(0)); for(int y = 0; y < image.rows; ++y) { for(int x = 0; x < image.cols; ++x) { unsigned char v = image.at<unsigned char>(y, x); if (v == 0) continue; contours.push_back(std::vector<geo::Vec2i>()); std::vector<geo::Vec2i>& points = contours.back(); std::vector<geo::Vec2i> line_starts; findContours(image, geo::Vec2i(x, y), 0, points, line_starts, contour_map, true); unsigned int num_points = points.size(); if (num_points <= 2) { contours.pop_back(); continue; } // Check for holes within the contour for(unsigned int i = 0; i < line_starts.size(); ++i) { int x2 = line_starts[i].x; int y2 = line_starts[i].y; while(image.at<unsigned char>(y2, x2) == v) ++x2; if (contour_map.at<unsigned char>(y2, x2 - 1) != 0) continue; // found a hole, so find the contours of this hole contours.push_back(std::vector<geo::Vec2i>()); std::vector<geo::Vec2i>& hole_points = contours.back(); findContours(image, geo::Vec2i(x2 - 1, y2 + 1), 1, hole_points, line_starts, contour_map, false); if (hole_points.size() <= 2) { contours.pop_back(); continue; } } // Remove the shape cv::floodFill(image, cv::Point(x, y), 0); } } }
//TODO: //TODO: Use libnoise http://libnoise.sourceforge.net/tutorials/index.html !!! //TODO: void generate() { //set crop height and width if (crop_height < 1) crop_height = tmap_size; if (crop_width < 1) crop_width = tmap_size; //if a crop value is set //set tmap_size to fit the cropped values int max_size = std::max(crop_height, crop_width); int max_size_tmp = max_size - 1; if ((max_size_tmp & (max_size_tmp - 1)) == 0) { //leave set size as highest crop value tmap_size = max_size; } else { //find smallest value such that (value is power of 2) + 1 and value > max_size int t = ceil(log2(max_size)) + 1; tmap_size = (1 << t) + 1; } double finish = 0; //display info if (verbose) { std::cout << "Using " << config_file << std::endl; std::cout << "Staring square diamond" << std::endl; std::cout << "Size: " << crop_width << " x " << crop_height << " original size " << tmap_size << std::endl; std::cout << "Starting seed value " << seed << std::endl; std::cout << "Starting random offset " << random_offset << std::endl; std::cout << "Random offset decrease ratio " << offset_dr << std::endl; } //init map array tmap = new int*[tmap_size]; for (int i = 0; i < tmap_size; ++i) { tmap[i] = new int[tmap_size]; for (int j = 0; j < tmap_size; j++) tmap[i][j] = 0; } // initialize random seed: // use for generating a random map every time // srand ( time(NULL) ); //harcoded for now as produces a nice map for testing srand(12); //fill the array with values square_diamond(); //interpolate voronoi diagram //TODO: add noise to voronoi if (verbose) { std::cout << "Voronoi points " << voronoi_size << std::endl; /* for (int i = 0; i < voronoi_size; ++i) { std::cout << "\t" << voronoi_points[i][0] << "," << voronoi_points[i][1] << std::endl; } */ } voronoi(); erosion(); if (!neg) clear_neg(); // finish = clock() - start; if (verbose) std::cout << "Finished square diamond " << (finish / 1000000) << std::endl; double sqadia = (finish / 1000000); if (normalise) { if (verbose) std::cout << "Normalising with value range " << normalise_min << "-" << normalise_max << std::endl; normalise_map(); } if (output_format == STANDRARD_HEIGHTS) { print_map(fopen(output_file.c_str(), "w")); } else if (output_format == STANDARD_XML) { print_map_xml(fopen(output_file.c_str(), "w")); } if (scale > 0 && crop_height > 256 && crop_width > 256) { // start = clock(); if (verbose) std::cout << "Generating rivers" << std::endl; rivers(); // finish = clock() - start; if (verbose) std::cout << "Done " << (finish / 1000000) << std::endl; double rivers_time = (finish / 1000000); print_rivers(0); // start = clock(); if (verbose) std::cout << "Generating vegetation" << std::endl; vegetation(verbose); // finish = clock() - start; if (verbose) std::cout << "Done " << (finish / 1000000) << std::endl; double veg_time = (finish / 1000000); print_vegetation(0); if (verbose) std::cout << "Generating settlements" << std::endl; settlements(); // finish = clock() - start; if (verbose) std::cout << "Done " << (finish / 1000000) << std::endl; double settlement_time = (finish / 1000000); print_settlements(0); std::cout << crop_height << "\t" << (sqadia + rivers_time + veg_time + settlement_time) << "\t" << sqadia << "\t " << rivers_time << "\t" << veg_time << "\t" << settlement_time << std::endl; } std::cout << "Drawing contours" << std::endl; contour_map(32, 32, verbose); print_contour(0); print_kf(0); }