Click here to Skip to main content
Click here to Skip to main content

Convert the image to float[][][]/float[][,]/T[][][]/T[][,] data , fast and safety

By , 18 May 2012
 

This provide a way to convert the image to float[][][]/T[][][] data fast and safe.

Background 

In the image process field, there is an obstacle between image data and algorithms. In the lab, the mathematician and algorithm engineer are good at matrix processing. For those scientist, the image is just a matrix. So they need not to understand the Bitmap Class. Further more, the mathematical tools such as MathNet.Numerics is design to deal with double[] or T[]data type. 

For example, the GDI+ could enlarge a image easily, but if you want to use some advance interpolation method to calculate the interpolated pixel value, the GDI+ seems helpless.

So, here I support this library to convert the Image to float[][][]/float[][,]/T[][][]/T[][,] type. And the algorithm engineers could focus on the algorithm, not "how to load the image correctly". 

Meanwhile, sometimes, I found some low efficiency code in our lab, such as GetPixel() and SetPixel(). So I think I need to provide a solution for connect Matrix and Image. 

Overview 

This class library do two things: 1. Convert image to Array. 2. Convert Array to Image.

Generally, the image could be classified in two type: a) monochromatic image; b) chromatic image. 

A  monochromatic image could be defined with a 2D matrix: float[Width][Height]/float[Width,Height] or T[Width][Height]/T[Width,Height].

A  chromatic image could be defined with a 3D matrix:  float[R/G/B][Width][Height]/[R/G/B]float[Width,Height] or T[R/G/B][Width][Height]/T[R/G/B][Width,Height].  

Here I support those 4 data type. 

Using the code 

After building the single cs file (DoubleToImageMethod.cs), you will get a DLL file. Add a reference for this DLL. 

string fileName = "test.bmp";
float[][][] image;
//here we god the image matrix
image= DoubleToImageMethods.LoadFromFile(fileName);
// ...Do something with this matrix, for example, pattern recognize 

 
Now you've three bands from test.bmp.  

image[0] is the red band, image[1] is the green band, image[2] is the blue band. Maybe you could do something with the image. And after you have finished your job, you should save the data: 

<pre lang="cs">// then save the matrix as a Bmp image file
DoubleToImageMethods.SaveToBmpLinear(image, "test.bmp");  

Then you got your result. 

 

Sometimes, you need other Data Type, eg. you need a more accurate value than float, such as double. You can use this way to load the image: 

string fileName = "test.bmp"; string fileName = "test.bmp";
double[][][] image;
//here we god the image matrix, and here request the double[][][] data type
image= DoubleToImageMethods.LoadFromFile<double>(fileName);
// ...Do something with this matrix  

Methods Details  

There are three methods: 

1. Load the image matrix from the file 

the v2.0 unified the load method, the way to load image are show blow. It load the image file as T[][][]/T[][,] matrix. 

a.

T[][][]  LoadFromFile<T>(string fileName) 

and 

T[][,] LoadFromFile2DArray<T>(string fileName) 

I defined the PixelFormat.Format24bppRgb, so I always get the RGB band of the image, even if the image file is 8bit gray scale image. If you load the monochromatic image file, the 3 bands has the same value.

2. Save the T[][] /T[,]/ T[][,] /T[][][]data to the image file

a

void SaveToBmpLinear<T>(T[][,] image, string fileName) 
void SaveToBmpLinear<T>(T[][][] image, string fileName)   

save the T[][,]/T[][][] image to RGB chrome 24bit bmp type image file. Before saving, it will stretch the data to 0 -255. It could promote the image's contrast.

b.

void SaveToBmpLinear<T>(T[,] image, string fileName) 
void SaveToBmpLinear<T>(T[][] image, string fileName) 

save the T[,]/T[][] image to RGB chrome 24bit bmp type image file. the red, green, blue value are the same.So, it looks like a 8bit monochrome image, but it is a real 24bit bmp file. Before saving, it will stretch the data to 0 -255. It could promote the image's contrast.

c

SaveToBmpNoLinear<T>(T[,] image, string fileName) 
SaveToBmpNoLinear<T>(T[][] image, string fileName)   

save the T[][]/T[,] image to RGB chrome 24bit bmp type image file. the red, green, blue value are the same.So, it looks like a 8bit monochrome image, but it is a real 24bit bmp file. But it won't stretch the color range.

d

SaveToBmpNoLinear<T>(T[][,] image, string fileName) 
SaveToBmpNoLinear<T>(T[][][] image, string fileName)  

save the T[][,]/T[][][] image to RGB chrome 24bit bmp type image file.

e.

Image ToImageLinear<T>(T[,] image)
Image ToImageLinear<T>(T[][] image)  

save the T[,]/T[][] to System.Drawing.Image type, with color stretch, 24bit RGB image, and seems like 8bit GrayScale Image; 

f

Image ToImageLinear<T>(T[][,] image)
Image ToImageLinear<T>(T[][][] image)   

save the T[][,]/T[][][] to System.Drawing.Image type

3.Convert Image to the T[][,]/T[][][] 

a

T[][][] LoadFromImage<T>(Image img)  

load Image data to T[R/G/B][Width][Height]. 

b

T[][,] LoadFromFile2DArray<T>(Image img) 

load Image data to T[R/G/B][Width,Height].  

Key Ways

I found that Marshal.Copy() is a kind class to solve this problem. 

ImageToDouble/keyWays.jpg

When I load or save data with bmp or jpg file, I need the BitmapData, and Marshal.Copy(), it support me a fast and safe way to load or save data.

Code Efficiency 

I use the Parallel.For() to fill the matrix, it obviously promote the program efficiency when load big image file(large than 5000*3000 pixels).

 Parallel.For(0, imgHeight, (int i) =>
            {
                for (int j = 0; j < imgExtentWidth; j += 3)
                {
                    if (j < imgWidth * 3)
                    {
                        linlizeImg[i * imgExtentWidth + j] = arrayData[2][j / 3][i];
                        linlizeImg[i * imgExtentWidth + j + 1] = arrayData[1][j / 3][i];
                        linlizeImg[i * imgExtentWidth + j + 2] = arrayData[0][j / 3][i];
                    }
                    else
                    {
                        linlizeImg[i * imgExtentWidth + j] = linlizeImg[i * imgExtentWidth + j - 1];
                    }
                }
            });  

History  

  • 2012 Apr 13, Update to .net 4.0, re-factor the  entire project, use parallel features in net40  
  • 2009 Oct 23, Update the description on the web.  
  • 2009 May 23, Updated, provide Template ways to convert the ImageData. Revised some bugs in rgbImage methods
  • 2009 May 10, Updated, revised some bugs in RGB image
  • 2009 March 11, Updated, revised 2 bugs in RGB image.. sorry.

I will try my best to debug and make it faster than before

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

mibxue
Software Developer Beijing Institute of Technology
China China
Member
Satellites' Image Processing
Content :
image restore
multispectrum image processing
noise reduction
distribute image processing system
target indetify

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 4memberJiangNanDeXue21 Sep '11 - 19:04 
可否交流一下,ganer_7@163.com
General呃...友情踩一下...memberchaircat26 Oct '09 - 16:18 
总算发现一篇不是全E的东西了... Laugh | :laugh:
Generalgood article !memberBillWoodruff23 Oct '09 - 19:49 
Hi Mibxue,
 
I've looked at the source code you provided; it's very readable, with clear English comments.
 
Please do know that the great majority of CodeProject users are happy and delighted to see contributions from all over the world by people for whom English is not their first language !
 
Unfortunately, a small number of narrow-minded people will make negative comments based on what they see as less-than-perfect English.
 
Such ignorant people deserve to be ignored Smile | :)
 
I, and other people here, will be happy to work with you on making your English a little more readable.
 
But, in the case of this article, I think you communicate the technical points clearly.
 
best, Bill
 
"Many : not conversant with mathematical studies, imagine that because it [the Analytical Engine] is to give results in numerical notation, its processes must consequently be arithmetical, numerical, rather than algebraical and analytical. This is an error. The engine can arrange and combine numerical quantities as if they were letters or any other general symbols; and it fact it might bring out its results in algebraical notation, were provisions made accordingly." Ada, Countess Lovelace, 1844

Generalgood jobmemberRozis23 Oct '09 - 14:31 
I think your english should be improved but your work is ok. I vote for 5 if you promise me to work on your english Smile | :)
 
Rozis
GeneralRe: good jobmembermibxue23 Oct '09 - 16:56 
I'll try to improve my english, you know, I'm not the native speaker, maybe with your help, i could do it better~
GeneralMy vote of 1memberToli Cuturicu6 Oct '09 - 10:39 
It is unreadable with lots of unknown characters
GeneralRe: My vote of 1membermibxue23 Oct '09 - 1:04 
I use two languages, chinese is my native language~ and i publish the details in both chinese and englsih, maybe i will re-edit it~
General很好,很强大:)memberqinshaohua6 Aug '09 - 18:58 
很好,很强大Smile | :)
GeneralLarge Resuls FilememberLaserson22 May '09 - 21:16 
There was one more article about converting images to double[] on CP, but resulted file was very large (about 20 times larger than image). What about your article? And what about base64? Can you convert any image to base64-encoded file and compare results with your article's code result?
GeneralRe: Large Resuls Filemembermibxue23 May '09 - 1:16 
Bitmap describe exery pixel use 3 * 1Byte
the range of byte is 0-255, if you use 255/2, the result is 128, not 127.5, so, we lose the accuracy.
 
But if you use double type to describe pixel, it will cost 3* 8Byte , because it is double type is 64bit. the vale could keep accuracy duaring the calculation.
 
as a result, it is 8 times larger than the Bitmap. (Sometimes you need Windows X64 to run the application because it cost much more memory, my workstation has 16GB RAM...)
 
Until now, my code did NOT support base 64. I'm sorry.
GeneralRe: Large Resuls FilememberRozis23 Oct '09 - 14:36 
Base64 packs bits into 6 bits - so 8 bits will cost 12 bits in base64, and 24 bits will cost 32 bits. On average your file will be 25% bigger.
 
Rozis
GeneralRe: Large Resuls Filemembermibxue23 Oct '09 - 16:55 
Excuse, could you sned me a base64 image and its jpg version? maybe I can develop a method to support the base64 file~
GeneralNicememberstixoffire22 May '09 - 4:04 
I will try this in a project I have - to see if it is any faster than my conversion.
Since I am not an expert maybe it will be. I have thousands of images that I must process in short time frame.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 18 May 2012
Article Copyright 2009 by mibxue
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid