I created a class that I called "Descripteurs". I want to call this class to create a csv file. So I have called my list of descriptors created in the class " Descriptors ".
I can't not associate my positions of pixel with descriptors to store it in my csv.
I should have with every pixel in my image the descriptors in the class " Descripteurs"(moyenne, number of black pixel, number of white pixel.....). The csv should have the position in each pixel and all the descriptors calculated in the class "Descripteurs ". I don't know if there is a thread problem or not.
My function is here:
public bool StoreIntoCsv(string pathOriginalPicture, string pathOriginalPictureWithOnlyOneLayer, int classe, BackgroundWorker worker, DoWorkEventArgs e)
{
//preprocessing of the original picture and the original picture with only one layer
Descripteurs featuresPathOriginal = new Descripteurs(new Bitmap(pathOriginalPicture));// m_constructeur de la classe Descripteurs
Bitmap binaryOriginalPictureWithOnlyOneLayer = new Bitmap(pathOriginalPictureWithOnlyOneLayer); // correspond à l'image binaire avec le L.
//we want to get the class of the picture
string[] res = pathOriginalPicture.Split('\\');
string classeName = res[res.Count() - 2]; // count = compter
//retrieving the file path of the csv
string pathFolder = pathOriginalPicture.Split('.').First();// le split divise la chaine en sous chaine en fonction des caractères
pathFolder = pathFolder.Remove(pathFolder.LastIndexOf('\\'));
string pathCsv = pathFolder + "\\" + classeName + ".csv";
libaforge.AForge.IntPoint pixel = new libaforge.AForge.IntPoint();
//open the stream
using (StreamWriter stream = File.AppendText(pathCsv)) //streamwriter permet d'écrire dans un fichier
{
//browse all the picture
for (int x = 0; x < binaryOriginalPictureWithOnlyOneLayer.Width; x = x + 2)
{
for (int y = 0; y < binaryOriginalPictureWithOnlyOneLayer.Height; y = y + 2)
{
//the user stop the application
if (worker.CancellationPending)//checks for cancel request
{
e.Cancel = true;
return false;
}
//we know, where is it the pixel black on the data set training
if (binaryOriginalPictureWithOnlyOneLayer.GetPixel(x, y).ToArgb() == Color.Black.ToArgb())
{
pixel.X = x;
pixel.Y = y;
WriteLineToCsv(pixel, featuresPathOriginal.Extract_Desscripteurs(pixel), classe, stream);
}
}
}
return true;
}
}
My class "Descripteurs is here:
namespace ProjetPRD
{
extern alias libaforge;
public class Descripteurs
{
//private Bitmap _imageLidar;
private static Bitmap image;
public Descripteurs(Bitmap img)
{
image = img;
}
//public static List <double> Extract_Desscripteurs(Bitmap image)
//public static List <double> Extract_Desscripteurs(libaforge.AForge.IntPoint pixel)
public double[] Extract_Desscripteurs(libaforge.AForge.IntPoint pixel)
{
int pixel_Central = 0;
double Moy2_Haut_Gauche = 0;
double Moy3_Haut_Droite = 0;
double Moy4_Bas_Gauche = 0;
double Moy5_Bas_Droite = 0;
int Difference = 0; // pour calculer la difference entre la valeur max et la valeur min de notre masc
int Nb_PNoir_Haut_Gauche = 0;
int Nb_PBlanc_Haut_Gauche = 0;
int Nb_PGris_Haut_Gauche = 0;
int Nb_PNoir_Haut_Droite = 0;
int Nb_PBlanc_Haut_Droite = 0;
int Nb_PGris_Haut_Droite = 0;
int Nb_PNoir_Bas_Gauche = 0;
int Nb_PBlanc_Bas_Gauche = 0;
int Nb_PGris_Bas_Gauche = 0;
int Nb_PNoir_Bas_Droite = 0;
int Nb_PBlanc_Bas_Droite = 0;
int Nb_PGris_Bas_Droite = 0;
List<double> caracteristique = new List <double>();
lock (image )
{
BitmapData bmd = new BitmapData();
try
{
Rectangle Rect = new Rectangle(0, 0, image.Width, image.Height);
bmd = image.LockBits(Rect, ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
//System.Drawing.Imaging.BitmapData bmpData = bmd.LockBits(Rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,bmd.PixelFormat);
unsafe
{
byte* Ptr = (byte*)bmd.Scan0;
for (int j = 0; j < bmd.Height; j++)
{
for (int i = 0; i < bmd.Width; i++)
{
//initialisation des différents éléments du masque 3*3
int couleur1 = Ptr[j * bmd.Width + i];
int couleur2 = Ptr[j * bmd.Width + (i + 1)];
int couleur3 = Ptr[j * bmd.Width + (i + 2)];
int couleur4 = Ptr[(j + 1) * bmd.Width + i];
pixel_Central = Ptr[(j + 1) * bmd.Width + (i + 1)];
int couleur6 = Ptr[(j + 1) * bmd.Width + (i + 2)];
int couleur7 = Ptr[(j + 2) * bmd.Width + (i)];
int couleur8 = Ptr[(j + 2) * bmd.Width + (i + 1)];
int couleur9 = Ptr[(j + 2) * bmd.Width + (i + 2)];
//faire la moyenne de chaque bloc de 4
Moy2_Haut_Gauche = (couleur1 + couleur2 + couleur4 + pixel_Central) / 4;
Moy3_Haut_Droite = (couleur2 + couleur3 + pixel_Central + couleur6) / 4;
Moy4_Bas_Gauche = (couleur4 + pixel_Central + couleur7 + couleur8) / 4;
Moy5_Bas_Droite = (pixel_Central + couleur6 + couleur8 + couleur9) / 4;
//remplir la liste des caractéristiques
caracteristique.Add(pixel_Central);
caracteristique.Add(Moy2_Haut_Gauche);
caracteristique.Add(Moy3_Haut_Droite);
caracteristique.Add(Moy4_Bas_Gauche);
caracteristique.Add(Moy5_Bas_Droite);
int[] tab_Difference = { couleur1, couleur2, couleur3, couleur4, pixel_Central, couleur6, couleur7, couleur8, couleur9 };
Difference = tab_Difference.Max() - tab_Difference.Min();
int[] tab = { couleur1, couleur2, couleur4, pixel_Central };
for (int k = 0; k < tab.Length; k++)
{
if (tab[k] < 60)
{
Nb_PNoir_Haut_Gauche++;
}
else
{
if (tab[k] > 180)
{
Nb_PBlanc_Haut_Gauche++;
}
else
{
Nb_PGris_Haut_Gauche++;
}
}
}
int[] tab2 = { couleur2, couleur3, pixel_Central, couleur6 };
for (int m = 0; m < tab2.Length; m++)
{
if (tab2[m] < 60)
{
Nb_PNoir_Haut_Droite++;
}
else
{
if (tab2[m] > 180)
{
Nb_PBlanc_Haut_Droite++;
}
else
{
Nb_PGris_Haut_Droite++;
}
}
}
int[] tab3 = { couleur4, pixel_Central, couleur7, couleur8 };
for (int n = 0; n < tab3.Length; n++)
{
if (tab3[n] < 60)
{
Nb_PNoir_Bas_Gauche++;
}
else
{
if (tab3[n] > 180)
{
Nb_PBlanc_Bas_Gauche++;
}
else
{
Nb_PGris_Bas_Gauche++;
}
}
}
int[] tab4 = { pixel_Central, couleur6, couleur8, couleur9 };
for (int n = 0; n < tab4.Length; n++)
{
if (tab4[n] < 60)
{
Nb_PNoir_Bas_Droite++;
}
else
{
if (tab4[n] > 180)
{
Nb_PBlanc_Bas_Droite++;
}
else
{
Nb_PGris_Bas_Droite++;
}
}
}
caracteristique.Add(Difference);
caracteristique.Add(Nb_PNoir_Haut_Gauche);
caracteristique.Add(Nb_PNoir_Haut_Droite);
caracteristique.Add(Nb_PNoir_Bas_Gauche);
caracteristique.Add(Nb_PNoir_Bas_Droite);
caracteristique.Add(Nb_PBlanc_Haut_Gauche);
caracteristique.Add(Nb_PBlanc_Haut_Droite);
caracteristique.Add(Nb_PBlanc_Bas_Gauche);
caracteristique.Add(Nb_PBlanc_Bas_Droite);
caracteristique.Add(Nb_PGris_Haut_Gauche);
caracteristique.Add(Nb_PGris_Haut_Droite);
caracteristique.Add(Nb_PGris_Bas_Gauche);
caracteristique.Add(Nb_PGris_Bas_Droite);
}
}
//mesCaracteristiques = caracteristique.ToArray();
}
}
finally
{
image.UnlockBits(bmd);
}
//e.Graphics.DrawImage(bmd, 0, 150);
//return mesCaracteristiques;
return caracteristique.ToArray();
}
}
}
}
I don't know if i was clear with my explication but i really need help.
Related
Lets say a=x+y and b=2x-y and I want to plot a-b=0. I can manually rewrite this from (x+y)-(2x-y)=0 to y=.5x which makes it trivial to graph, but how do I rewrite it in code? Given x how do I calculate y if all I have is (x+y)-(2x-y)=0?
To be more specific, I am trying to graph the decision boundary of a neural network. I want to be able to change the layers and outputs at will, essentially changing the function I get as an output.
This is an example of an output I could get:
(x_1 w_2 + x_2 w_2 + b_1) w_7
+ (x_1 w_3 + x_2 w_4 + b_2) w_8
+ (x_1 w_5 + x_2 w_6 + b_3) w_9
+ b_4 (x_1 w_1 + x_2 w_2 + b_1) w_10
+ (x_1 w_3 + x_2 w_4 + b_2) w_11
+ (x_1 w_5 + x_2 w_6 + b_3) w_12
+ b_5
It's a 1 by 2 matrix and I know all values except x2 which is the y-axis. In order to draw the decision boundary I have to calculate a-b=0 where a and b both contain x and y. I can manually separate y to get y=... ,but that's not an option if the results in the output matrix change. How do I seperate/calculate the y?
I am using c# in Unity and passing the points on the graph into the LineRenderer.
Alright, I found the solution the same day of posting the question but had already been messing about for days. It turned out to be a math question after all.
Here's a link to the specific setup for the neural network using a linear activation: https://www.desmos.com/calculator/crmeebqnfb
I manually rewrote the matrix multiplication for this specific setup into a function and was looking for a way to do that for any size and number of invisible layers.
The solution I found is to separate the input matrix into x1 and x2 and separately do the matrix multiplication for them. The x1 value gets the biases added but the x2 doesn't and the first weight matrix has to be split in 2 so x1 can get multiplied with the first row and x2 with the second row.
If you then do the matrix multiplication from there you'll get two 2 matrices like this:
[firstx1answer secondx1answer] [firstx2answer secondx2answer]
And then you can put them into this function:
Edit for better clarification:
Maybe a bit confusing but here's my code. CreateDecisionBoundaryPoints is where this is implemented:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using System.IO;
using System;
[ExecuteAlways]
public class Controller : MonoBehaviour
{
public Transform LineRenderer;
public GameObject textPrefab;
public GameObject pointPrefab;
public Transform weightsUI;
public Transform biasesUI;
[Range(.001f, .1f)] public float delta;
public int numberOfHiddenLayers;
public bool debugWeightMatrices;
public bool debugBiasMatrices;
[HideInInspector] public string[] dataValues;
private void Start()
{
if (Application.isPlaying)
{
//read file
int numberOfLines;
dataValues = ReadData("D:\\Documents\\Unity Projects\\Learning Machine Learning\\Assets\\Data.csv", out numberOfLines);
int numOfOutputNeurons = CreatePointsUI(numberOfLines, dataValues);
//create layerSizes for example [2,3,2]
int[] layerSizes = new int[numberOfHiddenLayers + 2];
layerSizes[0] = (dataValues.Length / numberOfLines) - 1;
layerSizes[numberOfHiddenLayers + 1] = numOfOutputNeurons;
for (int i = 0; i < numberOfHiddenLayers; i++)
{
layerSizes[i+1] = Mathf.Max((dataValues.Length / numberOfLines) - 1, numOfOutputNeurons) + 1;
}
//create the actual matrices
List<float[,]> weights = new List<float[,]>();
List<float[]> biases = new List<float[]>();
MakeTheMatrices(layerSizes, out weights, out biases);
//fill weights with random values
RandomlyFillMatrices(weights);
//print matrices to make sure they're the right size and filled randomly
if (debugWeightMatrices)
Debug.Log(PrintMatrices(weights, "Weight Matrices"));
if (debugBiasMatrices)
Debug.Log(PrintMatrices(biases, "Bias Matrices"));
LineRenderer.GetComponent<DrawDecisionBoundary>().DrawLine(CreateDecisionBoundaryPoints(weights, biases, delta));
}
}
public struct OutputNeuronsAndColours
{
public string value;
public Color color;
public OutputNeuronsAndColours(string value, Color color)
{
this.value = value;
this.color = color;
}
}
public void DoTheWeightsStufUI(int weights)
{
int cwn = 0;
List<Transform> ws = new List<Transform>();
foreach (Transform child in weightsUI)
{
cwn++;
ws.Add(child);
}
int wta = weights - cwn;
for (int i = wta; i < 0; i++)
{
cwn--;
DestroyImmediate(ws[cwn].gameObject);
ws.RemoveAt(cwn);
}
for (int i = wta; i > 0; i--)
{
cwn++;
GameObject weight = Instantiate(textPrefab, weightsUI);
weight.GetComponentInChildren<TMP_Text>().SetText("W" + cwn.ToString());
}
}
public void DoTheBiasesStufUI(int biases)
{
int cbn = 0;
List<Transform> bs = new List<Transform>();
foreach (Transform child in biasesUI)
{
cbn++;
bs.Add(child);
}
int bta = biases - cbn;
for (int i = bta; i < 0; i++)
{
cbn--;
DestroyImmediate(bs[cbn].gameObject);
bs.RemoveAt(cbn);
}
for (int i = bta; i > 0; i--)
{
cbn++;
GameObject bias = Instantiate(textPrefab, biasesUI);
bias.GetComponentInChildren<TMP_Text>().SetText("B" + cbn.ToString());
}
}
string[] ReadData(string path, out int numberOfLines)
{
List<string> data_values = new List<string>();
StreamReader strReader = new StreamReader(path);
bool endOfFile = false;
int numOfLines = 0;
while (!endOfFile)
{
string data_string = strReader.ReadLine();
if (data_string == null)
{
endOfFile = true;
break;
}
else
numOfLines += 1;
data_values.AddRange(data_string.Split(','));
}
numberOfLines = numOfLines;
return data_values.ToArray();
}
int CreatePointsUI(int numberOfLines, string[] dataValues)
{
string[] possibleOutputs = new string[numberOfLines];
for (int i = 0; i < numberOfLines; i++)
{
possibleOutputs[i] = dataValues[(i * (dataValues.Length / numberOfLines)) + ((dataValues.Length / numberOfLines) - 1)];
}
List<OutputNeuronsAndColours> outputNeurons = new List<OutputNeuronsAndColours>(possibleOutputs.Length);
for (int i = 0; i < possibleOutputs.Length; i++)
{
bool contains = false;
for (int x = 0; x < outputNeurons.Count; x++)
{
if (possibleOutputs[i] == outputNeurons[x].value)
contains = true;
}
if (!contains)
outputNeurons.Add(new OutputNeuronsAndColours(possibleOutputs[i], new Color(UnityEngine.Random.Range(0f, 1f), UnityEngine.Random.Range(0f, 1f), UnityEngine.Random.Range(0f, 1f))));
}
for (int i = 0; i < numberOfLines; i++)
{
GameObject point = Instantiate(pointPrefab);
point.transform.position = new Vector2(float.Parse(dataValues[i * (dataValues.Length / numberOfLines)]), float.Parse(dataValues[(i * (dataValues.Length / numberOfLines)) + 1]));
foreach (OutputNeuronsAndColours value in outputNeurons)
{
if (value.value == dataValues[(i * (dataValues.Length / numberOfLines)) + ((dataValues.Length / numberOfLines) - 1)])
point.GetComponent<SpriteRenderer>().color = value.color;
}
}
return outputNeurons.Count;
}
public static void MakeTheMatrices(int[] layerSizes, out List<float[,]> weights, out List<float[]> biases)
{
List<float[,]> tempWeights = new List<float[,]>();
List<float[]> tempBiases = new List<float[]>();
for (int i = 0; i < layerSizes.Length - 1; i++)
{
tempWeights.Add(new float[layerSizes[i], layerSizes[i + 1]]);
}
for (int i = 1; i < layerSizes.Length; i++)
{
List<float> temp = new List<float>();
for (int x = 0; x < layerSizes[i]; x++)
temp.Add(0);
tempBiases.Add(temp.ToArray());
}
weights = tempWeights;
biases = tempBiases;
}
public static void RandomlyFillMatrices(List<float[,]> matrices)
{
foreach (float[,] matrix in matrices)
{
for (int i = 0; i < matrix.GetLength(0); i++)
{
for (int x = 0; x < matrix.GetLength(1); x++)
{
matrix[i, x] = UnityEngine.Random.Range(-3f, 3f);
}
}
}
}
public static string PrintMatrices(List<float[,]> matrices, string name = "Count")
{
string returnString = matrices.Count + " " + name;
foreach (float[,] matrix in matrices)
{
returnString += " (" + matrix.GetLength(0) + ", " + matrix.GetLength(1) + ")";
for (int i = 0; i < matrix.GetLength(0); i++)
{
string log = "";
if (i == 0)
log += "[";
else
log += " ";
for (int x = 0; x < matrix.GetLength(1); x++)
{
log += matrix[i, x];
if(x != matrix.GetLength(1) - 1)
log += " ";
}
if (i == matrix.GetLength(0) - 1)
log += "]";
Debug.Log(log);
}
}
return returnString;
}
public static string PrintMatrices(List<float[]> matrices, string name = "Count")
{
string returnString = matrices.Count + " " + name;
foreach (float[] matrix in matrices)
{
returnString += " (" + matrix.Length + ")";
string log = "[";
for (int i = 0; i < matrix.Length; i++)
{
log += matrix[i];
if (i != matrix.Length - 1)
log += " ";
}
log += "]";
Debug.Log(log);
}
return returnString;
}
private Vector3[] CreateDecisionBoundaryPoints(List<float[,]> weights, List<float[]> biases, float delta)
{
//check whether there are exactly 2 input neurons
if (weights[0].GetLength(0) != 2)
Debug.LogError("Not exactly 2 input neurons!");
//check whether there are exactly 2 output neurons
if (biases[biases.Count - 1].Length != 2)
Debug.LogError("Not exactly 2 output neurons!");
//create the values for the first layer
float[] weightsForFirstLayerX = new float[weights[0].GetLength(1)];
for (int i = 0; i < weights[0].GetLength(1); i++)
{
weightsForFirstLayerX[i] = weights[0][0, i];
}
float[] denominatorValuesFirstLayer = new float[weights[0].GetLength(1)];
for (int i = 0; i < weights[0].GetLength(1); i++)
{
denominatorValuesFirstLayer[i] = weights[0][1, i];
}
List<Vector3> pointsForGraph = new List<Vector3>();
//Calculate the y value(s) for each x with interval delta
for (float x = -.04f; x <= 1 + delta; x += delta)
{
float[] numeratorValuesFirstLayer = new float[weightsForFirstLayerX.Length];
for (int i = 0; i < weightsForFirstLayerX.Length; i++)
numeratorValuesFirstLayer[i] = x * weightsForFirstLayerX[i] + biases[0][i];
//get the row matrices for the decision boundary function
float[] numeratorResults = PassValuesThroughMatrices(numeratorValuesFirstLayer, weights, biases, true);
float[] denominatorResults = PassValuesThroughMatrices(denominatorValuesFirstLayer, weights, biases, false);
float y = (numeratorResults[1] - numeratorResults[0]) / (denominatorResults[0] - denominatorResults[1]);
pointsForGraph.Add(new Vector3(x, y, -1));
}
return pointsForGraph.ToArray();
}
private float[] PassValuesThroughMatrices(float[] values, List<float[,]> weights, List<float[]> biases, bool isNumerator)
{
float[] previousLayer = values;
//loop passing the previous layer values through the current layer: values = values * weights + biases
for (int i = 1; i < weights.Count; i++)
{
float[] temp = new float[weights[i].GetLength(1)];
//loop through the colums in the weight matrix
for (int v = 0; v < weights[i].GetLength(1); v++)
{
float value = 0;
//loop through the rows in the weight matrix
for (int b = 0; b < weights[i].GetLength(0); b++)
value += previousLayer[b] * weights[i][b, v];
if (isNumerator)
value += biases[i][v];
temp[v] = value;
}
previousLayer = temp;
}
//return the last itteration of values
return previousLayer;
}
}
I have an application in Xamarin forms that uses digital persona which I adapted successfully from this code of Android java
The problem is that this app returns only a byte[] array of a fingerprint, so i need to send fid xml to web service so i can compare validate fingers
but i dont know how
heres is the class that i use to parse stream from digital persona to array byte
public class UruImage
{
private static int IMAGE_HEIGHT = 290;
private static int IMAGE_WIDTH = 384;
private static int QUALITY = 75;
private static string LOG_TAG = "U.are.U-Image ";
// Raw data
private short unknown_00;
private byte[] unknown_07 = new byte[9];
private byte[] unknown_2E = new byte[18];
public short num_lines;
public short width;
public sbyte key_number;
public byte[] flags_num_lines = new byte[30];
public byte[] data;
// setter & getter
public void createFromData(ByteBuffer sData) //throws IOException
{
try
{
//tengo duda con lo indices en codigo java esta sData.GetShort(); sin index
sData.Order(ByteOrder.LittleEndian);
unknown_00 = sData.Short;
System.Console.WriteLine(LOG_TAG+" unknown_00: " + Convert.ToString(unknown_00));
width = sData.Short;
System.Console.WriteLine(LOG_TAG+ "width: " + Convert.ToString(width));
num_lines = sData.Short;
System.Console.WriteLine(LOG_TAG+ "num_lines: " + Convert.ToString(num_lines));
key_number = sData.Get();
System.Console.WriteLine(LOG_TAG+ "key_number: " + Convert.ToString(key_number));
sData.Get(unknown_07, 0, 9);
System.Console.WriteLine(LOG_TAG+ "unknown_07: " + bytesToHex(unknown_07));
sData.Get(flags_num_lines, 0, 30);
System.Console.WriteLine(LOG_TAG, "flags_num_lines: " + bytesToHex(flags_num_lines));
sData.Get(unknown_2E, 0, 18);
System.Console.WriteLine(LOG_TAG+ "unknown_2E: " + bytesToHex(unknown_2E));
data = new byte[(num_lines + 1) * width]; // extra line for decoding
sData.Get(data, 0, num_lines * width);
}
catch (Exception ex) {
System.Console.WriteLine(" createFromData " + ex.Message + " " + ex.ToString());
throw new Java.IO.IOException();
}
}
public Byte[] getImageBitmap()
{
try
{
int dataOffset = 0;
int[] pixels = new int[IMAGE_WIDTH * IMAGE_HEIGHT];
int i = 0;
for (int y = 0; y < IMAGE_HEIGHT; y++)
{
for (int x = 0; x < IMAGE_WIDTH; x++)
{
int gray = data[dataOffset + i] & 0xff;
pixels[i] = unchecked((int)0xff000000) | gray << 16 | (gray << 8) | gray;
i++;
}
}
Bitmap bm = Bitmap.CreateBitmap(pixels, IMAGE_WIDTH, IMAGE_HEIGHT, Bitmap.Config.Argb8888);
MemoryStream bs = new MemoryStream();
bm.Compress(Bitmap.CompressFormat.Jpeg, QUALITY, bs);
return bs.ToArray();
}
catch (System.Exception ex) {
System.Console.WriteLine("Get Image bitmap" + ex.Message + " " + ex.StackTrace);
}
return new MemoryStream().ToArray();
}
public byte[] getPgm()
{
return data;
}
public void invert()
{
try
{
int length = width * num_lines;
int i;
//duda con conversion de valor byte max_value = 0xFFFFFFFF;
byte max_value = unchecked((byte)0xFFFFFFFF);
for (i = 0; i < length; i++)
{
data[i] = (byte)(max_value - data[i]);
}
}
catch (System.Exception ex) {
System.Console.WriteLine("Invert "+ex.Message);
}
}
protected static char[] hexArray = "0123456789ABCDEF".ToCharArray();
private static String bytesToHex(byte[] bytes)
{
char[] hexChars = new char[bytes.Length * 2];
for (int j = 0; j < bytes.Length; j++)
{
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[(uint)v >> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
}
I am having issues with the output of the the result of a math calculation. I have a basic average of an array of double and I assign the result to a Label object, using the ToString() method. When I emulate the average, the label shows the correct value of 15.96 for example, but the same average of the same array, on my Galaxy S3 shows 159.6.
Is there anyone who know what's up and what can I do to make the S3 show the correct value?
Thank you all!
EDIT: passing the result to a label and adding the label to the grid:
double result = Math.Round(NP122.DoAverage(parameters), 2);
CustomLabel label = new CustomLabel();
label.ColNo = grid.ColumnDefinitions.IndexOf(c);
label.FontSize = 25;
label.TextColor = Color.Green;
if (result.ToString() == "NaN")
label.Text = "0";
else
label.Text = result.ToString();
label.IsVisible = true;
for (int i = 0; i < numberOfRows.Length + 2; i++) {
if(i == numberOfRows.Length +1)
Grid.SetRow(label, i);
}
Grid.SetColumn(label, grid.ColumnDefinitions.IndexOf(c));
listaRez.Add(label);
foreach (CustomLabel a in listaRez)
{
if (a.ColNo == grid.ColumnDefinitions.IndexOf(c))
{
grid.Children.Add(a);
}
}
EDIT 2: Custom function for NP122.DoAverage:
public static class NP122
{
public static double Vx, sx, Xm, kn, Xkinf, Xksup;
public static double sum;
public static double sumaProvizorie;
public static double[] valoriKn = new double[25];
public static double ValoareCaracteristicaSuperioara(double[] l)
{
Vx = 0;
sx = 0;
Xm = 0;
kn = 0;
Xkinf = 0;
Xksup = 0;
sum = 0;
sumaProvizorie = 0;
valoriKn[0] = 0;
//more here
valoriKn[24] = 0.35;
if (l.Length < 2 )
{
Xksup = 0;
Xkinf = 0;
}
else
{
Xm = (l.Sum()) / (l.Length);
for (int j = 0; j < l.Length; j++)
{
sumaProvizorie = Math.Round(Math.Pow((l[j] - Xm), 2), 2);
sum += sumaProvizorie;
}
kn = valoriKn[l.Length - 1];
double elements = (1.00 / (l.Length - 1));
double putere = sum;
sx = Math.Round(Math.Sqrt(elements * putere), 4);
Vx = sx / Xm;
Xksup = Xm * (1 + kn * Vx);
Xkinf = Xm * (1 - kn * Vx);
}
return Xksup;
I'm trying to output a new image after applying the adaptive median filter but it only works if the maximum window size is 3*3, but it should work for all odd window sizes, and it does so if the image is so small for example 10*10 pixels, but if the image is for example 440*445 pixels it only works if the max window size is 3*3 otherwise it says index outside bounds of the array, here is my code using counting sort to sort the pixels:
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
namespace ImageFilters
{
public class Class2
{
public byte[,] median(byte[,] array, int width, int height, int msize)
{
byte[,] marr = new byte[height + 1, width + 1];
int size = 3;
for (int i = 0; i <height+1; i++)
{
marr[i, 0] = 255;
}
for (int j = 0; j < width+1; j++)
{
marr[0, j] = 255;
}
int n=0;
int z=0;
for (int k = 0; k < (height) * width; k++)
{
repeat:
byte[] farr = new byte[size * size];
int I=0;
for (int i = n; i < n+size; i++)
{
for (int j = z; j < z+size; j++)
{
if (j < width && i < height)
{
farr[I] = array[i, j];
I++;
}
else
{
farr[I] = 0;
I++;
}
}
}
int zxy = farr[(size*size)/2];
byte[] check = new byte[size * size];
check=counting(farr,size);
int median = 0;
int lennn;
lennn = check.Length;
int min = 99999;
int maxi = -1;
int a1, a2;
min = check.Min();
maxi = check.Max();
median = check[lennn / 2];
a1 = median - min;
a2 = maxi - median;
int b1, b2;
b1 = zxy - min;
b2 = maxi - zxy;
if (a1 > 0 && a2 > 0)
{
if (b1 > 0 && b2 > 0)
{
marr[n + 1, z + 1] = Convert.ToByte(zxy);
z++;
if (z + (size - 1) > (width + 1))
{
n++;
z = 0;
}
}
else
{
marr[n + 1, z + 1] = Convert.ToByte(median);
z++;
if (z + (size - 1) > (width + 1))
{
n++;
z = 0;
}
}
}
else
{
size = size + 2;
if (size <= msize)
goto repeat;
else
{
marr[n +1, z +1] = Convert.ToByte(median);
z++;
if (size > 3)
size = 3;
if (z + (size - 1) > (width + 1))
{
n++;
z = 0;
}
}
}
}
return marr;
}
public static byte[] counting(byte[] array1D, int siz)
{
int max = -10000000;
byte[] SortedArray = new byte[siz * siz];
max = array1D.Max();
byte[] Array2 = new byte[max + 1];
//for (int i = 0; i < Array2.Length; i++)
// Array2[i] = 0; // create new array ( Array2) with zeros in every index .
for (int i = 0; i < (siz*siz); i++)
{
Array2[array1D[i]] += 1; //take the element in the index(i) of(array1d) AS the index of (Array2)
// and increment the element in this index by 1 .
}
for (int i = 1; i <= max; i++)
{
Array2[i] += Array2[i - 1]; // Count every element in (array1d) and put it in (Array2).
}
for (int i = (siz*siz) - 1; i >= 0; i--)
{
SortedArray[Array2[array1D[i]] - 1] = array1D[i]; // transfer the element in index (i) of (array1d) to (SortedArray
Array2[array1D[i]]--;
}
return SortedArray;
}
}
}
Any help will be appreciated, thank you.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm trying to create a dungeon generator for a project I've been working on based off of this algorithm. I've gotten everything down, but my array (Fig. 1) doesn't seem to be holding giving the map data for some reason. I'm using three types of data to determine if a cell in the map is either empty (0), a space a character can be on (1), a hallway (2), or a wall (3).
I've gotten a bit stuck on this portion so any help is appreciated!
EDIT: The problem is the map object isn't storing the data in the loop shown in Fig. 1. Sorry for being so vague.
(Fig. 1)
for (int i = 0; i < roomList.Count; i++)
{
for (int x = roomList[i].X; x < (roomList[i].X + roomList[i].W); x++)
{
for (int y = roomList[i].Y; y < (roomList[i].Y + roomList[i].H); y++)
{
map[x, y] = 1;
}
}
}
(All of my relevant code)
namespace Project
{
}
public class Room
{
int xValue, yValue, widthValue, heightValue;
public int X
{
get { return xValue; }
set { xValue = value; }
}
public int Y
{
get { return yValue; }
set { yValue = value; }
}
public int W
{
get { return widthValue; }
set { widthValue = value; }
}
public int H
{
get { return heightValue; }
set { heightValue = value; }
}
}
public class DungeonGenerate
{
public int baseWidth = 513;
public int baseHeight = 513;
public int width = 64;
public int height = 64;
Color[,] arrayColor;
Random rand = new Random();
Room room = new Room();
Rectangle[,] rectMap;
public void Generate()
{
rectMap = new Rectangle[baseWidth, baseHeight];
//Creates a 2-D Array/Grid for the Dungeon
int[,] map = new int[baseWidth, baseHeight];
//Determines all the cells to be empty until otherwise stated
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
map[x, y] = 0;
}
}
//Determines the amount of rooms in the dungeon
int minRooms = (width * height) / 300;
int maxRooms = (width * height) / 150;
int amountOfRooms = rand.Next(minRooms, maxRooms);
//Room dimensions
int widthRoot = Convert.ToInt32(Math.Round(Math.Sqrt(width * 2)));
int heightRoot = Convert.ToInt32(Math.Round(Math.Sqrt(height * 2)));
int minWidth = Convert.ToInt32(Math.Round((width * .5) / widthRoot));
int maxWidth = Convert.ToInt32((width * 2) / widthRoot);
int minHeight = Convert.ToInt32(Math.Round(height * .5) / heightRoot);
int maxHeight = Convert.ToInt32((height * 2) / heightRoot);
//Creates the rooms
List<Room> roomList = new List<Room>(amountOfRooms);
for (int i = 0; i < amountOfRooms; i++)
{
bool ok = false;
do
{
room.X = rand.Next(width);
room.Y = rand.Next(height);
room.W = (rand.Next(maxWidth)) + minWidth;
room.H = (rand.Next(maxHeight)) + minHeight;
if (room.X + room.W >= width && room.Y + room.H >= height)
{
continue;
}
for (int q = 0; q < roomList.Count; q++)
{
if (room.X > roomList[q].X && room.X < roomList[q].X + room.W && room.Y > roomList[q].Y && room.Y < roomList[q].Y + room.H)
{
ok = false;
break;
}
}
ok = true;
roomList.Add(room);
} while (!ok);
}
//This will create hallways that lead to and from the rooms
int connectionCount = roomList.Count;
List<Point> connectedCells = new List<Point>((width * height));
for (int i = 0; i < connectionCount; i++)
{
Room roomA = roomList[i];
int roomNum = i;
while (roomNum == i)
{
roomNum = rand.Next(roomList.Count);
}
Room roomB = roomList[roomNum];
//Increasing this will make the hallway more straight, decreasing it will make the hallway more skewed
int sidestepChance = 10;
Point pointA = new Point(x: (rand.Next(roomA.W)) + roomA.X, y: (rand.Next(roomA.H)) + roomA.Y);
Point pointB = new Point(x: (rand.Next(roomB.W)) + roomB.X, y: (rand.Next(roomB.H)) + roomB.Y);
while (pointA != pointB)
{
int num = rand.Next() * 100;
if (num < sidestepChance)
{
if (pointB.X != pointA.X)
{
if (pointB.X > pointA.X)
{
pointB.X--;
}
else
{
pointB.X++;
}
}
}
else if(pointB.Y != pointA.Y)
{
if (pointB.Y > pointA.Y)
{
pointB.Y--;
}
else
{
pointB.Y++;
}
}
}
if (pointB.X < width && pointB.Y < height)
{
connectedCells.Add(pointB);
}
}
//Fills the room with data
for (int i = 0; i < roomList.Count; i++)
{
for (int x = roomList[i].X; x < (roomList[i].X + roomList[i].W); x++)
{
for (int y = roomList[i].Y; y < (roomList[i].Y + roomList[i].H); y++)
{
map[x, y] = 1;
}
}
}
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if (map[x, y] == 0)
{
bool wall = false;
for (int yy = y - 2; yy < y + 2; yy++)
{
for (int xx = x - 2; xx < x + 2; xx++)
{
if (xx > 0 && yy > 0 && xx < width && yy < height)
{
if (map[xx, yy] == 1 || map[xx, yy] == 2)
{
map[x, y] = 3;
wall = true;
}
}
}
if (wall)
{
break;
}
}
}
}
}
//Rendering the Map and giving it some Color (Sort of)!
int scaler = baseWidth / width;
for (int x = 0; x < baseWidth; x++)
{
for (int y = 0; y < baseHeight; y++)
{
rectMap[x, y] = new Rectangle(x, y, 1, 1);
arrayColor = new Color[baseWidth, baseHeight];
switch (map[x, y])
{
case 0:
arrayColor[x, y] = new Color(0,0,0);
break;
case 1:
arrayColor[x, y] = new Color(0,0,0);
break;
case 2:
arrayColor[x, y] = new Color(0,0,0);
break;
case 3:
arrayColor[x, y] = new Color (0,0,0);
break;
}
}
}
}
public Rectangle[,] GetMap()
{
return rectMap;
}
public Color[,] GetColors()
{
return arrayColor;
}
}
In the for-loop where you're populating roomList, you're not instantiating a new Room each time. You're simply manipulating the same Room object and re-adding it to the list, so roomList will just contain many references to the same Room object. Try removing the room field from your DungeonGenerate class and use a local variable instead:
for (int i = 0; i < amountOfRooms; i++)
{
bool ok = false;
do
{
var room = new Room();
...
roomList.Add(room);
} while (!ok);
}