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;
image= DoubleToImageMethods.LoadFromFile(fileName);
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">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;
image= DoubleToImageMethods.LoadFromFile<double>(fileName);
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.
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
- 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