I have taken several gps readings while driving around town.
gpsPositions=GeoPosition[{{33.657, -84.5197}, {33.6687, -84.4977},
{33.692, -84.4907}, {33.7057, -84.4287}, {33.7431, -84.4027}, {33.7285,
-84.3493}}]
map = GeoGraphics[GeoMarker[gpsPositions],
GeoRange ->Entity["City",{"Atlanta","Georgia","UnitedStates"}],ImageSize->Large]
Were are able to extract the main roads by the following functions:
bgnd = GeoGraphics[ GeoRange ->Entity["City",{"Atlanta","Georgia","UnitedStates"}],ImageSize->Large];
roads = DeleteSmallComponents@
Thinning@ImageAdd[
Dilation[#, DiskMatrix[3]] & /@
DominantColors[bgnd, 7, {"CoverageImage", "Color"}][[5 ;; 6, 1]]];
ImageCompose[map, ColorNegate@SetAlphaChannel[roads, roads]]
Road Extraction worked fine. Now convert the gpsPositions and map them to the road image.
range = Abs[#1 - #2] & @@@ map[[8, 2]]
origin = #1 & @@@ map[[8, 2]];
max = Reverse@ImageDimensions[roads];
waypoints = gpsPositions[[1]];
points = Reverse@(Round[(max (#)/range), 1]) & /@ ((# - origin) & /@
waypoints);
Show[ColorNegate@roads,
Graphics[{Red, PointSize[Large], Point[points]}]]
I would like to be able to segment the lines between the dots. Then, set up an interpolation function between each dot so we can simulate the placement of the vehicle at any point of the road as needed.
Any thoughts on how this can be achieved?
Answer
I'm not 100% sure what you want: "segmentation" has a well-defined meaning in image processing, and I think that's not what you want. Also, I couldn't reproduce your results (I think DominantColors
isn't guaranteed to give the same order or even the same results every time it's run). So this may or may not help...
First, this seems more reproducible than DominantColors
:
roadColors = List @@@ {Yellow, Blue};
colorDist =
Total[(# -
Transpose[
ImageData[bgnd][[All, All, ;; 3]], {2, 3, 1}])^2] & /@
roadColors;
roads = Thinning[
MorphologicalBinarize[
Closing[Image[1 - MapThread[Min, colorDist, 2]],
DiskMatrix[3]], {0.43, 0.8}]]
Next, I convert the white pixel locations to a graph:
whitePixels = PixelValuePositions[roads, 1];
nearestFn = Nearest[whitePixels -> Automatic];
edges = MapThread[
Function[{point, potentialNeighbors},
point <-> # & /@
Select[potentialNeighbors,
0 < EuclideanDistance[whitePixels[[#]], whitePixels[[point]]] <
2 &]],
{Range[Length[whitePixels]], nearestFn[#, 10] & /@ whitePixels}];
g = Graph[DeleteDuplicates@Flatten[edges]];
Now, if I choose point locations in the image:
pts = {{133, 97}, {464, 461}};
LocatorPane[Dynamic[pts], ColorNegate@roads]
I can use nearestFn
to find the nearest road pixel, and FindShortestPath
to find the shortest path between two points:
path = FindShortestPath[g, nearestFn[pts[[1]]][[1]],
nearestFn[pts[[2]]][[1]]];
Show[Image@bgnd,
Graphics[{Red, Line[whitePixels[[path]]], PointSize[Large],
Point[whitePixels[[path[[;; ;; 10]]]]]}]]
We can even make a little Indiana Jones-style animation:
Animate[Show[Image@bgnd,
Graphics[{Red, Thick, Line[whitePixels[[path[[;; i ;; 2]]]]]}]], {i,
1, Length[path], 1}]
(unfortunately, I don't think I can upload videos to Mathematica.SE)
Comments
Post a Comment