Average value of array elements - c#

I am trying to calculate the value of a single dimensional Array, here is my code:
So when I click "Detect", it should start a threshold through my Image, beginning from i = 0 to Image height and from j = 0 to Image width:
public void detektieren_Click(object sender, RoutedEventArgs e)
{
for (i = 0; i < bitmap.Height; i++)
{
for (j = 0; j < bitmap.Width; j++)
{
stride = bitmap.PixelWidth * (bitmap.Format.BitsPerPixel / 8);
data = new byte[stride * bitmap.PixelHeight];
bitmap.CopyPixels(data, stride, 0);
index = i * stride + 4 * j;
Now accessing the ARGB data:
byte A = data[index + 3];
byte R = data[index + 2];
byte G = data[index + 1];
byte B = data[index];
After the threshold, if there are any Pixels meet the condition R=0 & G=0 & B=255:
if (Convert.ToInt32(R) == 0 && Convert.ToInt32(G) == 0 && Convert.ToInt32(B) == 255)
{
// Create a writer and open the file:
StreamWriter Messdaten;
if (!File.Exists("C:/Users/.../Messdaten.csv"))
{
Messdaten = new StreamWriter("C:/Users/.../Messdaten.csv");
}
else
{
Messdaten = File.AppendText("C:/Users/.../Messdaten.csv");
}
// Write to the file:
Messdaten.WriteLine(j + ";" + i);
// Close the stream:
Messdaten.Close();
for (y = 0; y < bitmap.Height; y++)
{
for (x = 0; x < bitmap.Width; x++)
{
double x_mw = 0; double y_mw = 0;
int[] x_array = new int[(int)bitmap.Width];
int[] y_array = new int[(int)bitmap.Height];
x_array[x] = j;
x_mw = x_array.Average();
y_array[y] = i;
y_mw = y_array.Average();
xy_coord.Content = (int) x_mw + ";" + (int) y_mw;
}
}
}
}
}
}
Everything works perfectly in the CSV file, I can detect a Pixel (e.g. blue with R=0 G=0 B=255). But I also want to copy the data of each single Pixel into Array. But apparently it doesn't really deliver what I want. It doesn't calculate the average value of sum of blue Pixels (= the centroid of the blue Pixels scatter), instead it just Shows x_mw = 0 and y_mw = 0. What did I do wrong?

After I did some modification it works. So this is the code:
public void detektieren_Click(object sender, RoutedEventArgs e)
{
int x_sum = 0; int y_sum = 0; int x_count = 0; int y_count = 0; int x_mw; int y_mw;
int[] x_array = new int[(int)bitmap.Width];
int[] y_array = new int[(int)bitmap.Height];
int[] x_array_copy = new int[(int)bitmap.Width];
int[] y_array_copy = new int[(int)bitmap.Height];
stride = bitmap.PixelWidth * (bitmap.Format.BitsPerPixel / 8);
data = new byte[stride * bitmap.PixelHeight];
bitmap.CopyPixels(data, stride, 0);
for (i = 0; i < (int) bitmap.Height; i++)
{
for (j = 0; j < (int) bitmap.Width; j++)
{
index = i * stride + 4 * j;
byte A = data[index + 3];
byte R = data[index + 2];
byte G = data[index + 1];
byte B = data[index];
if (Convert.ToInt32(R) == 0 && Convert.ToInt32(G) == 0 && Convert.ToInt32(B) == 255)
{
x_array[j] = j;
x_count++;
x_array_copy[j] = x_array_copy[j] + j;
x_sum = (int) x_array_copy.Sum();
x_mw = x_sum / x_count;
y_array[i] = i;
y_count++;
y_array_copy[i] = y_array_copy[i] + i;
y_sum = (int) y_array_copy.Sum();
y_mw = y_sum / y_count;
xy_coord.Content = x_mw + ";" + y_mw;
}
}
}
}

Related

how to write the value to each matrix index

For example, I have set up a formula to find my Xnew[k+1], Ynew[k+1] and Anew[k+1].
How do I pass the value to a 3 by 1 matrix if I want my
index 1,1 be Xnew[k+1],
index 1,2 be Ynew[k+1],
index 1,3 be Anew[k+1].
Here's what I got so far.
for (k = 0; k < 5; k++)
{
Xnew[k+1] = cX + (T * MPCV[k]) * Math.Cos(cA);
Ynew[k+1] = cY + (T * MPCV[k]) * Math.Sin(cA);
Anew[k+1] = cA + (T * MPCW[k]);
double[,] qK = new double[3, 1];
int i, j;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 1; j++)
{
qK[i, j] = 1;
}
}
}
Thank you for the help.
Suposing Xnew[k+1], Ynew[k+1] and Anew[k+1] are doubles:
for ( k = 0; k < 5; k++ ) {
Xnew[k + 1] = cX + (T * MPCV[k]) * Math.Cos(cA);
Ynew[k + 1] = cY + (T * MPCV[k]) * Math.Sin(cA);
Anew[k + 1] = cA + (T * MPCW[k]);
double[,] qk = { { Xnew[k + 1] , Ynew[k + 1] , Anew[k + 1] } };
}
This will make you a 1x3 matrix (arrays start in 0) with:
qk[0,0] = Xnew[k+1]
qk[0,1] = Ynew[k+1]
qk[0,2] = Anew[k+1]
But if you want a 3x1 matrix use instead.
double[,] qk = { { Xnew[k + 1] }, {Ynew[k + 1] }, {Anew[k + 1] } };
That will give you:
qk[0,0] = Xnew[k+1]
qk[1,0] = Ynew[k+1]
qk[2,0] = Anew[k+1]

C# and matlab give different image means?

I am calculating the average of the RGB channels of images in C# and matlab and getting slightly different result?? (am using 0-255 pixel values...)
The difference is not large but I just can't seem to understand the reason...
Is this common?? Or is it due to bitmap implementation of image?? Or precision issue?? Or does it mean their is something wrong with my code??
Code:
Matlab
I = imread('Photos\hv2512.jpg');
Ir=double(I(:,:,1));
Ig=double(I(:,:,2));
Ib=double(I(:,:,3));
avRed=mean2(Ir)
avGn=mean2(Ig)
avBl=mean2(Ib)
C#
Bitmap bmp= new Bitmap(open.FileName)
double[,] Red = new double[bmp.Width, bmp.Height];
double[,] Green = new double[bmp.Width, bmp.Height];
double[,] Blue = new double[bmp.Width, bmp.Height];
int PixelSize = 3;
BitmapData bmData = null;
if (Safe)
{
Color c;
for (int j = 0; j < bmp.Height; j++)
{
for (int i = 0; i < bmp.Width; i++)
{
c = bmp.GetPixel(i, j);
Red[i, j] = (double) c.R;
Green[i, j] = (double) c.G;
Blue[i, j] = (double) c.B;
}
}
}
double avRed = 0, avGrn = 0, avBlue = 0;
double sumRed = 0, sumGrn = 0, sumBlue = 0;
int cnt = 0;
for (int rws = 0; rws < Red.GetLength(0); rws++)
for (int clms = 0; clms < Red.GetLength(1); clms++)
{
sumRed = sumRed + Red[rws, clms];
sumGrn = sumGrn + Green[rws, clms];
sumBlue = sumBlue + Blue[rws, clms];
cnt++;
}
avRed = sumRed / cnt;
avGrn = sumGrn / cnt;
avBlue = sumBlue / cnt;
This is the image I am using

System.OverflowException in one project -- while works in another project

I have a weird problem. I have been searching the internet for a good and fast Gaussian blur algorithm. And I finally found one!
So what I did was to try it in a new project - it worked just fine.
When I then was going to import the class into my main project and then tried it, I got a System.OverflowException. I'm finding this really weird that it works in one project, but not in another.
Here's the algorithm:
(I am calling the function almost the same. I tried calling it the exact same way, but I still got an exception)
public static void FastBlur(Bitmap SourceImage, int radius)
{
var rct = new Rectangle(0, 0, SourceImage.Width, SourceImage.Height);
var dest = new int[rct.Width * rct.Height];
var source = new int[rct.Width * rct.Height];
var bits = SourceImage.LockBits(rct, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
Marshal.Copy(bits.Scan0, source, 0, source.Length);
SourceImage.UnlockBits(bits);
if (radius < 1) return;
int w = rct.Width;
int h = rct.Height;
int wm = w - 1;
int hm = h - 1;
int wh = w * h;
int div = radius + radius + 1;
var r = new int[wh];
var g = new int[wh];
var b = new int[wh];
int rsum, gsum, bsum, x, y, i, p1, p2, yi;
var vmin = new int[max(w, h)];
var vmax = new int[max(w, h)];
var dv = new int[256 * div];
for (i = 0; i < 256 * div; i++)
{
dv[i] = (i / div);
}
int yw = yi = 0;
for (y = 0; y < h; y++)
{ // blur horizontal
rsum = gsum = bsum = 0;
for (i = -radius; i <= radius; i++)
{
int p = source[yi + min(wm, max(i, 0))];
rsum += (p & 0xff0000) >> 16;
gsum += (p & 0x00ff00) >> 8;
bsum += p & 0x0000ff;
}
for (x = 0; x < w; x++)
{
r[yi] = dv[rsum];
g[yi] = dv[gsum];
b[yi] = dv[bsum];
if (y == 0)
{
vmin[x] = min(x + radius + 1, wm);
vmax[x] = max(x - radius, 0);
}
p1 = source[yw + vmin[x]];
p2 = source[yw + vmax[x]];
rsum += ((p1 & 0xff0000) - (p2 & 0xff0000)) >> 16;
gsum += ((p1 & 0x00ff00) - (p2 & 0x00ff00)) >> 8;
bsum += (p1 & 0x0000ff) - (p2 & 0x0000ff);
yi++;
}
yw += w;
}
for (x = 0; x < w; x++)
{ // blur vertical
rsum = gsum = bsum = 0;
int yp = -radius * w;
for (i = -radius; i <= radius; i++)
{
yi = max(0, yp) + x;
rsum += r[yi];
gsum += g[yi];
bsum += b[yi];
yp += w;
}
yi = x;
for (y = 0; y < h; y++)
{
dest[yi] = (int)(0xff000000u | (uint)(dv[rsum] << 16) | (uint)(dv[gsum] << 8) | (uint)dv[bsum]); // <--- Here's where I get the exception
if (x == 0)
{
vmin[y] = min(y + radius + 1, hm) * w;
vmax[y] = max(y - radius, 0) * w;
}
p1 = x + vmin[y];
p2 = x + vmax[y];
rsum += r[p1] - r[p2];
gsum += g[p1] - g[p2];
bsum += b[p1] - b[p2];
yi += w;
}
}
// copy back to image
var bits2 = SourceImage.LockBits(rct, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
Marshal.Copy(dest, 0, bits2.Scan0, dest.Length);
SourceImage.UnlockBits(bits);
}
Here's how I call the function:
public Bitmap DownloadBlurredImage(List<string> uris, int blurradius)
{
Uri urlUri = new Uri(uris.ElementAt(0));
if (RandomSelect == true)
{
Random r = new Random();
urlUri = new Uri(uris.ElementAt(r.Next(0, uris.Count - 1)));
}
WebRequest webRequest = WebRequest.CreateDefault(urlUri);
webRequest.ContentType = "image/jpeg";
WebResponse webResponse = webRequest.GetResponse();
Stream mystream;
if ((mystream = webResponse.GetResponseStream()) != null)
{
Bitmap b = new Bitmap(mystream);
imageFilters.FastBlur(b, 10); //<--- here's where I'm calling
return b;
}
else
{
return null;
}
}
Does anyone know why this is acting up? I myself have NO clue..
You're using signed 'ints' to hold unsigned data - if the MSB is set, the overflow will occur. Use unsigned ints (for example for dest), or surround in an unchecked { } directive.

C# array into MWarray Matlab

I have an MxNx3 matrix and i want to transfer it into matlab using MWArray.
Here is my code, however there is no CTOR for that.
Is there any way to do it?
RGBImage image = _currentImage as RGBImage;
int height = image.Height;
int width = image.Width;
//transform the 1D array of byte into MxNx3 matrix
byte[, ,] rgbByteImage = new byte[3, height, width];
if (image[0].Bpp > 16)
{
for (int i = 0; i < height; i++)
{
for (int j = 0, k = 0; k < width; j = j + 3, k++)
{
rgbByteImage[0, i, k] = image[0].Data[i * width + j];
rgbByteImage[1, i, k] = image[0].Data[i * width + j + 1];
rgbByteImage[2, i, k] = image[0].Data[i * width + j + 2 ];
}
}
}
MWNumericArray tempArr = new MWNumericArray(rgbByteImage);
RGBImage image = _currentImage as RGBImage;
int height = image.Height;
int width = image.Width;
//transform the 1D array of byte into MxNx3 matrix
byte[ , , ] RGBByteImage = new byte[3,height, width];
if (image[0].Bpp > 16)
{
for (int i = 0; i < height; i++)
{
for (int j = 0, k = 0; k < width; j = j + 3, k++)
{
RGBByteImage[0, i, k] = image[0].Data[3 * i * width + j];
RGBByteImage[1, i, k] = image[0].Data[3 * i * width + j + 1];
RGBByteImage[2, i, k] = image[0].Data[3 * i * width + j + 2];
}
}
}
MWNumericArray matrix = null;
matrix = new MWNumericArray(MWArrayComplexity.Real, MWNumericType.Int8, 3,height, width);
matrix = RGBByteImage;
This is what I have found.
There is also a nice tutorial here
http://domoreinlesstime.wordpress.com/2013/01/26/access-matlab-from-c/
Please notice that you have the correct refernce to the MWArray.dll file (x64 or x86). I have wasted a day or so on that.

Out of memory and overflow exceptions creating small array

I am new to C# and XNA. Have just managed to write a class that generates a triangular grid.
But there is one problem. I can get maximum 27 nodes length triangle.
At 28 it throws Out of memory exception and at 31 -overFlow exception.
I don't understand how it overflows or out of memory... Tried to
calculate all those memory values but they look very tiny.
It is only array of nodes affected by variable. Node class is not very big:
float x; 4 B
float y; 4 B
float z; 4 B
int[] con; int[6] 4*6=24 B
byte pass; 1 B
Color col; 32 b= 4 B
Total: 41B
sequence sum of nodes needed to create triangle is n(n+1)/2
out of memory at 28
28*29/2=406 nodes
total memory:
41*406 = 16646 B = 16.26 kB
Overflows at 31: 496 nodes is 19.9 kB
I did read articles about "out of memory exceptions", that structures size is bigger than it seems and that out of memory happens at sizes of 500MB... there is no way my small triangle would reach such huge size.
This is my whole class:
class TriMatrix
{
int len;
int Lenght;
Node[] node;
VertexPositionColor[] vertex;
public class Node
{
public float x;
public float y;
public float z;
public int[] con;
public byte pass;
public Color col;
public Node(byte passable)
{
pass = passable;
if (pass > 0)
{ col = Color.Green; }
else
{ col = Color.DarkRed; }
x = 0;
z = 0;
con = new int[6];
}
}
public TriMatrix(int lenght)
{
len = lenght;
Lenght = 0;
byte pass;
Random rnd = new Random();
for (int i = 0; i <= len; i++)
{
Lenght += Lenght + 1;
}
node = new Node[Lenght];
int num = 0;
for (int i = 0; i < len; i++)
{
for (int j = 0; j <= i; j++)
{
if (rnd.Next(0, 5) > 0) { pass = 1; } else { pass = 0; }
node[num] = new Node(pass);
node[num].x = (float)i - (float)j / 2.0f;
node[num].y = 0;
node[num].z = (float)j * 0.6f;
if (i < len - 1) { node[num].con[0] = num + i; } else { node[num].con[0] = -1; node[num].col = Color.Violet; }
if (i < len - 1) { node[num].con[1] = num + i + 1; } else { node[num].con[1] = -1; }
if (j < i) { node[num].con[2] = num + 1; } else { node[num].con[2] = -1; node[num].col = Color.Violet; }
if (j < i) { node[num].con[3] = num - i; } else { node[num].con[3] = -1; }
if (i > 0) { node[num].con[4] = num - i - 1; } else { node[num].con[4] = -1; }
if (i > 0) { node[num].con[5] = num - 1; } else { node[num].con[5] = -1; }
if (j == 0) { node[num].col = Color.Violet; }
num++;
}
}
}
public void Draw(Effect effect, GraphicsDevice graphics)
{
VertexPositionColor[] verts = new VertexPositionColor[3];
int num = 0;
for (int i = 0; i < len-1; i++)
{
for (int j = 0; j <= i; j++)
{
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Apply();
verts[0] = new VertexPositionColor(new Vector3(node[num].x, node[num].y, node[num].z), node[num].col);
verts[1] = new VertexPositionColor(new Vector3(node[num + i + 1].x, node[num + i + 1].y, node[num + i + 1].z), node[num + i + 1].col);
verts[2] = new VertexPositionColor(new Vector3(node[num + i + 2].x, node[num + i + 2].y, node[num + i + 2].z), node[num + i + 2].col);
graphics.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleStrip, verts, 0, 1);
if ( j < i)
{
verts[0] = new VertexPositionColor(new Vector3(node[num].x, node[num].y, node[num].z), node[num].col);
verts[1] = new VertexPositionColor(new Vector3(node[num + i + 2].x, node[num + i + 2].y, node[num + i + 2].z), node[num + i + 2].col);
verts[2] = new VertexPositionColor(new Vector3(node[num + 1].x, node[num + 1].y, node[num + 1].z), node[num + 1].col);
graphics.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleStrip, verts, 0, 1);
}
}
num++;
}
}
}
}// endclass
I assume that your bug lies in this loop (taking the liberty to correct your spelling):
for (int i = 0; i <= len; i++)
{
Length += Length + 1;
}
Within the loop, you are incrementing the value of Length by itself plus one. This effectively means that you are doubling the value of Length for each iteration, resulting in exponential growth.
During the first few iterations, the values of Length will be: 1, 3, 7, 15, 31, 63, …. We can generalize this sequence such that, at iteration i, the value of Length will be 2i+1−1. At iteration 28, this would be 536,870,911. At iteration 31, this would be 4,294,967,295.
Edit: As you mentioned in the comment below, the correct fix for computing the number of elements in a triangular grid of length len would be:
for (int i = 1; i <= len; i++)
{
Length += i;
}
This is equivalent to the summation 1 + 2 + 3 + … + len, which computes what is known as the triangular number. It may be succinctly computed using the formula:
Length = len * (len + 1) / 2;
The reason that this number grows so large is that it is a square relation; for a side of length n, you need an area of approximately half of n².

Categories