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

Posted 2 months ago
747 Views
|
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; and fill in the pixel values via nested loops (for, while etc.), so that the values for red are in a[x][y], the values for green are in a[x][y] and the values for blue are in a[x][y].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"]]; Answer
7 Replies
Sort By:
Posted 2 months ago
 You could do this: rgb = {imgr, imgg, imgb} Answer
Posted 2 months ago
 Philip,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.Regards,Neil Answer
Posted 2 months ago
 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.Regards,Neil Answer
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. Answer
Posted 2 months ago
 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:= Head@img Head /@ cols Head /@ imgs Out= Image Out= {List, List, List} Out= {Image, Image, Image} ColorCombine[Image /@ cols, "RGB"] Answer
Posted 2 months ago
 As an additional sollution you can do: ColorCombine[Image /@ {r, g, b}] Answer
Posted 2 months ago
 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. Answer