Message Boards Message Boards


Combine three 2D matrices into a single array via nested lists?

Posted 2 months ago
7 Replies
0 Total Likes

Dear All,

I hope you can help me with a problem that is likely trivial to solve for someone who understands Mathematica. I only have a bit of background in C and Python so I am struggling a bit with the following issue.

I have three separate 2D matrices corresponding to pixel values for red, green and blue color channels (that is, a separate matrix for every channel).

Now I want to combine these three matrices into a single array. In C, I would probably construct an array similar to int a[319][239][2]; and fill in the pixel values via nested loops (for, while etc.), so that the values for red are in a[x][y][0], the values for green are in a[x][y][1] and the values for blue are in a[x][y][2].

I feel like in Mathematica, we try to avoid such loops whenever possible.

What would you guys recommend? This is how I start.

img = ImageResize[Import["IMG_1616.jpeg"], 480]
imgr = ImageData[ColorSeparate[img, "R"]];
imgg = ImageData[ColorSeparate[img, "G"]];
imgb = ImageData[ColorSeparate[img, "B"]];
7 Replies

You could do this: rgb = {imgr, imgg, imgb}


To reconstruct an image, you need to use the Image command which expects each pixel as a list of RGB colors. For this reason, you will need to transpose the list. You can get back your original image with

Image[Transpose[{imgr, imgg, imgb}, {3, 1, 2}]]

Note that in the Image command you may need to set the ImageType to get the exact type you want.



BTW - John is also correct about storing your data in a matrix, you just need to decide what form it should be in. Since C is Row-major format, I think it likely will be consistent with Mathematica's Image[] format. Also, I assumed you would want to reconstruct the image eventually.



Posted 2 months ago

Thanks for your inputs and the tip with reconstructing the image. This is indeed what I want to do after applying some transformations to the matrices holding the image data.

ColorCombine should do the trick. Mathematica works with lists and to loop over list one uses the Map operator, which in short notation is /@. Also data in an array is something different that data stored as and Image. Some functions are convenient but only work on Images and not Lists.

cols = {r, g, b} = ImageData /@ ColorSeparate[img];
imgs = {ri, gi, bi} = Image /@ cols

In[11]:= Head@img
Head /@ cols
Head /@ imgs

Out[11]= Image

Out[12]= {List, List, List}

Out[13]= {Image, Image, Image}

ColorCombine[Image /@ cols, "RGB"]

As an additional sollution you can do:

ColorCombine[Image /@ {r, g, b}]

I want to combine these three matrices into a single array, you have only to write:

list={imgr, imgg, imgb}

to "access them" you then can write a function (rough example)

f[r_,g_,b_]:={list[[1,r]],list[[2,b]],list[[3,b]]} (*-> {r,g,b}*)
f[x_,y_]:={list[[1,(y width+x)]],list[[2,(y width+x)]],list[[3,(y width+x)]]} (*-> {r,g,b}*)

So if your goal is to access them with new notation you don't need to actually "need to re-arrange the physical array" (doing so is optional). Mathematica discourages use of for loops (read the book, 5 programming styles). But without a target format - commenting on "a good way to do it" is subjective.

What format depends on how you use the data (what the target image size is, if the image is in vga, supervga, ega, or a Mathematica rgb format, etc). idk if you will use the result with Import or if your end goal is "any x,y format yielding {r,g,b}"? If you will display an image after working with the data - then knowing the target format is essential. jpeg is awfully complex and there are more rgb image formats than there are songs in a top 100's song list.

Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
or Discard

Group Abstract Group Abstract