We are using Google ortools to calculate a route using an image mask in C++.
First we create a two colour mask of an image with some objects we want to avoid in white, we then run the slic segmentation algorithm over the image and discard any segment centres that fall within a white object. Finally we run the remaining centres through ortools to plot the route.
Here is an image with the output plotted on an input mask so you can see what I'm are talking about.

I guess if I were to relate it to a map we would be plotting a route avoiding a number of lakes!
The TSP Code I'm using is based entirely on the circuit board example in ortools, but here's the code I'm using to calculate the route for completeness. In the code below the build_path method is simply a bastardised version of the print output in the sample code.
void GConstraintSolver::compute_path(const std::vector<std::vector<int>>& locations, Path &path, const Image& mask) {
const int num_vehicles = 1;
const operations_research::RoutingIndexManager::NodeIndex depot{0};
operations_research::RoutingIndexManager manager((int)locations.size(), num_vehicles, depot);
operations_research::RoutingModel routing(manager);
const auto distance_matrix = ComputeEuclideanDistanceMatrix(locations);
const int transit_callback_index = routing.RegisterTransitCallback(
[&distance_matrix, &manager](int64_t from_index, int64_t to_index) -> int64_t {
// Convert from routing variable Index to distance matrix NodeIndex.
auto from_node = (size_t)manager.IndexToNode(from_index).value();
auto to_node = (size_t)manager.IndexToNode(to_index).value();
return distance_matrix[from_node][to_node];
});
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index);
operations_research::RoutingSearchParameters searchParameters = operations_research::DefaultRoutingSearchParameters();
searchParameters.set_first_solution_strategy(
operations_research::FirstSolutionStrategy::PATH_CHEAPEST_ARC);
const operations_research::Assignment *solution = routing.SolveWithParameters(searchParameters);
build_path(manager, routing, *solution, locations, path, mask);
}
So here's my question:
Are there any parameters to the algorithm that I can use to guarantee that the calculated route doesn't traverse any of the objects we are trying to avoid? We haven't seen it yet, but I can see that there could easily be a situation whereby the route traverses a white object.
Can we pass areas to avoid to the algorithm? I've tried to look through the documentation but not found anything similar.
We could sample connections along the route that is generated, and if they traverse a white area then plot a route around the edge of the area but if there is anything I can supply as input to the route calculation I'd prefer that.