# Transform an image into a region and compute on it

Posted 9 years ago
6649 Views
|
5 Replies
|
22 Total Likes
|
 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 9 years ago
 In the "Neat Examples" section of documentation for ToElementMesh there is another way to do this. Follow the LINK.
Posted 9 years ago
 Not perfect, but darned good! Thanks, Vitaliy!Chris
Posted 9 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 9 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 9 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}]