Reputation: 35
Creating a script using C# and the OxyPlot class. The script will learn to tell the difference between a sunflower image and a dandelion image.
The problem I have is the PlotView of the PlotModel, which I added a Barseries to, does not show any data/bar lines. It does show a PlotView screen but it is empty. Just a white screen . with no axis lines, and I do not know how to fault find where the issue is. I think it has to do with how I am calling the PlotView.
Complete white screen with no data suggests that I am NOT calling the correct form.
I looked at the BarSeries variable and confirmed that is has 100 items attached. The properties with this data is 'Color', which has an oxyPlot color value, 'Value' which has a percentage value as a double datatype (range for this is from 0.0 to a highest of 2.5) and a 'CategoryIndex' which has an int value range from 1 to 100.
I confirmed that the plotModel has one Series count attached, and that the Series has 100 items in it.
What I have done so far is I have collected a small sample frame of bitmap images. Resized then all to 128 x 128. Extracted all the pixel colours to a dictionary format, which allowed me to find the percentage/proportion values of the same color type across all bitmap images. I then passed those values into the Barseries ('Color' of each bar, 'Value' as a double number, 'CategoryIndex' from 1 to 100). BarSeries was added to PlotModel and PlotModel was added to PlotView.
My 'CategoryIndex' flows along the x-axis and 'Value' porportion/percentage flows along the x-axis (Initially tried to use ColumnSeries but that no longer exists). Hence my y-axis and x-axis labels are the opposite to what is the norm.
Tried figuring this out but no luck.
Main method is 'public partial class Form1 : Form' and contains the following code
public void HistogramPlot()
{
Histogram histogram = new Histogram();
Dictionary<Color, Double> colorProportionAllImages = histogram.Compute(_resizedbitmapFlowersArray);
histogram.DisplayColorHistogram(colorProportionAllImages);
histogram.Show();
}
This calls the class 'public class Histogram : Window' which has the following code
using OxyPlot.Axes;
using OxyPlot.Series;
using OxyPlot;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OxyPlot.WindowsForms;
using System.Windows;
using System.Windows.Controls;
using Accord.Statistics.Visualizations;
namespace Sunflower_Recognition
{
public class Histogram : Window
{
public Histogram()
{
// Leave Empty
}
/// <summary>
/// Creating a proportional value of how often the same color value occurred thoughout all bitmap flower images
/// </summary>
/// <param name="colorImagesResized">Bitmap array</param>
/// <returns>Dictionary of all the 'key' color values and a porportional datum of those key color values</returns>
public Dictionary<Color, double> Compute(Bitmap[] colorImagesResized)
{
// Create a Dictionary that will hold a color value 'key' and
// a proportion representation of the color value (number of times that color value has occurred)
Dictionary<Color, double> histogramDictionary = new Dictionary<Color, double>();
// To create a proportion range between 0 to 1 we need to know how many pixels, in total, we will be analysing
int numPixels = colorImagesResized[0].Width * colorImagesResized[0].Height * colorImagesResized.Length;
// Extracting each Bitmap image
foreach (Bitmap image in colorImagesResized)
{
for (int y = 0; y < image.Height; y++)
{
for (int x = 0; x < image.Width; x++)
{
// Extracting each pixel color
Color pixelColor = image.GetPixel(x, y);
// No 'duplicate key values' allowed so we first check for duplicates by
// comparing an actual pixel color value against the existing keys
if (!histogramDictionary.ContainsKey(pixelColor))
{
// No duplicate key exists so we add a new key with default datum of 0.0
histogramDictionary[pixelColor] = 0.0;
}
// Increasing the datum count for that 'key color value' by 1
histogramDictionary[pixelColor] += 1;
}
}
}
// Create a new dictionary to hold the normalized/proportioned histogram data
Dictionary<Color, double> histogramColorProportions = new Dictionary<Color, double>();
// Normalize the histogram by dividing each frequency count by the total number of pixels analysed
foreach (KeyValuePair<Color,double> keyValue in histogramDictionary)
{
// We now get each datum value from each key and alter the number to a proportional percentage value
double proportionValue = (keyValue.Value / numPixels) * 100;
histogramColorProportions.Add(keyValue.Key, proportionValue);
}
return histogramColorProportions;
}
public void DisplayColorHistogram(Dictionary<Color, double> histogramColorProportions)
{
// Create a new plot model
PlotModel plotHistogramModel = new OxyPlot.PlotModel();
// ***************** Axis formation
// Create a new 'category' x-axis for displaying the color keys
// We will display these key 'datum' values on the left side of the plot graph, as a range from 0.0 to 1.0
CategoryAxis colorProportionAxis = new CategoryAxis();
colorProportionAxis.Position = AxisPosition.Bottom;
colorProportionAxis.Title = "Proportion (0 to 1)";
// Create a new value y-axis for the key color values (frequencies) which will be a range from 0 to 255
LinearAxis colorRangeAxis = new LinearAxis();
colorRangeAxis.Position = AxisPosition.Left;
colorRangeAxis.Title = "Color range (0 to 255)";
colorRangeAxis.MinimumPadding = 0;
colorRangeAxis.MaximumPadding = 0.1;
colorRangeAxis.Minimum = 0;
colorRangeAxis.Maximum = 3.0;
// Add the axes to the plot model
plotHistogramModel.Axes.Add(colorProportionAxis);
plotHistogramModel.Axes.Add(colorRangeAxis);
// Create a new column series to represent the color histogram
BarSeries histogramSeries = new BarSeries();
histogramSeries.Title = "Flower colors by proportion";
// Is wil ensure that the columns are stacked side by side
histogramSeries.IsStacked = false;
int indexRange = 0;
// Add data points from this histogram dictionary to the histogram barseries
foreach (KeyValuePair<Color, double> keyValue in histogramColorProportions)
{
// Convert the System.Drawing.Color value (A=255, R=58, G=58, B=58) to OxyColor (ff3a3a3a)
OxyColor oxyColor = OxyColor.FromRgb(keyValue.Key.R, keyValue.Key.G, keyValue.Key.B);
// Add a new data point to the histogram series with the summation as the category index and the frequency as the value
histogramSeries.Items.Add(new BarItem { Color = oxyColor, Value = keyValue.Value, CategoryIndex = indexRange++});
}
System.Windows.MessageBox.Show("Number of Items in 'histogramSeries: " + histogramSeries.Items.Count); // !00 Items
// Add the histogram series to the plot model
plotHistogramModel.Series.Add(histogramSeries);
System.Windows.MessageBox.Show("Number of Series in the PlotModel: " + plotHistogramModel.Series.Count); // 1 series in the plotmodel
// Create a new plot view and set its model to the plot model
PlotView plotView = new OxyPlot.WindowsForms.PlotView();
plotView.Width = 10;
plotView.Height = 800;
plotView.Model = plotHistogramModel;
}
}
}
Upvotes: 0
Views: 200