This program works with Median filter. I need help with fixing the code. It applies to the line
if ((diffX > -1) && (diffY > -1)...
...in the MedianOfArea method. It would be better if the pixels, which are included in the loop's bounds, would be determined initially. This solution helps to avoid checking every time. Can you help me with fixing it?
namespace Recognizer
{
internal static class MedianFilterTask
{
public static double[,] MedianFilter(double[,] original)
{
var filter = new double[original.GetLength(0), original.GetLength(1)];
var lengthX = original.GetLength(0);
var lengthY = original.GetLength(1);
for (var x = 0; x < lengthX; x++)
for (var y = 0; y < lengthY; y++)
filter[x, y] = MedianOfArea(x, y, original, lengthX, lengthY);
return filter;
}
public static double MedianCount(ref double median, List<double> pixelsFields)
{
pixelsFields.Sort();
var countPixels = pixelsFields.Count;
if (countPixels % 2 == 0)
median = (pixelsFields[countPixels / 2 - 1] + pixelsFields[countPixels / 2]) / 2;
else
median = pixelsFields[countPixels / 2];
return median;
}
public static double MedianOfArea(int x, int y, double[,] original, int lengthX, int lengthY)
{
var pixelsFields = new List<double>();
double median = 0;
for (int areasX = -1; areasX < 2; areasX++)
for (int areasY = -1; areasY < 2; areasY++)
{
var diffX = x + areasX;
var diffY = y + areasY;
if ((diffX > -1) && (diffY > -1) && (diffX < lengthX) && (diffY < lengthY))
pixelsFields.Add(original[diffX, diffY]);
}
MedianCount(ref median, pixelsFields);
return median;
}
}
}
You could iterate directly on diffX (and diffY) and use Min and Max to set the ranges to loop over:
using System;
int startX = Math.Max(0, x-1);
int endX = Math.Min(lengthX, x+2);
int startY = Math.Max(0, y-1);
int endY = Math.Min(lengthY, y+2);
for (int diffX = startX; diffX < endX; diffX++)
for (int diffY = startY; diffY < endY; diffY++)
pixelsFields.Add(original[diffX, diffY]);
I am creating a library for Neural Networks; I have successfully implemented the Back Propagation algorithm, but I'm having trouble with Resilient Propagation.
I have been using the XOR scenario to test my implementation; the error seems to decrease after a few epochs, then it increases and eventually stops changing.
The network I am testing on has 3 layers - 2 input, 2 hidden and 1 output neuron/s. The synapse/dendrite weights are on the following layer's neurons, for example, the input-hidden weights would be stored on the hidden neurons and the hidden-output weights would be stored on the output neurons.
This is my gradient calculation (EDIT 4):
private void CalculateGradient()
{
for (int t = 0; t < TrainingInputs.Count; ++t) //loop through training data
{
Network.Run(TrainingInputs[t]);
for (int l = Network.Layers.Count - 1; l > 0; l--)
{
for (int i = 0; i < Network.Layers[l].Neurons.Count; i++)
{
Network.Layers[l].Neurons[i].Delta = l < Network.Layers.Count - 1
? CalculateNonLastGradient(l + 1, i, Network.Layers[l].Neurons[i].Value)
: CalculateLastGradient(TrainingOutputs[t][i], Network.Layers[l].Neurons[i].Value);
}
}
for (int l = Network.Layers.Count - 1; l > 0; l--)
{
for (int j = 0; j < Network.Layers[l].Neurons.Count; ++j)
{
double grad = Network.Layers[l].Neurons[j].Delta;
biasGrads[l][j] += grad;
for (int i = 0; i < Network.Layers[l - 1].Neurons.Count; ++i)
{
grad = Network.Layers[l].Neurons[j].Delta * Network.Layers[l - 1].Neurons[i].Value;
grads[l][j][i] += grad;
}
}
}
int o = 0;
Layer layer = Network.Layers[Network.Layers.Count - 1];
errors.Add(layer.Neurons.Sum(n => Math.Abs(TrainingOutputs[t][o++] - n.Value)));
}
Error = errors.Average();
}
private double CalculateLastGradient(double ideal, double nValue)
{
return Network.Activation.Derivitive(nValue) * (ideal - nValue);
}
private double CalculateNonLastGradient(int nextLayer, int j, double nValue)
{
double sum = 0.0;
for (int i = 0; i < Network.Layers[nextLayer].Neurons.Count; i++)
{
sum += Network.Layers[nextLayer].Neurons[i].Delta * Network.Layers[nextLayer].Neurons[i].Dendrites[j].Weight;
}
return Network.Activation.Derivitive(nValue) * sum;
}
My RProp implementation (EDIT 4):
public bool Algorithm()
{
//initialise matrices
if (!initializedMatrices)
{
InitializeMatrices();
}
ZeroOut();
//calculate gradients
CalculateGradient();
for (int l = 1; l < Network.Layers.Count; l++) //layers
{
for (int i = 0; i < Network.Layers[l - 1].Neurons.Count; ++i) //prev layer neurons
{
for (int j = 0; j < Network.Layers[l].Neurons.Count; ++j) //current layer neurons
{
double delta = prevDeltas[l][j][i];
int change = Math.Sign(prevGrads[l][j][i] * grads[l][j][i]);
if (change > 0)
{
delta = Math.Min(delta * etaPlus, deltaMax);
double deltaWeight = -Math.Sign(grads[l][j][i]) * delta;
Network.Layers[l].Neurons[j].Dendrites[i].Weight += deltaWeight;
}
else if (change < 0)
{
delta = Math.Max(delta * etaMinus, deltaMin);
Network.Layers[l].Neurons[j].Dendrites[i].Weight -= prevDeltas[l][j][i];
prevGrads[l][j][i] = 0;
}
else if (change == 0)
{
double deltaWeight = -Math.Sign(grads[l][j][i]) * delta;
Network.Layers[l].Neurons[j].Dendrites[i].Weight += deltaWeight;
}
prevGrads[l][j][i] = grads[l][j][i];
prevDeltas[l][j][i] = delta;
} //j
} //i
for (int i = 1; i < Network.Layers[l].Neurons.Count; ++i)
{
double delta = prevBiasDeltas[l][i];
int change = Math.Sign(prevBiasGrads[l][i] * biasGrads[l][i]);
if (change > 0)
{
delta = Math.Min(prevBiasDeltas[l][i] * etaPlus, deltaMax);
double biasDeltaWeight = -Math.Sign(biasGrads[l][i]) * delta;
Network.Layers[l].Neurons[i].Bias += biasDeltaWeight;
}
else if (change < 0)
{
delta = Math.Max(prevBiasDeltas[l][i] * etaMinus, deltaMin);
Network.Layers[l].Neurons[i].Bias -= prevBiasDeltas[l][i];
prevBiasGrads[l][i] = 0;
}
else if (change == 0)
{
double biasDeltaWeight = -Math.Sign(biasGrads[l][i]) * delta;
Network.Layers[l].Neurons[i].Bias += biasDeltaWeight;
}
prevBiasGrads[l][i] = biasGrads[l][i];
prevBiasDeltas[l][i] = delta;
}
}
return true;
}
Could anyone point me as to what could be going wrong?
EDIT:
The issue seems to be that the delta is not changing.
EDIT 2:
I have fixed the delta not changing by initializing the first previous deltas to 0.01 and Zero'ing the gradients before each call. The error increases very fast, then decreases very slowly with TANH; with Sigmoid it does the opposite.
EDIT 3:
The loop for the bias' was starting at 0, when it should have been 1. Fixing this fixed the original issue, but has brought up at new one - the error stops decreasing after a certain point.
EDIT 4: I realised that I had not accumulated the gradients for each neuron over the training set. The error now decreases, but very slowly.
I have two Line Segments, represented by a 3D point at their beginning/end points.
Line:
class Line
{
public string Name { get; set; }
public Point3D Start { get; set; } = new Point3D();
public Point3D End { get; set; } = new Point3D();
}
The 3D points are just 3 doubles for coordinates X,Y and Z.
3DPoint:
class Point3D
{
public double X { get; set; }
public double Y { get; set; }
public double Z { get; set; }
}
The Question:
Can I find the distance between two 'Lines' and the endpoints of that distance 'Line'. [1
What I have:
Currently, I can successfully get the distance between the two lines with this code (Adapted From Here Using the Segment To Segment Section):
public double lineNearLine(Line l1, Line l2)
{
Vector3D uS = new Vector3D { X = l1.Start.X, Y = l1.Start.Y, Z = l1.Start.Z };
Vector3D uE = new Vector3D { X = l1.End.X, Y = l1.End.Y, Z = l1.End.Z };
Vector3D vS = new Vector3D { X = l2.Start.X, Y = l2.Start.Y, Z = l2.Start.Z };
Vector3D vE = new Vector3D { X = l2.End.X, Y = l2.End.Y, Z = l2.End.Z };
Vector3D w1 = new Vector3D { X = l1.Start.X, Y = l1.Start.Y, Z = l1.Start.Z };
Vector3D w2 = new Vector3D { X = l2.Start.X, Y = l2.Start.Y, Z = l2.Start.Z };
Vector3D u = uE - uS;
Vector3D v = vE - vS;
Vector3D w = w1 - w2;
double a = Vector3D.DotProduct(u, u);
double b = Vector3D.DotProduct(u, v);
double c = Vector3D.DotProduct(v, v);
double d = Vector3D.DotProduct(u, w);
double e = Vector3D.DotProduct(v, w);
double D = a * c - b * b;
double sc, sN, sD = D;
double tc, tN, tD = D;
if (D < 0.01)
{
sN = 0;
sD = 1;
tN = e;
tD = c;
}
else
{
sN = (b * e - c * d);
tN = (a * e - b * d);
if (sN < 0)
{
sN = 0;
tN = e;
tD = c;
}
else if (sN > sD)
{
sN = sD;
tN = e + b;
tD = c;
}
}
if (tN < 0)
{
tN = 0;
if (-d < 0)
{
sN = 0;
}
else if (-d > a)
{
sN = sD;
}
else
{
sN = -d;
sD = a;
}
}
else if (tN > tD)
{
tN = tD;
if ((-d + b) < 0)
{
sN = 0;
}
else if ((-d + b) > a)
{
sN = sD;
}
else
{
sN = (-d + b);
sD = a;
}
}
if (Math.Abs(sN) < 0.01)
{
sc = 0;
}
else
{
sc = sN / sD;
}
if (Math.Abs(tN) < 0.01)
{
tc = 0;
}
else
{
tc = tN / tD;
}
Vector3D dP = w + (sc * u) - (tc * v);
double distance1 = Math.Sqrt(Vector3D.DotProduct(dP, dP));
return distance1;
}
What I Need:
Is there any way to determine the endpoints of the displacement vector 'dP' from the code above? If not, can anyone suggest a better method for finding minimum distance and the endpoints of that distance?
Thank you for Reading, and Thanks in advance for any suggestions!
An Enormous Thank You to #Isaac van Bakel for the theory behind this Solution
Here is my code complete: Shortest distance between two lines represented by the line that connects them at that shortest distance.
Classes:
Sharp3D.Math : I use this reference for Vector3D, but really any 3D vector class will work. On top of that, the vectors aren't even required if you do the subtraction element by element.
Point3D : My Personal Point3D class. Feel free to use as much or little as you want.
class Point3D
{
public double X { get; set; }
public double Y { get; set; }
public double Z { get; set; }
public Vector3D getVector()
{
return new Vector3D { X = this.X, Y = this.Y, Z = this.Z };
}
}
Line : My Personal Line class. Feel free to use as much or little as you want.
class Line
{
public string Name { get; set; }
public Point3D Start { get; set; } = new Point3D();
public Point3D End { get; set; } = new Point3D();
public double Length
{
get
{
return Math.Sqrt(Math.Pow((End.X - Start.X), 2) + Math.Pow((End.Y - Start.Y), 2));
}
}
}
Functions:
ClampPointToLine : Clamping function I wrote to clamp a point to a line.
public Point3D ClampPointToLine(Point3D pointToClamp, Line lineToClampTo)
{
Point3D clampedPoint = new Point3D();
double minX, minY, minZ, maxX, maxY, maxZ;
if(lineToClampTo.Start.X <= lineToClampTo.End.X)
{
minX = lineToClampTo.Start.X;
maxX = lineToClampTo.End.X;
}
else
{
minX = lineToClampTo.End.X;
maxX = lineToClampTo.Start.X;
}
if (lineToClampTo.Start.Y <= lineToClampTo.End.Y)
{
minY = lineToClampTo.Start.Y;
maxY = lineToClampTo.End.Y;
}
else
{
minY = lineToClampTo.End.Y;
maxY = lineToClampTo.Start.Y;
}
if (lineToClampTo.Start.Z <= lineToClampTo.End.Z)
{
minZ = lineToClampTo.Start.Z;
maxZ = lineToClampTo.End.Z;
}
else
{
minZ = lineToClampTo.End.Z;
maxZ = lineToClampTo.Start.Z;
}
clampedPoint.X = (pointToClamp.X < minX) ? minX : (pointToClamp.X > maxX) ? maxX : pointToClamp.X;
clampedPoint.Y = (pointToClamp.Y < minY) ? minY : (pointToClamp.Y > maxY) ? maxY : pointToClamp.Y;
clampedPoint.Z = (pointToClamp.Z < minZ) ? minZ : (pointToClamp.Z > maxZ) ? maxZ : pointToClamp.Z;
return clampedPoint;
}
distanceBetweenLines : The function that returns the line that represents the shortest distance between two lines. Returns null if unsolvable.
public Line distBetweenLines(Line l1, Line l2)
{
Vector3D p1, p2, p3, p4, d1, d2;
p1 = l1.Start.getVector();
p2 = l1.End.getVector();
p3 = l2.Start.getVector();
p4 = l2.End.getVector();
d1 = p2 - p1;
d2 = p4 - p3;
double eq1nCoeff = (d1.X * d2.X) + (d1.Y * d2.Y) + (d1.Z * d2.Z);
double eq1mCoeff = (-(Math.Pow(d1.X, 2)) - (Math.Pow(d1.Y, 2)) - (Math.Pow(d1.Z, 2)));
double eq1Const = ((d1.X * p3.X) - (d1.X * p1.X) + (d1.Y * p3.Y) - (d1.Y * p1.Y) + (d1.Z * p3.Z) - (d1.Z * p1.Z));
double eq2nCoeff = ((Math.Pow(d2.X, 2)) + (Math.Pow(d2.Y, 2)) + (Math.Pow(d2.Z, 2)));
double eq2mCoeff = -(d1.X * d2.X) - (d1.Y * d2.Y) - (d1.Z * d2.Z);
double eq2Const = ((d2.X * p3.X) - (d2.X * p1.X) + (d2.Y * p3.Y) - (d2.Y * p2.Y) + (d2.Z * p3.Z) - (d2.Z * p1.Z));
double[,] M = new double[,] { { eq1nCoeff, eq1mCoeff, -eq1Const }, { eq2nCoeff, eq2mCoeff, -eq2Const } };
int rowCount = M.GetUpperBound(0) + 1;
// pivoting
for (int col = 0; col + 1 < rowCount; col++) if (M[col, col] == 0)
// check for zero coefficients
{
// find non-zero coefficient
int swapRow = col + 1;
for (; swapRow < rowCount; swapRow++) if (M[swapRow, col] != 0) break;
if (M[swapRow, col] != 0) // found a non-zero coefficient?
{
// yes, then swap it with the above
double[] tmp = new double[rowCount + 1];
for (int i = 0; i < rowCount + 1; i++)
{ tmp[i] = M[swapRow, i]; M[swapRow, i] = M[col, i]; M[col, i] = tmp[i]; }
}
else return null; // no, then the matrix has no unique solution
}
// elimination
for (int sourceRow = 0; sourceRow + 1 < rowCount; sourceRow++)
{
for (int destRow = sourceRow + 1; destRow < rowCount; destRow++)
{
double df = M[sourceRow, sourceRow];
double sf = M[destRow, sourceRow];
for (int i = 0; i < rowCount + 1; i++)
M[destRow, i] = M[destRow, i] * df - M[sourceRow, i] * sf;
}
}
// back-insertion
for (int row = rowCount - 1; row >= 0; row--)
{
double f = M[row, row];
if (f == 0) return null;
for (int i = 0; i < rowCount + 1; i++) M[row, i] /= f;
for (int destRow = 0; destRow < row; destRow++)
{ M[destRow, rowCount] -= M[destRow, row] * M[row, rowCount]; M[destRow, row] = 0; }
}
double n = M[0, 2];
double m = M[1, 2];
Point3D i1 = new Point3D { X = p1.X + (m * d1.X), Y = p1.Y + (m * d1.Y), Z = p1.Z + (m * d1.Z) };
Point3D i2 = new Point3D { X = p3.X + (n * d2.X), Y = p3.Y + (n * d2.Y), Z = p3.Z + (n * d2.Z) };
Point3D i1Clamped = ClampPointToLine(i1, l1);
Point3D i2Clamped = ClampPointToLine(i2, l2);
return new Line { Start = i1Clamped, End = i2Clamped };
}
Implementation:
Line shortestDistanceLine = distBetweenLines(l1, l2);
Results:
So far this has been accurate in my testing. Returns null if passed two identical lines. I appreciate any feedback!
The shortest distance between two skew lines (lines which don't intersect) is the distance of the line which is perpendicular to both of them.
If we have a line l1 with known points p1 and p2, and a line l2 with known points p3 and p4:
The direction vector of l1 is p2-p1, or d1.
The direction vector of l2 is p4-p3, or d2.
We therefore know that the vector we are looking for, v, is perpendicular to both of these direction vectors:
d1.v = 0 & d2.v = 0
Or, if you prefer:
d1x*vx + d1y*vy + d1z*vz = 0
And the same for d2.
Let's take the point on the lines l1, l2 where v is actually perpendicular to the direction. We'll call these two points i1 and i2 respectively.
Since i1 lies on l1, we can say that i1 = p1 + m*d1, where m is some number.
Similarly, i2 = p3 + n*d2, where n is another number.
Since v is the vector between i1 and i2 (by definition) we get that v = i2 - i1.
This gives the substitutions for the x,y,z vectors of v:
vx = i2x - i1x = (p3x + n*d2x) - (p1x + m*d1x)
and so on.
Which you can now substitute back into your dot product equation:
d1x * ( (p3x + n*d2x) - (p1x + m*d1x) ) + ... = 0
This has reduced our number of equations to 2 (the two dot product equations) with two unknowns (m and n), so you can now solve them!
Once you have m and n, you can find the coordinates by going back to the original calculation of i1 and i2.
If you only wanted the shortest distance for points on the segment between p1-p2 and p3-p4, you can clamp i1 and i2 between these ranges of coordinates, since the shortest distance will always be as close to the perpendicular as possible.
The code above return a wrong value so I take the idea from Python code (Shortest distance between two line segments) and I converted for C#. It necessary to use Numpy lib for C#:
public static Tuple<NDarray, NDarray, NDarray> closestDistanceBetweenLines(
NDarray a0,
NDarray a1,
NDarray b0,
NDarray b1,
bool clampAll = false,
bool clampA0 = false,
bool clampA1 = false,
bool clampB0 = false,
bool clampB1 = false)
{
// If clampAll=True, set all clamps to True
if (clampAll)
{
clampA0 = true;
clampA1 = true;
clampB0 = true;
clampB1 = true;
}
// Calculate denomitator
NDarray A = a1 - a0;
NDarray B = b1 - b0;
NDarray magA = np.linalg.norm(A);
NDarray magB = np.linalg.norm(B);
NDarray _A = A / magA;
NDarray _B = B / magB;
NDarray cross = np.cross(_A, _B);
double denom = Math.Pow((float)np.linalg.norm(cross), 2);
// If lines are parallel (denom=0) test if lines overlap.
// If they don't overlap then there is a closest point solution.
// If they do overlap, there are infinite closest positions, but there is a closest distance
if (denom == 0)
{
NDarray d0 = np.dot(_A, b0 - a0);
// Overlap only possible with clamping
if (clampA0 || clampA1 || clampB0 || clampB1)
{
NDarray d1 = np.dot(_A, b1 - a0);
// Is segment B before A?
if ((float)d0 <= 0F || (float)d0 >= (float)d1)
{
if (clampA0 && clampB1)
{
if ( (float)np.absolute(d0) < (float)np.absolute(d1) )
{
return Tuple.Create(a0, b0, np.linalg.norm(a0 - b0));
}
return Tuple.Create(a0, b1, np.linalg.norm(a0 - b1));
}
}
else if ((float)d0 >= (float)magA || (float)d0 <= (float)d1)
{
// Is segment B after A?
if (clampA1 && clampB0)
{
if ((float)np.absolute(d0) < (float)np.absolute(d1))
{
return Tuple.Create(a1, b0, np.linalg.norm(a1 - b0));
}
return Tuple.Create(a1, b1, np.linalg.norm(a1 - b1));
}
}
}
// Segments overlap, return distance between parallel segments;
NDarray vuoto1 = np.array(new[] { 0 });
return Tuple.Create(vuoto1, vuoto1, np.linalg.norm(d0 * _A + a0 - b0));
}
// Lines criss-cross: Calculate the projected closest points
NDarray t = b0 - a0;
var ArrFordetA = np.array(new float[,] { { (float)t[0], (float)t[1], (float)t[2] },
{ (float)_B[0], (float)_B[1], (float)_B[2] },
{ (float)cross[0], (float)cross[1], (float)cross[2] } });
NDarray detA = np.linalg.det(ArrFordetA);
var ArrFordetB = np.array(new float[,] { { (float)t[0], (float)t[1], (float)t[2] },
{ (float)_A[0], (float)_A[1], (float)_A[2] },
{ (float)cross[0], (float)cross[1], (float)cross[2] } });
NDarray detB = np.linalg.det(ArrFordetB);
var t0 = detA / denom;
var t1 = detB / denom;
var pA = a0 + _A * t0; // Projected closest point on segment A
var pB = b0 + _B * t1; // Projected closest point on segment B
// Clamp projections
if (clampA0 || clampA1 || clampB0 || clampB1)
{
if (clampA0 && (float)t0 < 0)
{
pA = a0;
}
else if (clampA1 && (float)t0 > (float)magA)
{
pA = a1;
}
if (clampB0 && (float)t1 < 0)
{
pB = b0;
}
else if (clampB1 && (float)t1 > (float)magB)
{
pB = b1;
}
// Clamp projection A
if (clampA0 && (float)t0 < 0 || clampA1 && (float)t0 > (float)magA)
{
NDarray dot = np.dot(_B, pA - b0);
if ( clampB0 && (float)dot < 0)
{
dot = (NDarray)0;
}
else if (clampB1 && (float)dot > (float)magB)
{
dot = magB;
}
pB = b0 + _B * dot;
}
// Clamp projection B
if ( clampB0 && (float)t1 < 0 || clampB1 && (float)t1 > (float)magB)
{
NDarray dot = np.dot(_A, pB - a0);
if (clampA0 && (float)dot < 0)
{
dot = (NDarray)0;
}
else if (clampA1 && (float)dot > (float)magA)
{
dot = magA;
}
pA = a0 + _A * dot;
}
}
return Tuple.Create(pA, pB, np.linalg.norm(pA - pB));
}
to call this function use:
private void button1_Click(object sender, EventArgs e)
{
NDarray a1 = np.array(new[] { 13.43, 21.77, 46.81 });
NDarray a0 = np.array(new[] { 27.83, 31.74, -26.60 });
NDarray b0 = np.array(new[] { 77.54, 7.53, 6.22 });
NDarray b1 = np.array(new[] { 26.99, 12.39, 11.18 });
Debug.WriteLine("----------------- True: -----------------");
Debug.WriteLine(closestDistanceBetweenLines(a0, a1, b0, b1, true));
Debug.WriteLine("---------------------------------------------");
Debug.WriteLine("");
Debug.WriteLine("----------------- False: -----------------");
Debug.WriteLine(closestDistanceBetweenLines(a0, a1, b0, b1, false));
Debug.WriteLine("---------------------------------------------");
Tuple<NDarray, NDarray, NDarray> RisultatoTrue = closestDistanceBetweenLines(a0, a1, b0, b1, true);
var Pa = np.array(RisultatoTrue.Item1);
Debug.WriteLine("Start point X:" + Pa[0].ToString());
Debug.WriteLine("Start point Y:" + Pa[1].ToString());
Debug.WriteLine("Start point Z:" + Pa[2].ToString());
var Pb = np.array(RisultatoTrue.Item2);
Debug.WriteLine("End point X:" + Pb[0].ToString());
Debug.WriteLine("End point Y:" + Pb[1].ToString());
Debug.WriteLine("End point Z:" + Pb[2].ToString());
var dist = np.array(RisultatoTrue.Item3);
Debug.WriteLine("Distance:" + dist.ToString());
}
I have project about fingerprint classification with c# and in one part compute angle.
in this part my project give no answer and hang and dont have any action .
to compute angle first compute sobelx and sobely filter and then compute angle with arctan
please help me
// calcute angle***************
public void computeAngle()
{
sobelx();
sobely();
angleIMG = new double[imgsx.Width, imgsx.Height];
try
{
for(int i=10 ; i<=200 ; i++)
{
for (int j = 10; j <= 150; j++)
{
if (Oy(i, j) != 0.0)
{
angleIMG[i, j] = Math.Atan(Ox(i, j) / Oy(i, j)) / 2 + Math.PI / 2;
textBox1.Text += Math.Abs(angleIMG[i, j]).ToString();
}
else
{
angleIMG[i, j] = 0.0;
}
}
textBox1.Text = "\n";
}
}
catch (Exception e1)
{
MessageBox.Show(e1.Message);
}
//get Ox(i,j)****************
public double Ox(int i, int j)
{
double wx=0.0;
for (int u = i - 1; u <= i + 1; u++)
{
for (int v = i - 1; v <= i + 1; v++)
{
Color cw = imgsx.GetPixel(u, v);
Color cw1 = imgsy.GetPixel(u, v);
wx =wx+ 2*( cw.R * cw1.R);
}
}
return wx;
}
//get Oy(i,j)****************
public double Oy(int i, int j)
{
double wy = 0.0;
for (int u = i - 1; u <= i + 1; u++)
{
for (int v = i - 1; v <= i + 1; v++)
{
Color cw=imgsx.GetPixel(u, v);
Color cw1=imgsy.GetPixel(u, v);
wy =wy+ Math.Pow (cw.R,2 )- Math.Pow(cw1.R,2);
}
}
return wy;
}
Because Red color can be up to 255, your Ox method can return values up to 1,170,450, and Oy is similar, is this what you intended?
An angle stored as a double will have up to 16 significant figures, and you are trying to concatenate 26,600 of them, this will take a while! To increase performance, I suggest you round off the angles, for instance to 2 decimal places, and then append them to a StringBuilder, which you can convert back to a string before putting it in your text box. Do something like
sb.Append(angleIMG[i, j].ToString("F2")).
I am a beginner in C# and I wanted to implement the following Pseudo code of the FFT algorithm:
function fft(n, f):
if (n = 1)
return f
else
g = fft(n/2, (f_0, f_2, ..., f_{n-2}))
u = fft(n/2, (f_1, f_3, ..., f_{n-1}))
for k = 0 to n/2 - 1
c_k = g_k + u_k*exp(-2*pi*i*k/n)
c_{k+n/2} = g_k-u_k*exp(-2*pi*i*k/n)
return c
I tried to implement that in C# as you can see:
public static class FFT
{
public static Complex[] fft(Complex[] f)
{
if (f.Length == 1)
{
return f;
}
else
{
Complex[] g = fft(even_indices(f));
Complex[] u = fft(odd_indices(f));
Complex[] c = new Complex[f.Length];
for (int k = 0; k < f.Length / 2 - 1; k++)
{
Complex w_k = u[k] * Complex.FromPolarCoordinates(1.0, -2 * Math.PI * k / f.Length);
c[k] = g[k] + w_k;
c[k + f.Length / 2] = g[k] - w_k;
}
return c;
}
}
private static Complex[] even_indices(Complex[] f)
{
Complex[] f_even = new Complex[f.Length / 2];
for (int i = 0; i < f.Length; i++)
{
if (i % 2 == 0)
{
f_even[i / 2] = f[i];
}
}
return f_even;
}
private static Complex[] odd_indices(Complex[] f)
{
Complex[] f_odd = new Complex[f.Length / 2];
for (int i = 0; i < f.Length; i++)
{
if (i % 2 == 1)
{
f_odd[(i-1)/2] = f[i];
}
}
return f_odd;
}
}
class Program
{
static void Main()
{
Complex[] test = { 1.0, 2.454167, 8.4567, 9.4564 };
var data = FFT.fft(test);
Console.WriteLine("FFT");
for (int i = 0; i < data.Length; i++)
{
Console.WriteLine(data[i]);
}
Console.ReadKey();
}
}
Now there is no error message and it gets completely compiled. However, the output is
FFT
(0, 0)
(0, 0)
(0, 0)
(0, 0)
which is not what I want. What is wrong here?
Thanks again
Complex[] c = new Complex[f.Length / 2 - 1];
I would round up, so + 1..
f.Length == 2 would return 0 for array length.
I'd expect the error actually resulting from the next line:
c[k + f.Length / 2] = g[k] - u[k] * Complex.Exp(-w_k);
where you add len/2 to the k-index - which will eventually result in a index > length/2-1. (dev of 'c').
If the rest is correct you should declare c as:
Complex[] c = new Complex[f.Length];
Add:
in your code, the loop should iterate uo to len/2-1, so change to:
for (int k = 0; k <= f.Length / 2 - 1; k++)