What command should I use to increase interval between two points? On the graph.
I guess chart. shoul help me but what exactly?
public static void ShowHeatmap(string title, double[,] heat, int xMin, int yMin)
{
var chart = new ZedGraphControl()
{
Dock = DockStyle.Fill
};
var maxHeat = heat.Cast<double>().Max();
chart.GraphPane.Title.Text = title;
chart.GraphPane.YAxis.Title.Text = "Дни";
chart.GraphPane.YAxis.Title.Text = "Месяцы";
var maxSize = Math.Max(heat.GetLength(0), Math.Pow(heat.GetLength(1),2));
for (int x = 0; x < heat.GetLength(0); x++)
for (int y = 0; y < heat.GetLength(1); y++)
{
var value = heat[x, y];
if (value > 1000) throw new ArgumentException("too large heat value " + value);
var color = Color.FromArgb(255, 200, (int)(255 * value / maxHeat), 0);
var lineItem = chart.GraphPane.AddCurve("", new double[] { x + xMin }, new double[] { y + yMin }, color);
lineItem.Symbol.Type = SymbolType.Circle;
lineItem.Symbol.Fill = new Fill(color);
lineItem.Symbol.Size = (float)(6000 * value / maxHeat / maxSize);
}
chart.GraphPane.YAxis.Scale.MaxAuto = true;
chart.GraphPane.YAxis.Scale.MinAuto = true;
chart.AxisChange();
var form = new Form();
form.Text = title;
form.Size = new Size(1920, 1080);
form.Controls.Add(chart);
form.ShowDialog();
Related
A few days ago i switched from tensorflow to fastai for my c# Project. But now i am facing a problem with my normalisation. For both i use an onnx pipeline to load the model and the data.
var onnxPipeline = mLContext.Transforms.ResizeImages(resizing: ImageResizingEstimator.ResizingKind.Fill, outputColumnName: inputName,
imageWidth: ImageSettings.imageWidth, imageHeight: ImageSettings.imageHeight,
inputColumnName: nameof(ImageInputData.Image))
.Append(mLContext.Transforms.ExtractPixels(outputColumnName: inputName, interleavePixelColors: true, scaleImage: 1 / 255f))
.Append(mLContext.Transforms.ApplyOnnxModel(outputColumnName: outputName, inputColumnName: inputName, modelFile: onnxModelPath));
var emptyData = mLContext.Data.LoadFromEnumerable(new List<ImageInputData>());
var onnxModel = onnxPipeline.Fit(emptyData);
with
class ImageInputData
{
[ImageType(ImageSettings.imageHeight, ImageSettings.imageWidth)]
public Bitmap Image { get; set; }
public ImageInputData(byte[] image)
{
using (var ms = new MemoryStream(image))
{
Image = new Bitmap(ms);
}
}
public ImageInputData(Bitmap image)
{
Image = image;
}
}
After using fastai i learned, that the models get better accuracy if the data is normalized with a specific mean and standard deviation (because i used the resnet34 model it should be means { 0.485, 0.456, 0.406 } stds = { 0.229, 0.224, 0.225 } respectively).
So the pixelvalues (for each color ofc.) have to be transformed with those values to match the trainings images. But how can i achive this in C#?
What i tried so far is:
int imageSize = 256;
double[] means = new double[] { 0.485, 0.456, 0.406 }; // used in fastai model
double[] stds = new double[] { 0.229, 0.224, 0.225 };
Bitmap bitmapImage = inputBitmap;
Image image = bitmapImage;
Color[] pixels = new Color[imageSize * imageSize];
for (int x = 0; x < bitmapImage.Width; x++)
{
for (int y = 0; y < bitmapImage.Height; y++)
{
Color pixel = bitmapImage.GetPixel(x, y);
pixels[x + y] = pixel;
double red = (pixel.R - (means[0] * 255)) / (stds[0] * 255); // *255 to scale the mean and std values to the Bitmap
double gre = (pixel.G - (means[1] * 255)) / (stds[1] * 255);
double blu = (pixel.B - (means[2] * 255)) / (stds[2] * 255);
Color pixel_n = Color.FromArgb(pixel.A, (int)red, (int)gre, (int)blu);
bitmapImage.SetPixel(x, y, pixel_n);
}
}
Ofcourse its not working, because the Colorvalues can`t be negative (which i realised only later).
But how can i achive this normalisation between -1 and 1 for my model in C# with the onnx-model?
Is there a different way to feed the model or to handle the normalisation?
Any help would be appreciated!
One way to solve this problem is to switch from an onnx pipeline to an onnx Inferencesession, which is in my view simpler and better to understand:
public List<double> UseOnnxSession(Bitmap image, string onnxModelPath)
{
double[] means = new double[] { 0.485, 0.456, 0.406 };
double[] stds = new double[] { 0.229, 0.224, 0.225 };
using (var session = new InferenceSession(onnxModelPath))
{
List<double> scores = new List<double>();
Tensor<float> t1 = ConvertImageToFloatData(image, means, stds);
List<float> fl = new List<float>();
var inputMeta = session.InputMetadata;
var inputs = new List<NamedOnnxValue>()
{
NamedOnnxValue.CreateFromTensor<float>("input_1", t1)
};
using (var results = session.Run(inputs))
{
foreach (var r in results)
{
var x = r.AsTensor<float>().First();
var y = r.AsTensor<float>().Last();
var softmaxScore = Softmax(new double[] { x, y });
scores.Add(softmaxScore[0]);
scores.Add(softmaxScore[1]);
}
}
return scores;
}
}
// Create your Tensor and add transformations as you need.
public static Tensor<float> ConvertImageToFloatData(Bitmap image, double[] means, double[] std)
{
Tensor<float> data = new DenseTensor<float>(new[] { 1, 3, image.Width, image.Height });
for (int x = 0; x < image.Width; x++)
{
for (int y = 0; y < image.Height; y++)
{
Color color = image.GetPixel(x, y);
var red = (color.R - (float)means[0] * 255) / ((float)std[0] * 255);
var gre = (color.G - (float)means[1] * 255) / ((float)std[1] * 255);
var blu = (color.B - (float)means[2] * 255) / ((float)std[2] * 255);
data[0, 0, x, y] = red;
data[0, 1, x, y] = gre;
data[0, 2, x, y] = blu;
}
}
return data;
}
Also i have to use my own Softmax method on these scores to get the real probabilities out of my model:
public double[] Softmax(double[] values)
{
double[] ret = new double[values.Length];
double maxExp = values.Select(Math.Exp).Sum();
for (int i = 0; i < values.Length; i++)
{
ret[i] = Math.Round((Math.Exp(values[i]) / maxExp), 4);
}
return ret;
}
Hope this helps someone who has a similar Problem.
I am writing a chess game program using windows forms (System.Windows.Forms) and I made a button to start a new game. For some reason the text that the button is supposed to display isn't showing at all. Other than that, the button functions perfectly well.
How Can I fix it?
Code:
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using Chess.Properties;
public class Form1 : Form
{
PictureBox[,] tiles = new PictureBox[8, 8];
Button newGame = new Button();
public Form1()
{
this.MinimumSize = new Size(560, 519);
this.MaximumSize = new Size(560, 519);
newGame.Click += new EventHandler(newGame_Click);
newGame.Size = new Size(560, 519);
newGame.Location = new Point(481, 0);
newGame.Text = "New Game";
newGame.Font = new Font(FontFamily.GenericSansSerif, 24.0f, FontStyle.Bold);
this.Controls.Add(newGame);
for (int x = 0; x < 8; x++)
for (int y = 0; y < 8; y++)
{
tiles[x, y] = new PictureBox();
tiles[x, y].Size = new Size(60, 60);
tiles[x, y].Location = new Point(x * 60, y * 60);
tiles[x, y].Name = "";
this.Controls.Add(tiles[x, y]);
if (x == 0)
if (y % 2 == 0)
tiles[x, y].BackColor = Color.Gray;
else tiles[x, y].BackColor = Color.White;
else if (tiles[x - 1, y].BackColor == Color.Gray)
tiles[x, y].BackColor = Color.White;
else tiles[x, y].BackColor = Color.Gray;
}
}
void newGame_Click(Object sender, EventArgs e)
{
//Initial White Pieces
tiles[0, 0].Image = Resources.wTower;
tiles[0, 1].Image = Resources.wHorse;
tiles[0, 2].Image = Resources.wRunner;
tiles[0, 3].Image = Resources.wQueen;
tiles[0, 4].Image = Resources.wKing;
tiles[0, 5].Image = Resources.wRunner;
tiles[0, 6].Image = Resources.wHorse;
tiles[0, 7].Image = Resources.wTower;
tiles[0, 0].Name = "wTower";
tiles[0, 1].Name = "wHorse";
tiles[0, 2].Name = "wRunner";
tiles[0, 3].Name = "wQueen";
tiles[0, 4].Name = "wKing";
tiles[0, 5].Name = "wRunner";
tiles[0, 6].Name = "wHorse";
tiles[0, 7].Name = "wTower";
for(int i = 0; i < 8; i++)
{
tiles[1, i].Image = Resources.wSoldier;
tiles[1, i].Name = "wSoldier";
}
//Initial Black Pieces
tiles[7, 0].Image = Resources.bTower;
tiles[7, 1].Image = Resources.bHorse;
tiles[7, 2].Image = Resources.bRunner;
tiles[7, 3].Image = Resources.bQueen;
tiles[7, 4].Image = Resources.bKing;
tiles[7, 5].Image = Resources.bRunner;
tiles[7, 6].Image = Resources.bHorse;
tiles[7, 7].Image = Resources.bTower;
tiles[7, 0].Name = "bTower";
tiles[7, 1].Name = "bHorse";
tiles[7, 2].Name = "bRunner";
tiles[7, 3].Name = "bQueen";
tiles[7, 4].Name = "bKing";
tiles[7, 5].Name = "bRunner";
tiles[7, 6].Name = "bHorse";
tiles[7, 7].Name = "bTower";
for (int i = 0; i < 8; i++)
{
tiles[6, i].Image = Resources.bSoldier;
tiles[6, i].Name = "bSoldier";
}
}
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
}
Resources:
My resources
Your button is way to large and you are seeing just the left side portion of it , which excludes the part with the text. Try using this for your button size instead:
newGame.Size = new Size(60, 519);
I have list XY points are including 16000 points, I deployed it to 2 chart type waveform chart and arc graph. I used the class name is VerticalLineAnnotation to design the vertical line on waveform chart and add series chart type line on arc graph to reflect any the last X point of the veritcal line on arc graph. When move the vertical line to left-right, it work very well but when I leave mouse out the line, the charts (waveforma and arc graph) are redraw and take to long time. How can I prevent it (redraw event) or speed up?.
This is source code
ChartArea CA;
Series S1;
VerticalLineAnnotation VA;
double degree = 0;
int test = 0;
Dictionary<int, PointXY> xyMap = new Dictionary<int, PointXY>();
private void DrawGraph(DataTable dtExcel)
{
Series series1 = new Series("Series2");
series1.ChartArea = "ChartArea1";
series1.ChartType = SeriesChartType.Spline;
series1.Color = Color.White;
chart1.ChartAreas["ChartArea1"].AxisY.Minimum = 1000;
chart1.ChartAreas["ChartArea1"].AxisY.Maximum = 4500;
chart1.ChartAreas["ChartArea1"].AxisY.Interval = 500;
chart1.ChartAreas["ChartArea1"].AxisX.Minimum = 0;
chart1.ChartAreas["ChartArea1"].AxisX.Maximum = 16000;
chart1.ChartAreas["ChartArea1"].AxisX.Interval = 1000;
Series series2 = new Series("Series2");
series2.ChartArea = "ChartArea1";
series2.ChartType = SeriesChartType.Spline;
series2.Color = Color.White;
chart2.ChartAreas["ChartArea1"].AxisY.Minimum = -100;
chart2.ChartAreas["ChartArea1"].AxisY.Maximum = 100;
chart2.ChartAreas["ChartArea1"].AxisY.Interval = 10;
chart2.ChartAreas["ChartArea1"].AxisX.Minimum = -100;
chart2.ChartAreas["ChartArea1"].AxisX.Maximum = 100;
chart2.ChartAreas["ChartArea1"].AxisX.Interval = 10;
foreach (DataRow item in dtExcel.Rows)
{
series1.Points.AddXY(int.Parse(item[0].ToString()), item[1].ToString());
CaculatePointXY(item, series2);
}
chart1.Series.Add(series1);
chart1.ChartAreas["ChartArea1"].AxisX.MajorGrid.LineColor = Color.Green;
chart1.ChartAreas["ChartArea1"].AxisY.MajorGrid.LineColor = Color.Green;
chart1.ChartAreas["ChartArea1"].AxisX.LabelAutoFitStyle = LabelAutoFitStyles.DecreaseFont;
chart2.Series.Add(series2);
chart2.ChartAreas["ChartArea1"].AxisX.MajorGrid.LineColor = Color.Green;
chart2.ChartAreas["ChartArea1"].AxisY.MajorGrid.LineColor = Color.Green;
chart2.ChartAreas["ChartArea1"].AxisX.LabelAutoFitStyle = LabelAutoFitStyles.DecreaseFont;
//Draw vertical line
CA = chart1.ChartAreas["ChartArea1"];
VA = new VerticalLineAnnotation();
VA.AxisX = CA.AxisX;
VA.AllowMoving = true;
VA.IsInfinitive = true;
VA.ClipToChartArea = CA.Name;
VA.Name = "myLine";
VA.LineColor = Color.Red;
VA.LineWidth = 2; // use your numbers!
VA.X = 8000;
chart1.Annotations.Add(VA);
chart2.Series.Add("Line");
chart2.Series["Line"].Points.Add(new DataPoint(0, 0));
chart2.Series["Line"].Color = Color.Red;
chart2.Series["Line"].BorderWidth = 2;
chart2.Series["Line"].Points.Add(new DataPoint(0, 100));
chart2.Series["Line"].ChartType = SeriesChartType.Line;
}
private void CaculatePointXY(DataRow item, Series series2)
{
double distance = (int.Parse(item[1].ToString()) - 819) * 0.0030525;
distance += 95;
double x = distance * Math.Cos((degree * Math.PI / 180));
double y = distance * Math.Sin((degree * Math.PI / 180));
series2.Points.AddXY(x, y);
xyMap.Add(int.Parse(item[0].ToString()), new PointXY()
{
X = x,
Y = y
});
degree += 0.0225;
}
private void chart1_Customize(object sender, EventArgs e)
{
foreach (var label in chart1.ChartAreas[0].AxisY.CustomLabels)
{
label.Text = ((int)double.Parse(label.Text) / 100).ToString();
}
foreach (var label in chart1.ChartAreas[0].AxisX.CustomLabels)
{
label.Text = ((int)double.Parse(label.Text) / 100).ToString();
}
}
private void chart1_MouseDoubleClick(object sender, MouseEventArgs e)
{
var xVal = chart1.ChartAreas[0].AxisX.PixelPositionToValue(e.X);
var yVal = chart1.ChartAreas[0].AxisY.PixelPositionToValue(e.Y);
ZoomWaveFormGraph(xVal, yVal);
}
private void ZoomWaveFormGraph(double xVal, double yVal)
{
ZoomArcGraph((int)xVal);
var YMin = Math.Round(yVal - 1000, 0);
var YMax = Math.Round(yVal + 1000, 0);
chart1.ChartAreas["ChartArea1"].AxisY.Minimum = YMin;
chart1.ChartAreas["ChartArea1"].AxisY.Maximum = YMax;
chart1.ChartAreas["ChartArea1"].AxisY.Interval = 100;
var XMin = Math.Round(xVal - 1000, 0);
var XMax = Math.Round(xVal + 1000, 0);
chart1.ChartAreas["ChartArea1"].AxisX.Minimum = XMin;
chart1.ChartAreas["ChartArea1"].AxisX.Maximum = XMax;
chart1.ChartAreas["ChartArea1"].AxisX.Interval = 200;
}
private void ZoomArcGraph(double xVal)
{
int a = (int)xVal;
var b = xyMap[a];
chart2.ChartAreas["ChartArea1"].AxisY.Minimum = Math.Round(b.Y - 20, 0);
chart2.ChartAreas["ChartArea1"].AxisY.Maximum = Math.Round(b.Y + 20, 0);
chart2.ChartAreas["ChartArea1"].AxisY.Interval = 2;
chart2.ChartAreas["ChartArea1"].AxisX.Minimum = Math.Round(b.X - 20, 0);
chart2.ChartAreas["ChartArea1"].AxisX.Maximum = Math.Round(b.X + 20, 0);
chart2.ChartAreas["ChartArea1"].AxisX.Interval = 2;
}
private double RadianToDegree(double angle)
{
return angle * (180.0 / Math.PI);
}
private void chart1_AnnotationPositionChanging(object sender, AnnotationPositionChangingEventArgs e)
{
test = (int)Math.Round(e.NewLocationX, 0);
Console.WriteLine("X : " + e.NewLocationX.ToString());
}
private void chart1_AnnotationPositionChanged(object sender, EventArgs e)
{
var a = xyMap[test];
chart2.Series["Line"].Points.ElementAt(1).SetValueXY(a.X, a.Y);
chart2.Refresh();
}
I'm working emgucv project, But I have problem.
I want as a result of this image
I accept the four input coordinates and want to Perspective with a new image.
But my code is impossible...
This is my code:
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
Image<Bgr, byte> image = new Image<Bgr, byte>(#"C:\Users4.jpg");
Bitmap bitImage;
ImageConverter im = new ImageConverter();
int w, h;
int count = 4;
int a = 0;
HomographyMatrix homography;
PointF[] spoint = new PointF[4];
PointF[] dpoint = new PointF[4];
public Form1()
{
InitializeComponent();
}
private void Form1_Shown(object sender, EventArgs e)
{
bitImage = new Bitmap(#"C:\Users4.jpg");
w = bitImage.Width;
h = bitImage.Height;
this.Size = new System.Drawing.Size(w, h);
ibCanvas.BackgroundImage = bitImage;
}
/*
When taking the mouse coordinates being the X and Y axes to the coordinates stored in the Point array.
*/
private void ibCanvas_MouseDown(object sender, MouseEventArgs e)
{
if (count != 0)
{
spoint[a] = new PointF(e.X, e.Y);
a++;
count -= 1;
}
if (count == 0)
{
count = 4;
a = 0;
PointF[] pts1 = new PointF[4];
PointF[] pts2 = new PointF[4];
label1.Text = spoint[0].ToString();
label2.Text = spoint[1].ToString();
label3.Text = spoint[2].ToString();
label4.Text = spoint[3].ToString();
double w1 = Math.Sqrt(Math.Pow(spoint[3].X - spoint[0].X, 2)
+ Math.Pow(spoint[3].X - spoint[0].X, 2));
double w2 = Math.Sqrt(Math.Pow(spoint[2].X - spoint[1].X, 2)
+ Math.Pow(spoint[2].X - spoint[1].X, 2));
double h1 = Math.Sqrt(Math.Pow(spoint[3].Y - spoint[2].Y, 2)
+ Math.Pow(spoint[3].Y - spoint[2].Y, 2));
double h2 = Math.Sqrt(Math.Pow(spoint[0].Y - spoint[1].Y, 2)
+ Math.Pow(spoint[0].Y - spoint[1].Y, 2));
double maxWidth = (w1 < w2) ? w1 : w2;
double maxHeight = (h1 < h2) ? h1 : h2;
dpoint[0].X = 0;
dpoint[0].Y = 0;
dpoint[1].X = 0;
dpoint[1].Y = ((float)maxHeight-1);
dpoint[2].X = ((float)maxWidth - 1); ;
dpoint[2].Y = ((float)maxHeight - 1); ;
dpoint[3].X = ((float)maxWidth - 1); ;
dpoint[3].Y = 0;
homography = CameraCalibration.GetPerspectiveTransform(spoint, dpoint);
Image<Bgr, byte> newImage = image.WarpPerspective(homography, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC, Emgu.CV.CvEnum.WARP.CV_WARP_DEFAULT, new Bgr(0, 0, 0));
CvInvoke.cvShowImage("new Image", newImage);
}
}
}
}
I want really solve this problem
Please Help me!
I'm trying to place a grid of labels on my winforms app. First, I'm populating a list of label objects of size (200 x 50) and then trying to place them so that when x reaches the width of the form (581), I increment y by 50 + 1
Here is my code:
private List<Label> _labels;
private int xOffset = 10;
private int yOffset = 10;
public Form1()
{
InitializeComponent();
_labels = new List<Label>();
for(var i = 0; i <= 20; i++)
_labels.Add(new Label() { Name = "lbl" + i, Height = 50, Width = 200, MinimumSize = new Size(200, 50), BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D, Text = "Label "+i});
// 581, 517
var x = 0;
var y = 0;
foreach (var lbl in _labels)
{
if (x >= 580)
{
x = 0;
y = y + lbl.Height + 2;
lbl.Location = new Point(x, y);
}
this.Controls.Add(lbl);
x += x + lbl.Width;
}
}
It's only placing the even labels from the list on new lines. I'm not sure what I'm doing wrong.
I'm trying to place all of the labels in a grid like design. When one row is full, go to the next row and continue placing labels from the list on that new "row"
You need to move the Location setting code out of the resetting loop:
foreach (var lbl in _labels)
{
if (x >= 580)
{
x = 0;
y = y + lbl.Height + 2;
}
lbl.Location = new Point(x, y);
this.Controls.Add(lbl);
x += lbl.Width;
}
The problematic part is here
x += x + lbl.Width; //+= x
change it to
x += lbl.Width;
Get the
lbl.Location = new Point(x, y);
out of the if statement
if (x >= 580)
{
x = 0;
y = y + lbl.Height + 2;
//lbl.Location = new Point(x, y);
}
lbl.Location = new Point(x, y);
this.Controls.Add(lbl);
x += lbl.Width;
Try this using a Docked FlowLayoutPanel:
public partial class Form1 : Form
{
List<Label> labels;
public Form1()
{
InitializeComponent();
this.labels=new List<Label>();
AddLabelsToFrom(20);
}
void AddLabelsToFrom(int count)
{
for (int i=0; i<count; i++)
{
var lbl=new Label() { Name="lbl"+i, Height=50, Width=200, MinimumSize=new Size(200, 50), BorderStyle=System.Windows.Forms.BorderStyle.Fixed3D, Text="Label "+i };
labels.Add(lbl);
flowLayoutPanel1.Controls.Add(lbl);
}
}
}
void SetGridLabel()
{
for (int i = 0; ; i++)
{
for (int j = 0; ; j++)
{
Label L = new Label();
L.TextAlign = ContentAlignment.MiddleCenter;
L.AutoSize = false;
L.Size = new Size(70, 70);
L.Text = "Test_" + j + "_" + i;
L.Location = new Point(j * L.Size.Width, i * L.Size.Height);
if ((i + 1) * L.Size.Height > this.Size.Height)
return;
if ((j + 1) * L.Size.Width > this.Size.Width)
break;
this.Controls.Add(L);
}
}
}
private List<Label> _labels;
public Form1()
{
InitializeComponent();
_labels = new List<Label>();
for (var i = 0; i <= 20; i++)
_labels.Add(new Label()
{
Name = "lbl" + i, Height = 50,Width = 200,
Size = MinimumSize = new Size(200, 50),
Location = new Point(i * 200 % 600, 50 * (i * 200 / 600)),
BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D,
Text = "Label " + i
});
foreach (var lbl in _labels) this.Controls.Add(lbl);
}