I have a float array representing a grayscale picture that I want to convert to an image in C#. How do I go about doing so?
Bitmap newBitmap = new Bitmap(original.Width, original.Height);
for (int j = 0; j < original.Height; j++)
{
for (int i = 0; i < original.Width; i++)
{
Color newColor = Color.FromArgb((int)grayScale[i + j * original.Width], (int)grayScale[i + j * original.Width], (int)grayScale[i + j * original.Width]);
newBitmap.SetPixel(i, j, newColor);
}
}
Image img = (Image)newBitmap;
Microsoft forum for converting
Example in codeproject
Related
usage
public UserControlTester()
{
InitializeComponent();
GetSetPixelsRandom();
}
code
private void GetSetPixelsRandom()
{
Bitmap img = new Bitmap(#"d:\\downloaded images\\test.gif");
for (int i = 0; i < img.Width; i++)
{
for (int j = 0; j < img.Height; j++)
{
Color pixel = img.GetPixel(i, j);
pixels.Add(pixel);
}
}
Bitmap img1 = new Bitmap(512,512);
for (int i = 0; i < img1.Width; i++)
{
for (int j = 0; j < img1.Height; j++)
{
for (int c = 0; c < pixels.Count; c++)
{
img1.SetPixel(i, j, pixels[c]);
}
}
}
img1.Save(#"d:\\downloaded images\\test3.gif");
}
Not sure if this is the right way. the inner loop with the variable c take a lot of time because there are more then 290,000 pixels.
Assuming you want to resize the image, this can be done easily. The Bitmap constructor has rescaling build in:
Bitmap img = new Bitmap(#"d:\\downloaded images\\test.gif");
Bitmap img1 = new Bitmap(img, new Size(512, 512));
img1.Save(#"d:\\downloaded images\\test3.gif");
If you do not want to resize but indeed take random pixels take a look at what at MickyD mentioned.
Note that in your provided example every pixel in the new image is effectively set to the last pixel in the pixels list because you loop over every pixel in pixels for every pixel in the new image.
How to get the red component from an image, in C# (windows forms).
I want to get the Red component in a new matrix.
I tried something like this with a bmp:
byte[,] MatrixImage= new byte[256, 256]; // is my matrix where every pixel of my image is stored
byte[,] MatrixRed= new byte[256, 256];
Bitmap bmp = new Bitmap(256, 256);
for (int i = 0; i < 256; i++)
{
for (int j = 0; j < 256; j++)
{
var red = Color.FromArgb(MatrixImage[i, j], 0, 0);
bmp.SetPixel(i, j, red);
var getRedPixel = bmp.GetPixel(i, j);
MatrixRed[i, j] = (byte)getRedPixel;
}
}
GetPixel Returns a Color object so you're probably looking for this :
MatrixRed[i, j] = (byte)(getRedPixel.R);
I have two images(original and noisy). I'm calculating PSNR. I kinda did it for color RGB images, but i don't know how to do it with grayscale. As i read, MSE calculation is different. For RGB i'm doing it like you can see in following code (I'm using Visual C#):
for (int i = 0; i < bmp1.Width; i++)
{
for (int j = 0; j < bmp1.Height; j++)
{
mseR += Math.Pow(bmp1.GetPixel(i, j).R - bmp2.GetPixel(i, j).R, 2);
mseG += Math.Pow(bmp1.GetPixel(i, j).G - bmp2.GetPixel(i, j).G, 2);
mseB += Math.Pow(bmp1.GetPixel(i, j).B - bmp2.GetPixel(i, j).B, 2);
}
}
mse = (mseR + mseG + mseB) / ((bmp1.Width * bmp1.Height) * 3);
Here I am manipulating with R,G,B of pixels.But i don't know what should i take in case of grayscale images. Can I use RGB aswell, because it actually gives some results, or i should take something else?
To make grayscale you can make the picture out of averages (no need to vary your implementation). I'm assuming your images are bmp1 = grayImage and bmp2 = noisy image.
for (int i = 0; i < bmp1.Width; i++)
{
for (int j = 0; j < bmp1.Height; j++)
{
// As a grayscale image has rthe same color on all RGB just pick one
int gray1 = bmp1.GetPixel(i, j).R;
int gray2 = bmp2.GetPixel(i, j).R;
double sum = Math.Pow(gray1 - gray2, 2)
mseGray += sum;
}
}
mse = (mseGray) / ((bmp1.Width * bmp1.Height) * 3);
Also getting pixels one at a time is a slow process look into using the indexes, and a optimization in the loop. It should give about a tenfold in performance.
You need to make the bitmap into an indexable img, I'm assuming its BitmapSource for this example. the interesting part is the loop and the index building and not the precode, the precode is just to make the image indexable.
var height = bmp1.Height;
var width = bmp1.Width;
var pixelBytes1 = new byte[height * width * 4];
var pixelBytes2 = new byte[height * width * 4];
bmp1.CopyPixels(pixelBytes1, stride, 0);
bmp2.CopyPixels(pixelBytes2, stride, 0);
for (int x = 0; x < width; x++)
{
int woff = x * height;
for (int y = 0; y < height; y++)
{(R*0.3 + G*0.59+ B*0.11)
int index = woff + y;
int gray1 = bmp1[index];
int gray2 = bmp2[index];
double sum = Math.Pow(gray1 - gray2, 2)
mseGray += sum;
}
}
mse = (mseGray) / ((bmp1.Width * bmp1.Height) * 3);
EDIT:
http://www.mathworks.com/matlabcentral/answers/49906-how-to-calculate-psnr-of-compressed-images-and-how-to-compare-psnr-of-images-compressed-by-two-diff
I'm having an issue with your implementation of PSNR though im thinking its not per definition
here is an example from java (very similar to C#)
http://www.cyut.edu.tw/~yltang/program/Psnr.java
I have a matrix (2D) of an image in EMGU cv,how can I fill the rest of the matrix with zeros but keep a certain area(rectangle) with the original data?
Method 1
One way to achieve what your after is to access the Data of the Matrix directly and set the values to '0' the following code will set the lower quarter of 'My_Matrix' to 0 where all other values will remain 20.
Matrix<double> My_Matrix_Image = new Matrix<double>(8,10);
My_Matrix_Image.SetValue(20); //set all values of Matrix to 20
for(int i = 4; i< My_Matrix_Image.Height; i++)
{
for (int j = 5; j < My_Matrix_Image.Width; j++)
{
My_Matrix_Image.Data[i,j] = 0;
}
}
To achieve what you wanted from your comment you must still take the same approach My_Matrix_Image would contain your image data values from 0-255 I will give solutions for both greyscale and colour images. I will keep the first 30 rows of the image and set the rest to zero the image will be 100x100 pixels in size. Change j = 30 to alter the amount of rows.
First Colour Image Matrix there will be 3 channels Red, Green and Blue:
for(int i = 0; i< My_Matrix_Image.Height; i++)
{
for (int j = 30; j < My_Matrix_Image.Width; j++)
{
My_Matrix_Image.Data[i,j,0] = 0; //RED
My_Matrix_Image.Data[i,j,1] = 0; //GREEN
My_Matrix_Image.Data[i,j,2] = 0; //BLUE
}
}
Greyscale Image Matrices are easier as there will be 1 channel:
for(int i = 0; i< My_Matrix_Image.Height; i++)
{
for (int j = 30; j < My_Matrix_Image.Width; j++)
{
My_Matrix_Image.Data[i,j,0] = 0;
}
}
Now lets assume you want to keep the Middle 40 Rows you will have to add an additional loop remember this is the only way with a Matrix I have only provided the colour image example as you can see it starts getting a little messy and Method 2 may be better:
for(int i = 0; i< My_Matrix_Image.Height; i++)
{
//LOOP 1 SET THE FRONT ROWS
for (int j = 0; j<40; j++)
{
My_Matrix_Image.Data[i,j,0] = 0; //RED
My_Matrix_Image.Data[i,j,1] = 0; //GREEN
My_Matrix_Image.Data[i,j,2] = 0; //BLUE
}
// LOOP 2 SET THE BACK ROWS
for (int j = 60; j < My_Matrix_Image.Width; j++)
{
My_Matrix_Image.Data[i,j,0] = 0; //RED
My_Matrix_Image.Data[i,j,1] = 0; //GREEN
My_Matrix_Image.Data[i,j,2] = 0; //BLUE
}
}
Method 2
Now lets assume you do want to keep a rectangle of data. Creating 6 Loops is complex and inefficient so here is what you could do.
//Make a Blank Copy of your Image this will be automatically full of zeros
Matrix<double> My_Image_Copy = My_Image_Matrix.CopyBlank();
//Now copy the data you want to keep from your original image into you blank copy
for(int i = 40; i< 60; i++)
{
for (int j = 40; j < 60; j++)
{
My_Image_Copy.Data[i,j,0] = My_Matrix_Image.Data[i,j,0]; //RED
My_Image_Copy.Data[i,j,1] = My_Matrix_Image.Data[i,j,1]; //GREEN
My_Image_Copy.Data[i,j,2] = My_Matrix_Image.Data[i,j,2]; //BLUE
}
}
The above code will copy the centre 20x20 pixels from an image you can obviously change this to copy whole rows by using for(int i = 0; i< My_Matrix_Image.Height; i++)
Much better I'm sure you will agree.
Alternative
Now while you are using a Matrix to store you data using a Image construct makes coding a little simpler. While this may not be relevant to you it may be to others.
If you use Image or alternative to store your Image data then this can be achieved by:
Image<Gray, Byte> My_Image = new Image<Gray, byte>(openfile.FileName);
Image<Gray, Byte> My_Image_Copy = My_Image.CopyBlank();
Rectangle Store_ROI = my_image.ROI; //Only need one as both images same size
My_Image.ROI = new Rectangle(50, 50, 100, 100);
My_Image_Copy.ROI = new Rectangle(50, 50, 100, 100);
My_Image_Copy = My_Image.Copy(); //This will only copy the Region Of Interest
//Reset the Regions Of Interest so you will now operate on the whole image
My_Image.ROI = Store_ROI;
My_Image_Copy.ROI = Store_ROI;
Now this the same as Method 2 but you don't need to sort write out loops where errors can occur.
Hope this correction answers your question,
Cheers
Chris
// Rectangle's parameters
static int x = 3;
static int y = 3;
static int width = 2;
static int height = 2;
Rectangle specificArea = new Rectangle(x, y, width, height);
// Your image matrix; 20x20 just a sample
Matrix<int> imageMatrix = new Matrix<int>(20, 20);
public Matrix<int> cropMatrix()
{
// Crop a specific area from image matrix
Matrix<int> specificMatrix = imageMatrix.GetSubRect(specificArea);
// Matrix with full of zeros and same size with imageMatrix
Matrix<int> croppedMatrix = imageMatrix.CopyBlank();
for (int i = x; i < x+width; i++)
{
for (int j = y; j < y+height; j++)
{
// Set croppedMatrix with saved values
croppedMatrix[i, j] = specificMatrix[i-x, j-y];
}
}
return croppedMatrix;
}
I'm looking for sample .NET code (System.Drawing.Image) that does the following:
Load a given image file.
Generate a new single image that repeats the orginal image for x times horizontally.
This creates a new bitmap and draws the source bitmap to it numTimes times.
Bitmap b = Bitmap.FromFile(sourceFilename);
Bitmap output = new Bitmap(b.Width * numTimes, b.Height);
Graphics g = Graphics.FromImage(output);
for (int i = 0; i < numTimes; i++) {
g.DrawImage(b, i * b.Width, 0);
}
// do whatever with the image, here we'll output it
output.Save(outputFilename);
// make sure to clean up too
g.Dispose();
b.Dispose();
output.Dispose();
Here a sample copying each source image pixel on destination bitmap
static void Main(string[] args)
{
ushort nbCopies = 2;
Bitmap srcBitmap = (Bitmap)Image.FromFile(#"C:\Users\Public\Pictures\Sample Pictures\Koala.jpg");
Bitmap dstBitmap = new Bitmap(srcBitmap.Width * nbCopies, srcBitmap.Height, srcBitmap.PixelFormat);
//Slow method
for (int curCopy = 0; curCopy < nbCopies; curCopy++)
{
for (int x = 0; x < srcBitmap.Width; x++)
{
for (int y = 0; y < srcBitmap.Height; y++)
{
Color c = srcBitmap.GetPixel(x, y);
dstBitmap.SetPixel(x + (curCopy * srcBitmap.Width), y, c);
}
}
}
//OR
//Fast method using unsafe code
BitmapData srcBd = srcBitmap.LockBits(new Rectangle(Point.Empty, srcBitmap.Size), ImageLockMode.ReadOnly, srcBitmap.PixelFormat);
BitmapData dstBd = dstBitmap.LockBits(new Rectangle(Point.Empty, dstBitmap.Size), ImageLockMode.WriteOnly, dstBitmap.PixelFormat);
unsafe
{
for (int curCopy = 0; curCopy < nbCopies; curCopy++)
{
for (int y = 0; y < srcBitmap.Height; y++)
{
byte* srcRow = (byte*)srcBd.Scan0 + (y * srcBd.Stride);
byte* dstRow = (byte*)dstBd.Scan0 + (y * dstBd.Stride) + (curCopy * srcBd.Stride);
for (int x = 0; x < srcBitmap.Width; x++)
{
//Copy each composant value (typically RGB)
for (int comp = 0; comp < (srcBd.Stride / srcBd.Width); comp++)
{
dstRow[x * 3 + comp] = srcRow[x * 3 + comp];
}
}
}
}
}
dstBitmap.UnlockBits(dstBd);
srcBitmap.UnlockBits(srcBd);
dstBitmap.Save(#"C:\Users\Public\Pictures\Sample Pictures\Koala_multiple.jpg");
dstBitmap.Dispose();
srcBitmap.Dispose();
}