Difficulty in source conversion
I have looked up the internal functions and related documentation supported by the DLL, but I have difficulty finding matching functions or data types.
[Calibration Find value]
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using OpenCvSharp;`
namespace Project_NFT
{
class CalibrateCamera
{
public const string ImageCalibration = "C:\\Users\\JL\\Documents\\Visual Studio 2008\\Projects\\Project NET\\Project NFT\\Image/{0:D2}.jpg";
public CalibrateCamera()
{
const int IMAGE_NUM = 3;
const int PAT_ROW = 7;
const int PAT_COL = 10;
const int PAT_SIZE = PAT_ROW * PAT_COL;
const int ALL_POINTS = IMAGE_NUM * PAT_SIZE;
const float CHESS_SIZE = 24.0f;
CvSize patternSize = new CvSize(PAT_COL, PAT_ROW);
IplImage[] srcImg = new IplImage[IMAGE_NUM];
for (int i = 0; i < IMAGE_NUM; i++)
{
string path = string.Format(ImageCalibration, i);
srcImg[i] = new IplImage(path, LoadMode.Color);
}
CvPoint3D32f[] objects = new CvPoint3D32f[ALL_POINTS];
for (int i = 0; i < IMAGE_NUM; i++)
{
for (int j = 0; j < PAT_ROW; j++)
{
for (int k = 0; k < PAT_COL; k++)
{
objects[(i * PAT_SIZE) + (j * PAT_COL) + k] = new CvPoint3D32f
{
X = j * CHESS_SIZE,
Y = k * CHESS_SIZE,
Z = 0.0f
};
}
}
}
CvMat objectPoints = new CvMat(ALL_POINTS, 3, MatrixType.F32C1, objects);
int foundNum = 0;
List<CvPoint2D32f> allCorners = new List<CvPoint2D32f>(ALL_POINTS);
int[] pCount = new int[IMAGE_NUM];
using (CvWindow window = new CvWindow("Calibration", WindowMode.AutoSize))
{
for (int i = 0; i < IMAGE_NUM; i++)
{
CvPoint2D32f[] corners;
bool found = Cv.FindChessboardCorners(srcImg[i], patternSize, out corners);
Debug.Print("{0:D2}...", i);
if (found)
{
Debug.Print("ok");
foundNum++;
}
else
{
Debug.Print("fail");
}
using (IplImage srcGray = new IplImage(srcImg[i].Size, BitDepth.U8, 1))
{
Cv.CvtColor(srcImg[i], srcGray, ColorConversion.BgrToGray);
Cv.FindCornerSubPix(srcGray, corners, corners.Length, new CvSize(3, 3), new CvSize(-1, -1), new CvTermCriteria(20, 0.03));
Cv.DrawChessboardCorners(srcImg[i], patternSize, corners, found);
pCount[i] = corners.Length;
window.ShowImage(srcImg[i]);
Cv.WaitKey(0);
}
allCorners.AddRange(corners);
}
if (foundNum != IMAGE_NUM)
{
Debug.Assert(false);
}
}
CvMat imagePoints = new CvMat(ALL_POINTS, 1, MatrixType.F32C2, allCorners.ToArray());
CvMat pointCounts = new CvMat(IMAGE_NUM, 1, MatrixType.S32C1, pCount);
CvMat intrinsic, distortion, rotation, translation;
Cv.CalibrateCamera2(objectPoints, imagePoints, pointCounts, new CvSize(640, 480), out intrinsic, out distortion, out rotation, out translation, CalibrationFlag.Default);
CvMat subImagePoints, subObjectPoints;
Cv.GetRows(imagePoints, out subImagePoints, 0, PAT_SIZE);
Cv.GetRows(objectPoints, out subObjectPoints, 0, PAT_SIZE);
Cv.FindExtrinsicCameraParams2(subObjectPoints, subImagePoints, intrinsic, distortion, out rotation, out translation);
using (CvFileStorage fs = new CvFileStorage("camera.xml", null, FileStorageMode.Write))
{
fs.Write("intrinsic", intrinsic);
fs.Write("rotation", rotation);
fs.Write("translation", translation);
fs.Write("distortion", distortion);
}
foreach (IplImage img in srcImg)
{
img.Dispose();
}
Console.WriteLine(File.ReadAllText("camera.xml"));
Console.Read();
}
}
}
[Calibration Apply Value]
CvMat intrinsic, distortion, extrinsic;
CvFileNode param;
using (CvFileStorage fs = new CvFileStorage("camera.xml", null, FileStorageMode.Read))
{
param = Cv.GetFileNodeByName (fs, null, "intrinsic");
intrinsic = fs.Read<CvMat>(param);
param = Cv.GetFileNodeByName (fs, null, "distortion");
distortion = fs.Read<CvMat>(param);
}
Cv.FindExtrinsicCameraParams2(object_points, image_points,intrinsic, distortion,
out rotation_vector, out translation_vector);
The source is the Camera Calibration reference, which is difficult to convert
Related
I am trying to work out how to use ConvNetShar correctly to learn some shapes in some images. I have test data consisting of black shapes on white backgrounds, all these shapes belong to 1 class (road) and I have a mixture of images with that and without. I have tried to adapt the 2d demo and it does seem to learn but when it tests it fails...
Below is my code...just wondering if anyone has a working example with images?
Thanks
(code just updated) seems to be learning..still failing tests though...
using System;
using System.Collections.Generic;
using ConvNetSharp.Core;
using ConvNetSharp.Core.Layers.Double;
using ConvNetSharp.Core.Training;
using ConvNetSharp.Volume;
using ConvNetSharp.Volume.Double;
using System.IO;
using System.Windows.Forms;
using System.Drawing;
using NDNBackpropNnTrainer;
namespace ClassifyImageDemo
{
internal class Program
{
private static void ClassifyImage()
{
string inputFolder = GetInputFolder();
var filelist = Directory.EnumerateFiles(inputFolder, "*.png");
List<List<double>> matrix = new List<List<double>>();
List<int> expetedList = new List<int>();
int looper = 0;
int width = 1;
int height = 1;
foreach (var fileInImage in filelist)
{
matrix.Add(new List<double>());
Bitmap source = (Bitmap) Image.FromFile(fileInImage);
List<double> innerList = new List<double>();
using (var bmp = new LockBitmap(source))
{
width = bmp.Width;
height = bmp.Height;
for (var y = 0; y < bmp.Height; y++)
{
for (var x = 0; x < bmp.Width; x++)
{
var color = bmp.GetPixel(x, y);
int myR = color.R;
int myG = color.G;
int myB = color.B;
int total = myR + myG + myB;
//Adds new sub List
innerList.Add(total);
}
}
}
matrix[looper]=innerList; //Add values to the sub List at index 0
looper = looper + 1 ;
byte[] myImageRaw = File.ReadAllBytes(fileInImage);
int len = myImageRaw.Length;
var lastOneByte = (byte) myImageRaw[len - 1];
expetedList.Add(lastOneByte);
}
var net = new Net<double>();
net.AddLayer(new InputLayer(1, 1, (width * height)));
net.AddLayer(new FullyConnLayer(6));
net.AddLayer(new TanhLayer());
net.AddLayer(new FullyConnLayer(2));
net.AddLayer(new TanhLayer());
net.AddLayer(new FullyConnLayer(2));
net.AddLayer(new SoftmaxLayer(2));
// Data
var data = new List<double[]>();
var labels = new List<int>();
foreach (var lstInputs in matrix)
{
double[] arrayIn = lstInputs.ToArray();
data.Add(arrayIn);
}
foreach (var lbl in expetedList)
{
labels.Add(lbl);
}
var n = labels.Count;
var trainer = new SgdTrainer<double>(net) { LearningRate = 0.01, L2Decay = 0.001, BatchSize = n };
double loss = 1.0;
// Training
while (loss > 0.00001)
{
loss = ClassifyImageUpdate(width, height, n, data, trainer, labels);
}
// Testing
var netx = BuilderInstance.Volume.From(new double[(width * height) * n], new Shape(1, 1, (width*height), n));
for (var ix = 0; ix < n; ix++)
{
int subLooper2 = 0;
foreach (var dtA2 in data[ix])
{
netx.Set(0, 0, subLooper2, ix, dtA2);
subLooper2 = subLooper2 + 1;
}
}
var result = net.Forward(netx);
var c = net.GetPrediction();
var accurate = c[0] == labels[0];
Console.ReadLine();
}
private static string GetInputFolder()
{
return #"D:\temp\filtered\blackroads\subset_500";
}
private static double ClassifyImageUpdate(int width, int height, int n, List<double[]> data, TrainerBase<double> trainer, List<int> labels)
{
var avloss = 0.0;
int dimensions = width * height;
var netx = BuilderInstance.Volume.SameAs(new Shape(1, 1, dimensions, n));
var hotLabels = BuilderInstance.Volume.SameAs(new Shape(1, 1, 1, n));
for (var ix = 0; ix < n; ix++)
{
hotLabels.Set(0, 0, 0, ix, labels[ix]);
int subLooper = 0;
foreach (var dtA in data[ix])
{
netx.Set(0, 0, subLooper, ix, dtA);
subLooper = subLooper + 1;
}
// netx.Set(0, 0, 1, ix, data[ix][1]);
}
for (var iters = 0; iters < 50; iters++)
{
trainer.Train(netx, hotLabels);
avloss += trainer.Loss;
}
avloss /= 50.0;
Console.WriteLine(" Loss:" + avloss);
return avloss;
}
private static void Main(string[] args)
{
ClassifyImage();
}
}
}
I am trying to simulate how gravity acts on objects in space using 3D xna programming (for a school project). I am calculating the direction and velocities of each of the objects in relation to each other object and turning this into an array of movements. I am then trying to sum up all the movement of each object into one Vector3 and storing this in a one dimensional array. I am able to add up all the movements apart from the last index value in the array.
This is my Gravitation class
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace GravitySimulator
{
class Gravitation
{
static Random Random = new Random();
public Vector3[] positions = new Vector3[3], summovement = new Vector3[3];
public float[,] distance = new float[3, 3], force = new float[4, 4], acceleration = new float[3, 3], velocity = new float[3, 3];
public Vector3[,] dir = new Vector3[3, 3], movement = new Vector3[3, 3];
public double G, mass;
public void GenerateVectors()
{
for (int vectors = 0; vectors < positions.Length; vectors++)
{
positions[vectors] = new Vector3(Random.Next(-7, 7), Random.Next(-12, 12), Random.Next(-5, 5));
}
}
public void CalculateDistance()
{
for (int j = 0; j < positions.Length; j++)
{
for (int i = 0; i < positions.Length; i++)
{
distance[j, i] = Vector3.Distance(positions[j], positions[i]);
}
}
}
public void CalculateForce()
{
G = 6.67 * Math.Pow(10, -11);
mass = 1;
for (int k = 0; k < positions.Length; k++)
{
for (int l = 0; l < positions.Length; l++)
{
force[k, l] = (float)((G * mass * mass) / Math.Pow(distance[k, l], 2));
}
}
}
public void CalulateAcceleration()
{
for (int m = 0; m < positions.Length; m++)
{
for (int n = 0; n < positions.Length; n++)
{
acceleration[m, n] = (float)(force[m, n] / mass);
}
}
}
public void SummariseMovement()
{
for (int a = 0; a < positions.Length; a++)
{
for (int b = 0; b < positions.Length;b++)
{
summovement[a] = movement[a, b];
}
}
}
}
}
I have a function that takes a variable as a parameter and returns a calculated result. That function splits up into other functions each doing their own calculation. I need the function to run multi threaded.
My code:
for (int i = 0; i < pic.Width; i++)
{
for (int k = 0; k < pic.Height; k++)
{
var localK = k;
var localI = i;
Image bestPic;
new Thread(() =>
{
bestPic = new Bitmap(getBestPic(argb));//THIS IS WHERE THE WRONG VALUES ARE ASSIGNED BECAUSE OF CROSS THREADING
lock (thisLock)
{
g.DrawImage(bestPic, localI * bestPic.Width, localK * bestPic.Height, bestPic.Width, bestPic.Height);
}
}).Start();
}
}
All I need is the function getBestPic to run multi threaded. But how do I run the function getBestPic multi threaded and make the assigning of the returned result to the bestPic variable atomic?
My entire program if needed: This is a montage program.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Drawing;
namespace test
{
public partial class Form1 : Form
{
private static readonly Object thisLock = new Object();
private Graphics g;
private Bitmap returnImg;
private Bitmap pic;
private int done = 0;
private int pictureWidthAndLength = 200;
private string inputPicName = "test";
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
DateTime dtStart = DateTime.Now;
pic = new Bitmap(inputPicName + ".jpg");
//MessageBox.Show(pic.GetPixel(1,1).ToArgb().ToString());
//MessageBox.Show(pic.Width.ToString() + " x " + pic.Height.ToString());
returnImg = new Bitmap(pic.Width * pictureWidthAndLength, pic.Height * pictureWidthAndLength);
using (g = Graphics.FromImage(returnImg))
{
Color clr;
int[] argb = new int[4];
for (int i = 0; i < pic.Width; i++)
{
for (int k = 0; k < pic.Height; k++)
{
clr = pic.GetPixel(i, k);
argb[0] = clr.A;
argb[1] = clr.R;
argb[2] = clr.G;
argb[3] = clr.B;
var localK = k;
var localI = i;
Image bestPic;
if (cbxthreading.Checked)
{
new Thread(() =>
{
bestPic = new Bitmap(getBestPic(argb));
lock (thisLock)
{
g.DrawImage(bestPic, localI * bestPic.Width, localK * bestPic.Height, bestPic.Width, bestPic.Height);
done++;
}
}).Start();
}
else
{
//Single threaded
bestPic = new Bitmap(getBestPic(argb));
g.DrawImage(bestPic, localI * pictureWidthAndLength, localK * pictureWidthAndLength, pictureWidthAndLength, pictureWidthAndLength);
}
//MessageBox.Show(getBestPic(argb));
}
}
if (cbxthreading.Checked)
{
int loopNum = pic.Width * pic.Height;
while (done < loopNum) { }
}
}
DateTime dtEnd = DateTime.Now;
MessageBox.Show((dtEnd - dtStart).ToString());
}
//Get picture that is best suited to replace pixel
private string getBestPic(int[] argb)
{
int numOfpics = 5;
int[] currentBest = new int[2];
currentBest[0] = 255;
currentBest[1] = 150;
for (int i = 0; i < numOfpics; i++)
{
int compare = compareARGB(getAverageRGB(new Bitmap((i + 1).ToString()+".jpg")), argb);
if (compare < currentBest[0])
{
currentBest[0] = compare;
currentBest[1] = i + 1;
}
}
return currentBest[1].ToString() + ".jpg";
}
// smaller the value, closer the camparison
private int compareARGB(int[] one, int[] two)
{
int [] tmp = new int[4];
tmp[0] = Convert.ToInt32(Math.Abs(one[0] - two[0]));
tmp[1] = Convert.ToInt32(Math.Abs(one[1] - two[1]));
tmp[2] = Convert.ToInt32(Math.Abs(one[2] - two[2]));
tmp[3] = Convert.ToInt32(Math.Abs(one[3] - two[3]));
return (tmp[0] + tmp[1] + tmp[2] + tmp[3]);
}
//return int arry with size 4 containing the argb values
private int[] getAverageRGB(Bitmap img)
{
Color clr;
int aplha = 0;
int red = 0;
int green = 0;
int blue = 0;
for (int i = 0; i < img.Width; i++)
{
for (int k = 0; k < img.Height; k++)
{
clr = img.GetPixel(i, k);
aplha += clr.A;
red += clr.R;
green += clr.G;
blue += clr.B;
}
}
aplha = aplha / (img.Width * img.Height);
red = red / (img.Width * img.Height);
green = green / (img.Width * img.Height);
blue = blue / (img.Width * img.Height);
int[] re = new int[] {aplha,red,green,blue};
return re;
}
private void button2_Click(object sender, EventArgs e)
{
returnImg.Save(inputPicName+".bmp");
MessageBox.Show("Done!");
}
}
}
The single thread functionality works, but takes long. The multi threaded functionality also finishes in a third of the time of the single threaded, but the result is not correct.
getBestPic() method runs multi-thread as I understand. But the problem is the argb parameter. You initialize it ones and then overwrite its values in for loops.argb is reference type, so only the reference is passed to getBestPic(), so it's referenced values get changed while processed in getBestPic().
I would try to pass it by Value or move int[] argb = new int[4];line to the inside of the second for loop, so you every time initialize new variable. More on passing reference type params here.
Just create a copy of the Value of your argb in the getBestPic() method and use it instead of using the original one
private string getBestPic(int[] argb)
{
int[] argbCopy = argb.ToArray();
int numOfpics = 5;
int[] currentBest = new int[2];
currentBest[0] = 255;
currentBest[1] = 150;
for (int i = 0; i < numOfpics; i++)
{
int compare = compareARGB(getAverageRGB(new Bitmap((i + 1).ToString()+".jpg")), argbCopy);
if (compare < currentBest[0])
{
currentBest[0] = compare;
currentBest[1] = i + 1;
}
}
return currentBest[1].ToString() + ".jpg";
}
I have been making a card matching game in C#. It has a 12 card set up (2 of each photo so 6 photos in total) using a picture array, and when you press the cards it finds out if the photos are a match by using another array (a int array with the numbers 1-6 repeated twice, same as the photos) I use this code to randomize the numbers
Image away;
int tagger;
for (int i = 1; i < 13; i++)
{
cards[i].Visible = true;
away = pics[i];
tagger = tags[i];
int h = random.Next(1, 6);
pics[i] = pics[h];
tags[i] = tags[h];
pics[h] = away;
tags[h] = tagger;
}
for (int i = 1; i < 13; i++)
{
cards[i].Image = pics[i];
}
It works for about 4 of the matches, then it says the matches are wrong for the rest... can anyone help?
here is the rest of my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
int a = 0;
PictureBox card = null;
Image[] pics = new Image[13];
int[] tags = new int[13];
PictureBox[] cards = new PictureBox[13];
Random random = new Random();
public Form1()
{
InitializeComponent();
pics[1] = Image.FromFile(#"h:\profile\desktop\game\photos\g1.jpg");
pics[2] = Image.FromFile(#"h:\profile\desktop\game\photos\g1.jpg");
pics[3] = Image.FromFile(#"h:\profile\desktop\game\photos\g2.jpg");
pics[4] = Image.FromFile(#"h:\profile\desktop\game\photos\g2.jpg");
pics[5] = Image.FromFile(#"h:\profile\desktop\game\photos\g3.jpg");
pics[6] = Image.FromFile(#"h:\profile\desktop\game\photos\g3.jpg");
pics[7] = Image.FromFile(#"h:\profile\desktop\game\photos\g4.jpg");
pics[8] = Image.FromFile(#"h:\profile\desktop\game\photos\g4.jpg");
pics[9] = Image.FromFile(#"h:\profile\desktop\game\photos\g5.jpg");
pics[10] = Image.FromFile(#"h:\profile\desktop\game\photos\g5.jpg");
pics[11] = Image.FromFile(#"h:\profile\desktop\game\photos\g6.jpg");
pics[12] = Image.FromFile(#"h:\profile\desktop\game\photos\g6.jpg");
tags[1] = 1;
tags[2] = 1;
tags[3] = 2;
tags[4] = 2;
tags[5] = 3;
tags[6] = 3;
tags[7] = 4;
tags[8] = 4;
tags[9] = 5;
tags[10] = 5;
tags[11] = 6;
tags[12] = 6;
cards[1] = pictureBox1;
cards[2] = pictureBox2;
cards[3] = pictureBox3;
cards[4] = pictureBox4;
cards[5] = pictureBox8;
cards[6] = pictureBox7;
cards[7] = pictureBox6;
cards[8] = pictureBox5;
cards[9] = pictureBox9;
cards[10] = pictureBox10;
cards[11] = pictureBox11;
cards[12] = pictureBox12;
}
private void click_card(object sender, EventArgs e)
{
PictureBox pic = sender as PictureBox;
string s = pic.Name;
string s1 = s.Substring(10);
int num = int.Parse(s1);
if (card == null)
{
card = pic;
a = num;
}
else if (a > 0)
{
int one = tags[a];
int two = tags[num];
if (one == two)
{
System.Windows.Forms.MessageBox.Show("Correct!");
a = 0;
pic.Visible = false;
card.Visible = false;
card = null;
}
else if (one != two)
{
System.Windows.Forms.MessageBox.Show("Wrong!");
card = null;
a = 0;
}
}
}
private void button1_Click(object sender, EventArgs e)
{
Image away;
int tagger;
for (int i = 1; i < 13; i++)
{
cards[i].Visible = true;
away = pics[i];
tagger = tags[i];
int h = random.Next(1, 6);
pics[i] = pics[h];
tags[i] = tags[h];
pics[h] = away;
tags[h] = tagger;
}
for (int i = 1; i < 13; i++)
{
cards[i].Image = pics[i];
}
}
}
}
To comment on your "shuffler".
If cards is your array, then your for loop should start at 0. Arrays are zero based. You have 12 cards, so you'll 0 - 11 indexes. Then you should use the Length property of the array to control your for loop.
When you use random.next(1, 6), you're only generating a random number from 1 - 5. Indexes 0 & 6 - 11, are never being generated, so are never being shuffled.
Lastly, I don't see why you need the extra for loop, just add the assigning of Image to the bottom of your for loop after the swapping.
Image away;
int tagger;
for (int i = 1; i < cards.Length; i++)
{
cards[i].Visible = true;
away = pics[i];
tagger = tags[i];
int h = random.Next(1, cards.Length + 1);
pics[i] = pics[h];
tags[i] = tags[h];
pics[h] = away;
tags[h] = tagger;
cards[i].Image = pics[i];
}
I'm trying to calculate the mahalanobis distance with c#. I can't find any real good examples online and I'm new to C#. I am especially having trouble getting the covariance matrix to run right. Any help would be appreciated. Thanks!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MathNet.Numerics.LinearAlgebra.Double;
namespace MahalanobisDistance
{
class Program
{
static void Main(string[] args)
{
Program p = new Program();
DenseVector vector1 = new DenseVector(4);
DenseVector vector2 = new DenseVector(4);
DenseMatrix matrix1 = new DenseMatrix(vector1.Count/2);
vector1[0] = 1;
vector1[1] = 2;
vector1[2] = 3;
vector1[3] = 4;
vector2[0] = 2;
vector2[1] = 12;
vector2[2] = 14;
vector2[3] = 18;
matrix1 = p.twoPassCovariance(vector1, vector2);
for(int i = 0; i < matrix1.RowCount; i++)
{
for(int k = 0; k < matrix1.ColumnCount; k++)
{
Console.Write(matrix1[k, i] + " ");
}
//Mahalanobis2(v1, v2, covariance);
Console.Write("\n");
}
}
public DenseMatrix twoPassCovariance(DenseVector data1, DenseVector data2)
{
int n = data1.Count;
double mean1 = data1.Average();
double mean2 = data2.Average();
DenseMatrix covariance = new DenseMatrix(data1.Count);
double x;
for(int i = 0; i < 2; i++)
{
for (int k = 0; k < n; k++)
{
double a = data1[i] - mean1;
double b = data2[k] - mean2;
x = a*b;
covariance[i, k] = x;
}
}
covariance.Multiply(1/n);
return covariance;
}
}}
In the i loop in the twoPassCovariance method, I believe you should loop to i < n rather than i < 2.