Can you guys help me converting this C# code to Objective-C?
I don't have a clue about C#/Visual Studio!
public static class BezierSpline
{
public static void GetCurveControlPoints(Point[] knots,
out Point[] firstControlPoints, out Point[] secondControlPoints)
{
int n = knots.Length - 1;
// Calculate first Bezier control points
// Right hand side vector
double[] rhs = new double[n];
// Set right hand side X values
for (int i = 1; i < n - 1; ++i)
rhs[i] = 4 * knots[i].X + 2 * knots[i + 1].X;
rhs[0] = knots[0].X + 2 * knots[1].X;
rhs[n - 1] = (8 * knots[n - 1].X + knots[n].X) / 2.0;
// Get first control points X-values
double[] x = GetFirstControlPoints(rhs);
// Set right hand side Y values
for (int i = 1; i < n - 1; ++i)
rhs[i] = 4 * knots[i].Y + 2 * knots[i + 1].Y;
rhs[0] = knots[0].Y + 2 * knots[1].Y;
rhs[n - 1] = (8 * knots[n - 1].Y + knots[n].Y) / 2.0;
// Get first control points Y-values
double[] y = GetFirstControlPoints(rhs);
// Fill output arrays.
firstControlPoints = new Point[n];
secondControlPoints = new Point[n];
for (int i = 0; i < n; ++i)
{
// First control point
firstControlPoints[i] = new Point(x[i], y[i]);
// Second control point
if (i < n - 1)
secondControlPoints[i] = new Point(2 * knots
[i + 1].X - x[i + 1], 2 *
knots[i + 1].Y - y[i + 1]);
else
secondControlPoints[i] = new Point((knots
[n].X + x[n - 1]) / 2,
(knots[n].Y + y[n - 1]) / 2);
}
}
private static double[] GetFirstControlPoints(double[] rhs)
{
int n = rhs.Length;
double[] x = new double[n]; // Solution vector.
double[] tmp = new double[n]; // Temp workspace.
double b = 2.0;
x[0] = rhs[0] / b;
for (int i = 1; i < n; i++) // Decomposition and forward substitution.
{
tmp[i] = 1 / b;
b = (i < n - 1 ? 4.0 : 3.5) - tmp[i];
x[i] = (rhs[i] - x[i - 1]) / b;
}
for (int i = 1; i < n; i++)
x[n - i - 1] -= tmp[n - i] * x[n - i]; // Backsubstitution.
return x;
}
}
thanks.
double[] tmp = new double[n];
tmp is an array of length n. Each value is not initialized explicitly, but it is implicitly set to the default value of the double type, which is 0. So tmp is an n length array of zeros. {0,0,0,0,0, ... 0}
Related
So I'm running iterations with this formula:
double x = 10 / 0.25 * ((0.0002 * x1 * (10 - 0.25 * x1)) + 0.00217 * x2 * (20 - 0.25 * x2)); With this process: Xn+1 = f(Xn).
And if you start from negative X you will eventually end up with (-/+) infinity, so after 6 iterations I'm supposed to get infinity, but what I got surprised me and I couldn't find anywhere what that is, I got "-?", I've tried comparing it to +/- infinity and tried to compare it to int numbers just to clarify what it is, but I cant get anything out of it, for example, I've tried if ("-?" > 1000) break;, and it doesn't outcome as "true". Neither am I getting any errors by comparing it to int/double, I need to stop iterations when I start going into infinity, how can I do that?
code:
public static double CalculateX1(double x1, double x2)
{
double x = 10 / 0.25 * ((0.0002 * x1 * (10 - 0.25 * x1)) + 0.00217 * x2 * (20 - 0.25 * x2));
return x;
}
public static double CalculateX2(double x2, double x1)
{
double y = 20 / 0.25 * ((0.00052 * x2 * (20 - 0.25 * x2)) + 0.0075 * x1 * (10 - 0.25 * x1));
return y;
}
static void Main(string[] args)
{
string writePath = #"C:\Users\evluc\Desktop\cord.txt";
double X = -5;
double Y = -5;
int pointer = 1;
double[,] coordinates = new double[10001, 2];
coordinates[0, 0] = X;
coordinates[0, 1] = Y;
for (int i = 0; i < 5000; i++)
{
//double XTemp = CalculateX1(X, Y);
//double YTemp = CalculateX2(Y, X);
//X = CalculateX1(coordinates[pointer - 1, 0], coordinates[pointer - 1, 1]);
//Y = CalculateX2(coordinates[pointer - 1, 1], coordinates[pointer - 1, 0]);
coordinates[pointer, 0] = CalculateX1(coordinates[pointer - 1, 0], coordinates[pointer - 1, 1]);
coordinates[pointer, 1] = CalculateX2(coordinates[pointer - 1, 1], coordinates[pointer - 1, 0]);
pointer++;
if (Math.Abs(coordinates[pointer, 0]) > 1000 || Math.Abs(coordinates[pointer, 1]) > 1000)
{
Console.WriteLine("infinity");
Console.ReadKey();
}
}
for (int i = 0; i < 5000; i++)
{
Console.WriteLine("X = " + coordinates[i, 0] + "," + "Y = " + coordinates[i, 1] + "; ");
}
}
I think whatever you use to display/inspect the value cannot print ∞.
double d = double.MinValue;
d *= 2;
Console.WriteLine($"{d}: IsInfinity: {double.IsNegativeInfinity(d)}");
-∞: IsInfinity: True
Stopping at infinity
Here's a loop that stops at infinity:
double d = 2;
var i = 1;
while(!double.IsInfinity(d))
{
d = i*d*d;
i = -i;
}
Console.WriteLine(d);
-∞
I'm trying to convert C++ code written OpenCV 2.x to Emgu.CV in C#.
I have a function in C++:
cv::Mat computeMatXGradient(const cv::Mat &mat) {
cv::Mat out(mat.rows, mat.cols, CV_64F);
for (int y = 0; y < mat.rows; ++y) {
const uchar* Mr = mat.ptr<uchar>(y);
double* Or = out.ptr<double>(y);
Or[0] = Mr[1] - Mr[0];
for (int x = 1; x < mat.cols - 1; ++x) {
Or[x] = (Mr[x + 1] - Mr[x - 1]) / 2.0;
}
Or[mat.cols - 1] = Mr[mat.cols - 1] - Mr[mat.cols - 2];
}
return out;
}
How to do the same thing in C# with EmguCV efficiently?
So far - I have this C# code:
(I can't test it because a lot of code is missing)
Mat computeMatXGradient(Mat inMat)
{
Mat outMat = new Mat(inMat.Rows, inMat.Cols, DepthType.Cv64F, inMat.NumberOfChannels);
for (int y = 0; y < inMat.Rows; ++y)
{
// unsafe is required if I'm using pointers
unsafe {
byte* Mr = (byte*) inMat.DataPointer;
double* Or = (double*) outMat.DataPointer;
Or[0] = Mr[1] - Mr[0];
for (int x = 1; x < inMat.Cols - 1; ++x)
{
Or[x] = (Mr[x + 1] - Mr[x - 1]) / 2.0;
}
Or[inMat.Cols - 1] = Mr[inMat.Cols - 1] - Mr[inMat.Cols - 2];
}
}
return outMat;
}
Questions:
Is my C# code correct?
Is there better/more efficient way?
You can try converting inMat to an array inM, then calculating the values you need in another array Or, and finally converting the latter array to the output Mat outMat.
Note: I considered NumberOfChannels to be 1 as I think this will be always the case.
Mat computeMatXGradient(Mat inMat)
{
int x, y;
byte[] inM, Mr;
double[] Or;
inM = new byte[(int)inMat.Total];
inMat.CopyTo(inM);
Mr = new byte[inMat.Cols];
Or = new double[inMat.Rows * inMat.Cols];
for (y = 0; y < inMat.Rows; y++)
{
Array.Copy(inM, y * inMat.Cols, Mr, 0, inMat.Cols);
Or[y * inMat.Cols] = Mr[1] - Mr[0];
for (x = 1; x < inMat.Cols - 1; x++)
Or[y * inMat.Cols + x] = (Mr[x + 1] - Mr[x - 1]) / 2.0;
Or[y * inMat.Cols + inMat.Cols - 1] = Mr[inMat.Cols - 1] - Mr[inMat.Cols - 2];
}
Mat outMat = new Mat(inMat.Rows, inMat.Cols, DepthType.Cv64F, 1);
Marshal.Copy(Or, 0, outMat.DataPointer, inMat.Rows * inMat.Cols);
return outMat;
}
Here is save code to do equivalent. Did not test. I checked the OpenCV library to get the structure of Mat. The real structure in OpenCV has a pointer to the data. Instead I made an array of bytes. So if you were loading/writing a OpenCV struct you would need an interface to convert. The output matrix is eight times the input since input is an array of bytes and output is an array double.
The code would be better if there was an input byte[][] and an output double[][].
public class Mat
{
public int flags;
//! the array dimensionality, >= 2
public int dims;
//! the number of rows and columns or (-1, -1) when the array has more than 2 dimensions
public int rows;
public int cols;
//! pointer to the data
public byte[] data;
//! pointer to the reference counter;
// when array points to user-allocated data, the pointer is NULL
public Mat[] refcount;
// other members
public Mat computeMatXGradient(Mat inMat)
{
Mat outMat = new Mat();
outMat.rows = inMat.rows;
outMat.cols = inMat.cols;
outMat.flags = inMat.flags; //include depthType and NumberofChannels
outMat.dims = inMat.dims;
outMat.data = new byte[inMat.rows * inMat.cols * sizeof(Double)];
int outIndex = 0;
byte[] d = new byte[sizeof(double)];
for (int y = 0; y < inMat.rows; ++y)
{
int inRowIndex = y * inMat.cols;
d = BitConverter.GetBytes((double)(inMat.data[inRowIndex + 1] - inMat.data[inRowIndex]));
Array.Copy(d, 0, outMat.data, outIndex, sizeof(double));
outIndex += sizeof(double);
for (int x = 1; x < inMat.cols - 1; ++x)
{
d = BitConverter.GetBytes((double)(inMat.data[inRowIndex + x + 1] - inMat.data[inRowIndex + x - 1]) / 2.0);
Array.Copy(d, 0, outMat.data, outIndex,sizeof(double));
outIndex += sizeof(double);
}
d = BitConverter.GetBytes((double)(inMat.data[inRowIndex + inMat.cols - 1] - inMat.data[inRowIndex - inMat.cols - 2]));
Array.Copy(d, 0, outMat.data, outIndex, sizeof(double));
}
return outMat;
}
}
I am calculating values by using weights and bias from MATLAB trained ANN. trying to code a sigmoid simulation equation, but for some reason C# calculations vary too much than that of MATLAB. i.e. error is too high. I tried to check each step of the equation and found out the specific part that is creating the problem (Emphasized part), but I don't know how to solve this issue, if someone could help, would be a huge favour.
1+(purelin(net.LW{2}×(tansig(net.IW{1}×(1-(abs(2×([inputs]-1)))))+net.b{1}))+net.b{2}))/2
//Normalization of Data
public double Normalization(double x, double xMAx, double xMin)
{
double xNorm = 0.0;
xNorm = (x - xMin) / (xMAx - xMin);
if (xNorm < 0)
xNorm = 0;
if (xNorm > 1)
xNorm = 1;
xNorm = Math.Round(xNorm, 4);
return xNorm;
}
// Equation to calculate ANN based Output Values
public double MetrixCalc(double[] Pn, double[,] W1, double[] W2, double[] b1, double b2, double maxValue, double minValue)
{
double FinalValue = 0;
double[] PnCalc1 = new double[Pn.Length];
double[] PnCalc2 = new double[W1.Length / Pn.Length];
for (int i = 0; i < Pn.Length; i++)
{
PnCalc1[i] = 1 - Math.Abs(2 * (Pn[i] - 1));
}
for (int i = 0; i < (W1.Length / Pn.Length); i++)
{
double PnCalc = 0.0;
for (int j = 0; j < Pn.Length; j++)
{
PnCalc = PnCalc + (W1[i, j] * PnCalc1[j]);
}
PnCalc2[i] = PnCalc;
}
for (int i = 0; i < PnCalc2.Length; i++)
{
//PnCalc2[i] = Math.Tanh(PnCalc2[i] + b1[i]);
PnCalc2[i] = PnCalc2[i] + b1[i];
PnCalc2[i] = 2.0 / (1 + Math.Exp(-2 * (PnCalc2[i]))) - 1;
PnCalc2[i] = Math.Round(PnCalc2[i], 4);
}
double FinalCalc = 0.0;
for (int i = 0; i < PnCalc2.Length; i++)
{
*FinalCalc = FinalCalc + (W2[i] * (PnCalc2[i]));*
//FinalValue = FinalCalc;
}
FinalValue = FinalCalc + b2;
FinalValue = 1 + FinalValue;
FinalValue = (1 + FinalValue) / 2.0;
FinalValue = (FinalValue * (maxValue - minValue)) + minValue;
FinalValue = Math.Round(FinalValue, 4);
FinalValue = Math.Abs(FinalValue);
return FinalValue;
}
Problem is solved.
Problem was with the weights matrix copied from MATLAB. debugging mode saved my life. :)
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]
My algorithm output is wrong. I tried many solutions, but nothing comes out.
View my result.
SourceImage
I'm sorry Lena
for (int x = 1; x < fimage.Bitmap.Width - 1; x++)
{
for (int y = 1; y < fimage.Bitmap.Height - 1; y++)
{
double sumX = 0, sumY = 0, sum = 0;
for ( int i = -1; i <= 1; i++ )
{
for ( int j = -1; j <= 1; j++ )
{
sumX += fimage[y + i, x + j].R * kernel1[i + 1, j + 1];
sumY += fimage[y + i, x + j].R * kernel2[i + 1, j + 1];
}
}
sum = Math.Sqrt(sumX * sumX + sumY * sumY);
sum = sum > 255 ? 255 : sum < 0 ? 0 : sum;
fimage[x, y] = Color.FromArgb((byte)sum, (byte)sum, (byte)sum);
}
}
Two things that are fishy:
for ( int j = -1; j <= 1; j++ )
{
sumX += fimage[y + i, x + j].R * kernel1[i + 1, j + 1];
sumY += fimage[y + i, x + j].R * kernel2[i + 1, j + 1];
}
You only respect the red component of the image here, why is that?
The other major thing is changing the input picture while iterating through it:
sum = Math.Sqrt(sumX * sumX + sumY * sumY);
sum = sum > 255 ? 255 : sum < 0 ? 0 : sum;
fimage[x, y] = Color.FromArgb((byte)sum, (byte)sum, (byte)sum);
You should save the value to a different output image (create a new Bitmap(fimage.Width, fimage.Height) with the dimensions from the source image). That could explain the weird diagonal symmetry in your picture, where there's basically a symteric copy of the other side.