Added median filter but for some reason it always trigger pointer exceptions
This commit is contained in:
@@ -49,6 +49,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Effect.cs" />
|
<Compile Include="Effect.cs" />
|
||||||
<Compile Include="EffectGrayScale.cs" />
|
<Compile Include="EffectGrayScale.cs" />
|
||||||
|
<Compile Include="EffectMedianFilter.cs" />
|
||||||
<Compile Include="Form1.cs">
|
<Compile Include="Form1.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|||||||
+5
-1
@@ -30,7 +30,11 @@ namespace AgraV2
|
|||||||
//I start and stop it so the child can just always use Restart()
|
//I start and stop it so the child can just always use Restart()
|
||||||
Chrono.Start();Chrono.Stop();
|
Chrono.Start();Chrono.Stop();
|
||||||
}
|
}
|
||||||
|
public virtual void populatePannel()
|
||||||
|
{
|
||||||
|
//For the childs to explore
|
||||||
|
ToolBox.Controls.Clear();
|
||||||
|
}
|
||||||
public virtual Bitmap[] apply(Bitmap inputBmp)
|
public virtual Bitmap[] apply(Bitmap inputBmp)
|
||||||
{
|
{
|
||||||
return new Bitmap[] { inputBmp };
|
return new Bitmap[] { inputBmp };
|
||||||
|
|||||||
@@ -0,0 +1,143 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace AgraV2
|
||||||
|
{
|
||||||
|
internal class EffectMedianFilter : Effect
|
||||||
|
{
|
||||||
|
private readonly object balancelock = new object();
|
||||||
|
private int _Radius;
|
||||||
|
|
||||||
|
public int Radius { get => _Radius; set => _Radius = value; }
|
||||||
|
|
||||||
|
public EffectMedianFilter(string name, Panel toolBox) : base(name, toolBox)
|
||||||
|
{
|
||||||
|
//This is just the default value
|
||||||
|
Radius = 1;
|
||||||
|
}
|
||||||
|
public override void populatePannel()
|
||||||
|
{
|
||||||
|
Label label = new Label();
|
||||||
|
label.Text = "Radius : ";
|
||||||
|
|
||||||
|
NumericUpDown nup = new NumericUpDown();
|
||||||
|
nup.Minimum = 1;
|
||||||
|
nup.Maximum = 100;
|
||||||
|
nup.Increment = 1;
|
||||||
|
nup.ValueChanged += nup_ValueChanged;
|
||||||
|
nup.Location = new Point(label.Location.X + label.Width,label.Location.Y);
|
||||||
|
|
||||||
|
ToolBox.Controls.Add(label);
|
||||||
|
ToolBox.Controls.Add(nup);
|
||||||
|
}
|
||||||
|
private void nup_ValueChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is NumericUpDown)
|
||||||
|
{
|
||||||
|
NumericUpDown nup = (NumericUpDown)sender;
|
||||||
|
Radius = (int)nup.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public override Bitmap[] apply(Bitmap inputBmp)
|
||||||
|
{
|
||||||
|
Bitmap[] result = new Bitmap[] { medianFilter(inputBmp) };
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
public unsafe Bitmap medianFilter(Bitmap inputBmp)
|
||||||
|
{
|
||||||
|
Chrono.Restart();
|
||||||
|
|
||||||
|
Size imgSize = new Size(inputBmp.Width,inputBmp.Height);
|
||||||
|
Bitmap result = new Bitmap(imgSize.Width, imgSize.Height);
|
||||||
|
BitmapData resultData = result.LockBits(new Rectangle(0, 0, imgSize.Width, imgSize.Height), ImageLockMode.ReadWrite, inputBmp.PixelFormat);
|
||||||
|
BitmapData inputData = inputBmp.LockBits(new Rectangle(0, 0, imgSize.Width, imgSize.Height), ImageLockMode.ReadWrite, inputBmp.PixelFormat);
|
||||||
|
|
||||||
|
int bytesPerPixel = Bitmap.GetPixelFormatSize(inputBmp.PixelFormat) / 8;
|
||||||
|
int byteCount = resultData.Stride * inputBmp.Height;
|
||||||
|
int offset = resultData.Stride - bytesPerPixel * imgSize.Width;
|
||||||
|
|
||||||
|
lock (balancelock)
|
||||||
|
{
|
||||||
|
byte* resultStartPx = (byte*)resultData.Scan0.ToPointer();
|
||||||
|
byte* resultCursor = resultStartPx;
|
||||||
|
byte* originalStartPx = (byte*)inputData.Scan0.ToPointer();
|
||||||
|
byte* originalCursor = originalStartPx;
|
||||||
|
|
||||||
|
for (int y = 0; y < inputBmp.Height; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < imgSize.Width; x++)
|
||||||
|
{
|
||||||
|
//We wont process border pixels
|
||||||
|
if (x > Radius && y > Radius && x < imgSize.Width - Radius && y < inputBmp.Height - Radius)
|
||||||
|
{
|
||||||
|
List<int> Blues = new List<int>();
|
||||||
|
List<int> Greens = new List<int>();
|
||||||
|
List<int> Reds = new List<int>();
|
||||||
|
|
||||||
|
List<Point> surroundingPixels = getSurroundingPixels(new Point(x, y), 2, imgSize.Width, inputBmp.Height);
|
||||||
|
|
||||||
|
foreach (Point pixel in surroundingPixels)
|
||||||
|
{
|
||||||
|
int relativePosition = (pixel.X) * bytesPerPixel + (pixel.Y * (imgSize.Width * bytesPerPixel + offset));
|
||||||
|
byte* address = (byte*)(relativePosition + originalStartPx);
|
||||||
|
Blues.Add(address[0]);
|
||||||
|
Greens.Add(address[1]);
|
||||||
|
Reds.Add(address[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Blues.Sort();
|
||||||
|
Greens.Sort();
|
||||||
|
Reds.Sort();
|
||||||
|
resultCursor[0] = (byte)Blues[Blues.Count / 2];
|
||||||
|
resultCursor[1] = (byte)Greens[Greens.Count / 2];
|
||||||
|
resultCursor[2] = (byte)Reds[Reds.Count / 2];
|
||||||
|
|
||||||
|
}
|
||||||
|
originalCursor += bytesPerPixel;
|
||||||
|
resultCursor += bytesPerPixel;
|
||||||
|
}
|
||||||
|
//Taking care of the offset
|
||||||
|
originalCursor += offset;
|
||||||
|
resultCursor += offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
result.UnlockBits(resultData);
|
||||||
|
inputBmp.UnlockBits(inputData);
|
||||||
|
|
||||||
|
Chrono.Stop();
|
||||||
|
ProcessingDuration.Add(Chrono.ElapsedMilliseconds / 1000.0);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
public List<Point> getSurroundingPixels(Point centerPoint, int Radius, int imageWidth, int imageHeight)
|
||||||
|
{
|
||||||
|
List<Point> result = new List<Point>();
|
||||||
|
int width = (Radius * 2 + 1);
|
||||||
|
|
||||||
|
Point cursor = centerPoint;
|
||||||
|
|
||||||
|
//we place the cursor on the top left of the matrix
|
||||||
|
cursor = new Point(cursor.X - Radius, cursor.Y - Radius);
|
||||||
|
|
||||||
|
for (int y = 0; y < width; y++)
|
||||||
|
{
|
||||||
|
//This scans top to bottom
|
||||||
|
for (int x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
//This scans left to right
|
||||||
|
result.Add(cursor);
|
||||||
|
cursor = new Point(cursor.X + 1, cursor.Y);
|
||||||
|
}
|
||||||
|
cursor = new Point(cursor.X - (Radius * 2 + 1), cursor.Y + 1);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Generated
+40
-39
@@ -31,12 +31,15 @@
|
|||||||
this.pbxOriginal = new System.Windows.Forms.PictureBox();
|
this.pbxOriginal = new System.Windows.Forms.PictureBox();
|
||||||
this.gpbx1 = new System.Windows.Forms.GroupBox();
|
this.gpbx1 = new System.Windows.Forms.GroupBox();
|
||||||
this.groupBox2 = new System.Windows.Forms.GroupBox();
|
this.groupBox2 = new System.Windows.Forms.GroupBox();
|
||||||
|
this.lblTimer1 = new System.Windows.Forms.Label();
|
||||||
this.btnDowload1 = new System.Windows.Forms.Button();
|
this.btnDowload1 = new System.Windows.Forms.Button();
|
||||||
this.pbxResult1 = new System.Windows.Forms.PictureBox();
|
this.pbxResult1 = new System.Windows.Forms.PictureBox();
|
||||||
this.groupBox3 = new System.Windows.Forms.GroupBox();
|
this.groupBox3 = new System.Windows.Forms.GroupBox();
|
||||||
|
this.lblTimer2 = new System.Windows.Forms.Label();
|
||||||
this.btnDownload2 = new System.Windows.Forms.Button();
|
this.btnDownload2 = new System.Windows.Forms.Button();
|
||||||
this.pbxResult2 = new System.Windows.Forms.PictureBox();
|
this.pbxResult2 = new System.Windows.Forms.PictureBox();
|
||||||
this.groupBox4 = new System.Windows.Forms.GroupBox();
|
this.groupBox4 = new System.Windows.Forms.GroupBox();
|
||||||
|
this.lblTimer3 = new System.Windows.Forms.Label();
|
||||||
this.btnDownload3 = new System.Windows.Forms.Button();
|
this.btnDownload3 = new System.Windows.Forms.Button();
|
||||||
this.pbxResult3 = new System.Windows.Forms.PictureBox();
|
this.pbxResult3 = new System.Windows.Forms.PictureBox();
|
||||||
this.gpbxFiles = new System.Windows.Forms.GroupBox();
|
this.gpbxFiles = new System.Windows.Forms.GroupBox();
|
||||||
@@ -47,9 +50,6 @@
|
|||||||
this.lsbEffects = new System.Windows.Forms.ListBox();
|
this.lsbEffects = new System.Windows.Forms.ListBox();
|
||||||
this.groupBox6 = new System.Windows.Forms.GroupBox();
|
this.groupBox6 = new System.Windows.Forms.GroupBox();
|
||||||
this.pnlEffectToolbox = new System.Windows.Forms.Panel();
|
this.pnlEffectToolbox = new System.Windows.Forms.Panel();
|
||||||
this.lblTimer1 = new System.Windows.Forms.Label();
|
|
||||||
this.lblTimer2 = new System.Windows.Forms.Label();
|
|
||||||
this.lblTimer3 = new System.Windows.Forms.Label();
|
|
||||||
((System.ComponentModel.ISupportInitialize)(this.pbxOriginal)).BeginInit();
|
((System.ComponentModel.ISupportInitialize)(this.pbxOriginal)).BeginInit();
|
||||||
this.gpbx1.SuspendLayout();
|
this.gpbx1.SuspendLayout();
|
||||||
this.groupBox2.SuspendLayout();
|
this.groupBox2.SuspendLayout();
|
||||||
@@ -95,6 +95,18 @@
|
|||||||
this.groupBox2.TabStop = false;
|
this.groupBox2.TabStop = false;
|
||||||
this.groupBox2.Text = "Result 1";
|
this.groupBox2.Text = "Result 1";
|
||||||
//
|
//
|
||||||
|
// lblTimer1
|
||||||
|
//
|
||||||
|
this.lblTimer1.AutoSize = true;
|
||||||
|
this.lblTimer1.BackColor = System.Drawing.Color.Black;
|
||||||
|
this.lblTimer1.ForeColor = System.Drawing.Color.Green;
|
||||||
|
this.lblTimer1.Location = new System.Drawing.Point(6, 25);
|
||||||
|
this.lblTimer1.Name = "lblTimer1";
|
||||||
|
this.lblTimer1.Size = new System.Drawing.Size(54, 20);
|
||||||
|
this.lblTimer1.TabIndex = 2;
|
||||||
|
this.lblTimer1.Text = "0.00s";
|
||||||
|
this.lblTimer1.Visible = false;
|
||||||
|
//
|
||||||
// btnDowload1
|
// btnDowload1
|
||||||
//
|
//
|
||||||
this.btnDowload1.Location = new System.Drawing.Point(44, 247);
|
this.btnDowload1.Location = new System.Drawing.Point(44, 247);
|
||||||
@@ -127,6 +139,18 @@
|
|||||||
this.groupBox3.TabStop = false;
|
this.groupBox3.TabStop = false;
|
||||||
this.groupBox3.Text = "Result 2";
|
this.groupBox3.Text = "Result 2";
|
||||||
//
|
//
|
||||||
|
// lblTimer2
|
||||||
|
//
|
||||||
|
this.lblTimer2.AutoSize = true;
|
||||||
|
this.lblTimer2.BackColor = System.Drawing.Color.Black;
|
||||||
|
this.lblTimer2.ForeColor = System.Drawing.Color.Green;
|
||||||
|
this.lblTimer2.Location = new System.Drawing.Point(6, 25);
|
||||||
|
this.lblTimer2.Name = "lblTimer2";
|
||||||
|
this.lblTimer2.Size = new System.Drawing.Size(54, 20);
|
||||||
|
this.lblTimer2.TabIndex = 3;
|
||||||
|
this.lblTimer2.Text = "0.00s";
|
||||||
|
this.lblTimer2.Visible = false;
|
||||||
|
//
|
||||||
// btnDownload2
|
// btnDownload2
|
||||||
//
|
//
|
||||||
this.btnDownload2.Location = new System.Drawing.Point(44, 247);
|
this.btnDownload2.Location = new System.Drawing.Point(44, 247);
|
||||||
@@ -159,6 +183,18 @@
|
|||||||
this.groupBox4.TabStop = false;
|
this.groupBox4.TabStop = false;
|
||||||
this.groupBox4.Text = "Result3";
|
this.groupBox4.Text = "Result3";
|
||||||
//
|
//
|
||||||
|
// lblTimer3
|
||||||
|
//
|
||||||
|
this.lblTimer3.AutoSize = true;
|
||||||
|
this.lblTimer3.BackColor = System.Drawing.Color.Black;
|
||||||
|
this.lblTimer3.ForeColor = System.Drawing.Color.Green;
|
||||||
|
this.lblTimer3.Location = new System.Drawing.Point(6, 25);
|
||||||
|
this.lblTimer3.Name = "lblTimer3";
|
||||||
|
this.lblTimer3.Size = new System.Drawing.Size(54, 20);
|
||||||
|
this.lblTimer3.TabIndex = 4;
|
||||||
|
this.lblTimer3.Text = "0.00s";
|
||||||
|
this.lblTimer3.Visible = false;
|
||||||
|
//
|
||||||
// btnDownload3
|
// btnDownload3
|
||||||
//
|
//
|
||||||
this.btnDownload3.Location = new System.Drawing.Point(44, 247);
|
this.btnDownload3.Location = new System.Drawing.Point(44, 247);
|
||||||
@@ -237,6 +273,7 @@
|
|||||||
this.lsbEffects.Name = "lsbEffects";
|
this.lsbEffects.Name = "lsbEffects";
|
||||||
this.lsbEffects.Size = new System.Drawing.Size(188, 204);
|
this.lsbEffects.Size = new System.Drawing.Size(188, 204);
|
||||||
this.lsbEffects.TabIndex = 4;
|
this.lsbEffects.TabIndex = 4;
|
||||||
|
this.lsbEffects.SelectedIndexChanged += new System.EventHandler(this.lsbEffects_SelectedIndexChanged);
|
||||||
//
|
//
|
||||||
// groupBox6
|
// groupBox6
|
||||||
//
|
//
|
||||||
@@ -255,42 +292,6 @@
|
|||||||
this.pnlEffectToolbox.Size = new System.Drawing.Size(188, 250);
|
this.pnlEffectToolbox.Size = new System.Drawing.Size(188, 250);
|
||||||
this.pnlEffectToolbox.TabIndex = 2;
|
this.pnlEffectToolbox.TabIndex = 2;
|
||||||
//
|
//
|
||||||
// lblTimer1
|
|
||||||
//
|
|
||||||
this.lblTimer1.AutoSize = true;
|
|
||||||
this.lblTimer1.BackColor = System.Drawing.Color.Black;
|
|
||||||
this.lblTimer1.ForeColor = System.Drawing.Color.Green;
|
|
||||||
this.lblTimer1.Location = new System.Drawing.Point(6, 25);
|
|
||||||
this.lblTimer1.Name = "lblTimer1";
|
|
||||||
this.lblTimer1.Size = new System.Drawing.Size(54, 20);
|
|
||||||
this.lblTimer1.TabIndex = 2;
|
|
||||||
this.lblTimer1.Text = "0.00s";
|
|
||||||
this.lblTimer1.Visible = false;
|
|
||||||
//
|
|
||||||
// lblTimer2
|
|
||||||
//
|
|
||||||
this.lblTimer2.AutoSize = true;
|
|
||||||
this.lblTimer2.BackColor = System.Drawing.Color.Black;
|
|
||||||
this.lblTimer2.ForeColor = System.Drawing.Color.Green;
|
|
||||||
this.lblTimer2.Location = new System.Drawing.Point(6, 25);
|
|
||||||
this.lblTimer2.Name = "lblTimer2";
|
|
||||||
this.lblTimer2.Size = new System.Drawing.Size(54, 20);
|
|
||||||
this.lblTimer2.TabIndex = 3;
|
|
||||||
this.lblTimer2.Text = "0.00s";
|
|
||||||
this.lblTimer2.Visible = false;
|
|
||||||
//
|
|
||||||
// lblTimer3
|
|
||||||
//
|
|
||||||
this.lblTimer3.AutoSize = true;
|
|
||||||
this.lblTimer3.BackColor = System.Drawing.Color.Black;
|
|
||||||
this.lblTimer3.ForeColor = System.Drawing.Color.Green;
|
|
||||||
this.lblTimer3.Location = new System.Drawing.Point(6, 25);
|
|
||||||
this.lblTimer3.Name = "lblTimer3";
|
|
||||||
this.lblTimer3.Size = new System.Drawing.Size(54, 20);
|
|
||||||
this.lblTimer3.TabIndex = 4;
|
|
||||||
this.lblTimer3.Text = "0.00s";
|
|
||||||
this.lblTimer3.Visible = false;
|
|
||||||
//
|
|
||||||
// Form1
|
// Form1
|
||||||
//
|
//
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
|
||||||
|
|||||||
+9
-1
@@ -25,7 +25,7 @@ namespace AgraV2
|
|||||||
{
|
{
|
||||||
effects = new List<Effect>();
|
effects = new List<Effect>();
|
||||||
effects.Add(new EffectGrayScale("GrayScale", pnlEffectToolbox));
|
effects.Add(new EffectGrayScale("GrayScale", pnlEffectToolbox));
|
||||||
|
effects.Add(new EffectMedianFilter("Median Filter", pnlEffectToolbox));
|
||||||
RefreshUi();
|
RefreshUi();
|
||||||
}
|
}
|
||||||
private void RefreshUi()
|
private void RefreshUi()
|
||||||
@@ -143,5 +143,13 @@ namespace AgraV2
|
|||||||
{
|
{
|
||||||
DownloadImage(pbxResult3.Image);
|
DownloadImage(pbxResult3.Image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void lsbEffects_SelectedIndexChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (lsbEffects.SelectedIndex >= 0)
|
||||||
|
{
|
||||||
|
effects[lsbEffects.SelectedIndex].populatePannel();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user