15,669,910 members
Articles / Programming Languages / C#
Article
Posted 13 May 2009

202K views
32 bookmarked

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

Rate me:
I support a group methods to load the image to double[,]/double[][,]/T[][,], that could help to manipulate the image

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:  `<code>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.

C#
```string fileName = "test.bmp";
float[][][] image;
//here we god the image matrix
// ...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:

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

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:

C#
```string fileName = "test.bmp"; string fileName = "test.bmp";
double[][][] image;
//here we god the image matrix, and here request the double[][][] data type
// ...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.

C#
`T[][][]  LoadFromFile<T>(string fileName) `

and

C#
`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

C#
```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.

C#
```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

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

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.

e.

C#
```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)  `

b

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

Key Ways

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

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).

C#
```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

• 2014 Aug 24, version 2.1. Simplified the entire code, removed all the cloned code, and support BIG image such as 8000*8000 or even larger~
• 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

Written By
Software Developer
China
Satellites' Image Processing
Include:
Imaging Progress Simulation
Multispectral Image Processing
Distributed System

 First Prev Next
 How to treat large image? BOLLILAND CHEN13-Aug-14 19:58 BOLLILAND CHEN 13-Aug-14 19:58
 Re: How to treat large image? mibxue23-Aug-14 8:40 mibxue 23-Aug-14 8:40
 Re: How to treat large image? mibxue23-Aug-14 8:43 mibxue 23-Aug-14 8:43
 Re: How to treat large image? mibxue26-Aug-14 4:54 mibxue 26-Aug-14 4:54
 My vote of 5 Chris Maunder1-Dec-13 21:23 Chris Maunder 1-Dec-13 21:23
 My vote of 4 JiangNanDeXue21-Sep-11 19:04 JiangNanDeXue 21-Sep-11 19:04
 呃...友情踩一下... chaircat26-Oct-09 16:18 chaircat 26-Oct-09 16:18
 good article ! BillWoodruff23-Oct-09 19:49 BillWoodruff 23-Oct-09 19:49
 good job Rozis23-Oct-09 14:31 Rozis 23-Oct-09 14:31
 Re: good job mibxue23-Oct-09 16:56 mibxue 23-Oct-09 16:56
 My vote of 1 Toli Cuturicu6-Oct-09 10:39 Toli Cuturicu 6-Oct-09 10:39
 Re: My vote of 1 mibxue23-Oct-09 1:04 mibxue 23-Oct-09 1:04
 很好，很强大:) qinshaohua6-Aug-09 18:58 qinshaohua 6-Aug-09 18:58
 Large Resuls File Laserson22-May-09 21:16 Laserson 22-May-09 21:16
 Re: Large Resuls File mibxue23-May-09 1:16 mibxue 23-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.
 Re: Large Resuls File Rozis23-Oct-09 14:36 Rozis 23-Oct-09 14:36
 Re: Large Resuls File mibxue23-Oct-09 16:55 mibxue 23-Oct-09 16:55
 Nice stixoffire22-May-09 4:04 stixoffire 22-May-09 4:04
 Last Visit: 31-Dec-99 18:00     Last Update: 7-Jun-23 3:47 Refresh 1