11
|
7075 Views
|
5 Replies
|
22 Total Likes
View groups...
Share

# Transform an image into a region and compute on it

Posted 10 years ago
 Imagine you have an irregular image like this: How would you solve a differential equation or compute an integral over a region of this shape? First, let's get the boundary: i = Import["http://wolfr.am/ZS7ERg"]; edge = EdgeDetect[ColorNegate[i]]  It is now easy to extract points with Position but how to order them inside Polygon correctly along the boundary? Using FindShortestTour! - a trick I learned from this excellent post: Find polygons corresponding to image borders reg = MeshRegion[#, Polygon[Last[FindShortestTour[#]]]] &@ Position[ImageData[edge], 1]  Now we are ready to have fun: Plot3D[Cos[.0002 ((x - 215)^2 + (y - 215)^2)]^2, {x, y} \[Element] reg, Mesh -> None, Filling -> -3, FillingStyle -> Red, PlotRange -> All, BoxRatios -> {1, 1, 1/3}]  uif = NDSolveValue[{\!$$\*SubsuperscriptBox[\(\[Del]$$, $${x, y}$$, $$2$$]$$u[x, y]$$\) == 0, DirichletCondition[u[x, y] == 1/2 + Sin[.0001 x y] , True]}, u, {x, y} \[Element] reg]; ContourPlot[uif[x, y], {x, y} \[Element] reg, PlotPoints -> 50, ContourStyle -> Opacity[.2], Contours -> 50, ColorFunction -> "Rainbow"] 
5 Replies
Sort By:
Posted 10 years ago
 In the "Neat Examples" section of documentation for ToElementMesh there is another way to do this. Follow the LINK.
Posted 10 years ago
 Not perfect, but darned good! Thanks, Vitaliy!Chris
Posted 10 years ago
 Here's a related challenge: how can I extract the line segments in this image as Line objects? Show[PolyhedronData["Spikey"], Boxed -> False, Lighting -> {White}] 
Posted 10 years ago
 I think this is not perfect but could be improved: i = Rasterize[Show[PolyhedronData["Spikey"], Boxed -> False, Lighting -> {White},ImageSize -> 1500]]; g = i // ColorNegate // Binarize // MorphologicalGraph; Graphics[GraphicsComplex[ Sort[Transpose[{VertexList[g], GraphEmbedding[g]}]][[All, 2]], Line[EdgeList[g] /. UndirectedEdge -> List]]] 
Posted 10 years ago
 This is very cool, thanks for sharing!Here is a variation to transform a (black and white) image to a graphics expression, while taking into account multiple regions.Throughout this post I will use the following test image: image = Import["c:\\Users\\arnoudb.WRI\\paw.png"] This is a helper function which uses MorphologicalComponents to split the image up into a list of images, each containing a single coherent part of the original image: ImageToParts[image_] := Module[{components, max}, components = MorphologicalComponents[Binarize@ColorNegate[image]]; max = Max[Union[Flatten[components]]]; parts = Table[Image[components /. Table[i -> If[i == j, 1, 0], {i, max}]], {j, max}] ] And here is an example of what it does (the third image is a tiny speck in the original): ImageToParts[image] This function uses the helper function to split up the original image and find the 'shortest tour' for the edge points of each sub-image: ImageToGraphics[image_] := Module[ {dims, parts, edges, points, shortest, smooth, prims}, dims = ImageDimensions[image]; parts = ImageToParts[image]; prims = Table[ edges = EdgeDetect[part]; points = {Last[#], 1+Last[dims] - First[#]} & /@ N@Position[ImageData[edges], 1]; shortest = FindShortestTour[points][[2]]; smooth = Mean /@ Partition[points[[shortest]], 8, 1, {-1, 1}]; Polygon[smooth], {part, parts}]; Graphics[ {EdgeForm[Black], Opacity[.5], Red, prims}, ImageSize -> dims, PlotRange -> {{1, First[#]}, {1, Last[#]}} &[dims] ] ] And here is the result, when calling it on the test image: graphics = ImageToGraphics[image] And this shows how the test image and the graphics expression match: Overlay[{image, graphics}]