Get information from a graph image - c#

In this image black colour graph is in the white background. I want to get the pixel length between the two peak waves in the graph and the average amplitude (height of the peak) of the peak waves.
I'm stuck with the logic to implement this code.can anyone help me to implement this. I'm using C#
public void black(Bitmap bmp)
{
Color col;
for (int i = 0; i < bmp.Height; i++)
{
for (int j = 0; j < bmp.Width; j++)
{
col = bmp.GetPixel(j, i);
if (col.R == 0) //check whether black pixel
{
y = i; //assign black pixel x,y positions to a variable
x = j;
}
}
}
}
my supervisor told i have to use a 2D array to store increments and decrements(start point pixel value and end point pixel value of each increment and decrement) of the line to get these values.But i haven't sufficient coding skills to apply that logic to this code.

Bitmap img = new Bitmap(pictureBox1.Image);
int width = img.Width;
int height = img.Height;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
Color pixelColor = img.GetPixel(x, y);
if (pixelColor.R == 0 && pixelColor.G == 0 && pixelColor.B == 0)
//listBox1.Items.Add(String.Format("x:{0} y:{1}", x, y));
textBox1.Text = (String.Format("x:{0} y:{1}", x, y));
}
}

Related

Calculate X & Y of coordinate from byte array with known width & height

My input is a single byte array. I know it's width and height and the length of the entire byte array. How do I iterate through each x & y coordinate? I can figure out the current x coordinate with the mod operation but I'm drawing a blank on logic for determining my y position.
for (int i = 0; i <= sender.Count(); i++)
{
// figure out x & y
int x = i % width;
int y =
Color c = pal[sender[i]];
bmp.SetPixel(x, y, c);
}
Thanks to FBergo for the answer. I knew I was missing something very obvious!
for (int i = 0; i <= sender.Count(); i++)
{
int x = i % width;
int y = i / width;
Color c = pal[sender[i]];
bmp.SetPixel(x, y, c);
}

Adaptive Thresholding Technique to live videos from webcam C#

I am trying to detect light from 2 LED lights (red and blue) I did that using Bernsen thresholding technique. However, I applied that to an image. Now I want to apply that same technique but to a live video from my webcam. Is there anyway I could simply edit the code for this technique on the image to make it work on a video from the webcam? I will add below the code I used for this thresholding technique.
private ArrayList getNeighbours(int xPos, int yPos, Bitmap bitmap)
{
//This goes around the image in windows of 5
ArrayList neighboursList = new ArrayList();
int xStart, yStart, xFinish, yFinish;
int pixel;
xStart = xPos - 5;
yStart = yPos - 5;
xFinish = xPos + 5;
yFinish = yPos + 5;
for (int y = yStart; y <= yFinish; y++)
{
for (int x = xStart; x <= xFinish; x++)
{
if (x < 0 || y < 0 || x > (bitmap.Width - 1) || y > (bitmap.Height - 1))
{
continue;
}
else
{
pixel = bitmap.GetPixel(x, y).R;
neighboursList.Add(pixel);
}
}
}
return neighboursList;
}
private void button5_Click_1(object sender, EventArgs e)
{
//The input image
Bitmap image = new Bitmap(pictureBox2.Image);
progressBar1.Minimum = 0;
progressBar1.Maximum = image.Height - 1;
progressBar1.Value = 0;
Bitmap result = new Bitmap(pictureBox2.Image);
int iMin, iMax, t, c, contrastThreshold, pixel;
contrastThreshold = 180;
ArrayList list = new ArrayList();
for (int y = 0; y < image.Height; y++)
{
for (int x = 0; x < image.Width; x++)
{
list.Clear();
pixel = image.GetPixel(x, y).R;
list = getNeighbours(x, y, image);
list.Sort();
iMin = Convert.ToByte(list[0]);
iMax = Convert.ToByte(list[list.Count - 1]);
// These are the calculations to test whether the
current pixel is light or dark
t = ((iMax + iMin) / 2);
c = (iMax - iMin);
if (c < contrastThreshold)
{
pixel = ((t >= 160) ? 0 : 255);
}
else
{
pixel = ((pixel >= t) ? 0 : 255);
}
result.SetPixel(x, y, Color.FromArgb(pixel, pixel, pixel));
}
progressBar1.Value = y;
}
pictureBox3.Image =result;
}

Image mask by another image or color using c#

I looking for solution just like in the above question just in c#
question about android
I know how to do this with color, but I need to do this with image too.
Here is my code for color replacement:
Bitmap bit = new Bitmap(img);
for (int y = 0; y < img.Height; y++)
{
for (int x = 0; x < img.Width; x++)
{
if (bit.GetPixel(x, y).A != 0)
{
bit.SetPixel(x, y, Color.Red);
}
}
}
bit.Save(stream, ImageFormat.Png);
I don't know if this is the best answer but it's working.
System.Drawing.Image img = System.Drawing.Image.FromFile(Server.MapPath("OriginalImagePath"));
Bitmap bit = new Bitmap(img);
System.Drawing.Image mask = System.Drawing.Image.FromFile(Server.MapPath("MaskImagePath"));
Bitmap bitMask = new Bitmap(mask);
for (int y = 0; y < img.Height; y++)
{
for (int x = 0; x < img.Width; x++)
{
if (bit.GetPixel(x, y).A != 0)
{
bit.SetPixel(x, y, bitMask.GetPixel(x, y));
//bit.SetPixel(x, y, Color.Red);
}
}
}
If the mask image not in same size as the original, we need to crop it before we can replace the pixels,
of course.

C# Normalizing RGB and creating a new image

I am trying to create a program that accepts an image, recursively goes through each pixel, normalizes the pixel and re-creates a NEW image that looks the same as the original, but has normalized pixels instead.
public void parseJpeg(String jpegPath)
{
var normalizedRed = 0.0;
var normalizedGreen = 0.0;
var normalizedBlue = 0.0;
Bitmap normalizedImage = null;
var image = new Bitmap(jpegPath);
normalizedImage = new Bitmap(image.Width, image.Height);
for (int x = 0; x < image.Width; ++x)
{
for (int y = 0; y < image.Height; ++y)
{
Color color = image.GetPixel(x, y);
double exponent = 2;
double redDouble = Convert.ToDouble(color.R);
double blueDouble = Convert.ToDouble(color.B);
double greenDouble = Convert.ToDouble(color.G);
double redResult = Math.Pow(redDouble, exponent);
double blueResult = Math.Pow(blueDouble, exponent);
double greenResult = Math.Pow(greenDouble, exponent);
double totalResult = redResult + blueResult + greenResult;
normalizedRed = Convert.ToDouble(color.R) / Math.Sqrt(totalResult);
normalizedGreen = Convert.ToDouble(color.G) / Math.Sqrt(totalResult);
normalizedBlue = Convert.ToDouble(color.B) / Math.Sqrt(totalResult);
Color newCol = Color.FromArgb(Convert.ToInt32(normalizedRed), Convert.ToInt32(normalizedGreen), Convert.ToInt32(normalizedBlue));
normalizedImage.SetPixel(x, y, newCol);
}
}
normalizedImage.Save("C:\\Users\\username\\Desktop\\test1.jpeg");
resultsViewBox.AppendText("Process completed.\n");
}
Using the above code produces all black pixels and I do not understand why. When it normalizes it sets RGB = 1. After normalization, how do I set pixels with the NEW normalized value?
When I perform the below code, I get a black and blue image in my preview, but when I open the file it's blank. This is better than what I was getting before, which was ALL black pixels. This only works on one image though. So I am not sure how much of a step forward it is.
public void parseJpeg(String jpegPath)
{
Bitmap normalizedImage = null;
var image = new Bitmap(jpegPath);
normalizedImage = new Bitmap(image.Width, image.Height);
for (int x = 0; x < image.Width; ++x)
{
for (int y = 0; y < image.Height; ++y)
{
Color color = image.GetPixel(x, y);
float norm = (float)System.Math.Sqrt(color.R * color.R + color.B * color.B + color.G * color.G);
Color newCol = Color.FromArgb(Convert.ToInt32(norm));
normalizedImage.SetPixel(x, y, newCol);
}
}
normalizedImage.Save("C:\\Users\\username\\Desktop\\test1.jpeg");
resultsViewBox.AppendText("Process completed.\n");
}
I found the code for what I was trying to do:
http://www.lukehorvat.com/blog/normalizing-image-brightness-in-csharp/
public void parseJpeg(String jpegPath)
{
var image = new Bitmap(jpegPath);
normalizedImage = new Bitmap(image.Width, image.Height);
for (int x = 0; x < image.Width; ++x)
{
for (int y = 0; y < image.Height; ++y)
{
float pixelBrightness = image.GetPixel(x, y).GetBrightness();
minBrightness = Math.Min(minBrightness, pixelBrightness);
maxBrightness = Math.Max(maxBrightness, pixelBrightness);
}
}
for (int x = 0; x < image.Width; x++)
{
for (int y = 0; y < image.Height; y++)
{
Color pixelColor = image.GetPixel(x, y);
float normalizedPixelBrightness = (pixelColor.GetBrightness() - minBrightness) / (maxBrightness - minBrightness);
Color normalizedPixelColor = ColorConverter.ColorFromAhsb(pixelColor.A, pixelColor.GetHue(), pixelColor.GetSaturation(), normalizedPixelBrightness);
normalizedImage.SetPixel(x, y, normalizedPixelColor);
}
}
normalizedImage.Save("C:\\Users\\username\\Desktop\\test1.jpeg");
resultsViewBox.AppendText("Process completed.\n");
}
You are creating a new Bitmap and saving over the file for every pixel in your image. Move the
normalizedImage = new Bitmap(image.Width, image.Height);
line to before your loops, and the
normalizedImage.Save("C:\\Users\\username\\Desktop\\test1.jpeg");
line to after your loops.
Your normalization algorithm does not appear to be correct. Let's say your original color was red (255,0,0) Then your totalResult will be 65025, and your normalizedRed will be 255/sqrt(65025), which is 1, giving you a new normalized color of (1,0,0), which is essentially black.
Just as a note, your code will run a bit faster if you define all the doubles once outside the look and then assign them within the loop rather than defining and deleting each of the 8 doubles each iteration
Instead of messing with the colors you should use the brightness or luminosity factor to achieve normalization. Here is a link to the already answered question that can help you. you can convert each RGB pixel to HSL and minupulate L factor:
How do I normalize an image?
The code that you shared is actually a trim down version of HSL manipulation.

How to evaluate other elements in an array

Basically I'm creating a forest fire program that depends on the wind / dryness of the surround elements. I have an array var Trees [,] that is 20 x 20. The middle square is set "on fire". This is what needs to be done once you click button1: Evaluate each square around the one that is set on fire to determine the probability for the others to catch fire.
Color[,] map = new Color[WIDTH, HEIGHT];
for (int x = 0; x < WIDTH; x++)
for (int y = 0; y < HEIGHT; y++)
{
if (x == WIDTH / 2 && y == HEIGHT / 2)
map[x, y] = Color.Red;
else
map[x, y] = Color.Green;
}
fireBox1.box = map;
This is the 20 x 20 array that I have setup with the middle square set on fire. I just have no idea how to get the squares (array elements) around the one that is currently on fire.
You can start with a simple loop.
for (int i = 0; i < 20; i++)
{
for (int j = 0; j < 20; j++)
{
var tree = Trees[i, j];
// ...
}
}
After you have built your matrix the center should look like this.
[G][G][G]
[G][R][G]
[G][G][G]
Then we can loop through only the points that touch the center point.
int centerX = 9;
int centerY = 9;
int beginX = centerX - 1;
int endX = centerX + 1;
int beginY = centerY - 1;
int endY = centerY + 1;
for (int y = beginY; y <= endY; y++)
{
for (int x = beginX ; x <= endX; x++)
{
//Skip the center
if (x == centerX && y == centerY)
continue;
// Calculate the chance of catching on fire.
if (IsWindyPoint(x, y) || IsDryPoint(x, y))
map[x, y] = Color.Yellow;
}
}
So assuming we have wind blowing east we should see this as the matrix.
[G][G][G]
[G][R][Y]
[G][G][G]
And eventually it will expand out like this.
[G][G][G][G]
[G][G][Y][Y]
[G][R][R][Y]
[G][G][Y][Y]
[G][G][G][G]

Categories

Resources