Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I'm reading the blog on mosaics by Theodore Gray. I tried the first example:

dir = "d:\\mosaic\\pool\\*.jpg";  
master = "d:\\mosaic\\master.jpg";  
imagePool = Map[With[{i = Import[#]}, {i, Mean[Flatten[N[i[[1, 1]]], 1]]}] &, 
  FileNames[dir]];
closeMatch[c_] := RandomChoice[Take[SortBy[imagePool, Norm[c - #[[2]]] &], 20]][[1]];
Grid[Reverse[Map[closeMatch, Import[master][[1, 1]], {2}]], Spacings -> {0, 0}]

but it gives me errors:

Part::partd: Part specification (<an image>)[1,1] is longer than depth of object.

I'm using Mathematica version 9. A comment on the blog says the code has to be modified for version 8, so I guess the changes are also required for version 9. How can I make this code work?

share|improve this question
3  
Have you tried debugging this yourself? It's a very good leaning exercise to try. For a start, you have two lines of code that actually does something (other than definitions). Have you looked at which one causes the error? If you found that out already, have you tried to "peel back" a few layers of functions to find out which exact part of the offending line causes the problem? –  Szabolcs Feb 2 at 19:07
    
@Szabolcs: I'm a beginner in Mathematica, and the code isn't all clear to me. But I'm confused by image[[1,1]], because I thought the first element of the image object is the pixel map, so the [[1,1]] doesn't seem to make sense. Correct? –  Geert Goeteyn Feb 2 at 19:18
    
I updated the answer with a few more changes. –  Szabolcs Feb 2 at 19:28
1  
Exact same question on Stack Overflow. –  rm -rf Feb 2 at 20:21
1  
@rm-rf yeah, but do you really trust the guy who posted the accepted answer? –  bobthechemist Feb 2 at 21:09
add comment

1 Answer 1

The problem is that in version 9 Image became an atomic object, so it's not possible to extract the image data using Part any more. Here's a mention of this change.

You need to change every occurrence of someImage[[1,1]] to ImageData[someImage]


This takes the small images from the example data. It filters only those that have a square aspect ratio.

images = Select[ExampleData /@ ExampleData["TestImage"], Equal @@ ImageDimensions[#] &];

Now let us resize all of them to 50 pixels wide (so they're the same size) and set their magnification to 1. The Magnification option only affects how they're displayed on screen, but doesn't change the image data. This is useful to have to prevent automatic sizing within Grid later, and potential alignment problems when the grid doesn't fit in the window.

images = Image[ImageResize[#, 50], Magnification -> 1] & /@ images

These images won't give a very pretty output unfortunately, but I wanted to post self-contained code that doesn't rely on external image files people might not have.

I took the master image from the example data too. Note that here master holds an image, not a file name, so the rest of the code needs to be changed accordingly. I resized master to 10 by 10 so the resulting grid will also consist of 10 by 10 small images.

master = ImageResize[ExampleData[{"TestImage", "Lena"}], 10]

The rest is mostly identical, except for the change I mention and for using master as an image instead of a file name.

imagePool = 
  Function[i, {i, Mean@Flatten[N@ImageData[i], 1]}] /@ images;

closeMatch[c_] := 
  First@RandomChoice@Take[SortBy[imagePool, Norm[ c - #[[2]] ] &], 20];

Grid[Reverse@Map[closeMatch, ImageData[master], {2}],
  Spacings -> {0, 0}]
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.