├── .gitignore
├── SeamCarving
├── Images
│ └── Desert_VerySimpleLandscape.jpg
├── SeamCarving
│ ├── Properties
│ │ ├── Settings.settings
│ │ ├── Settings.Designer.cs
│ │ ├── AssemblyInfo.cs
│ │ ├── Resources.Designer.cs
│ │ └── Resources.resx
│ ├── Program.cs
│ ├── Form1.cs
│ ├── Form1.Designer.cs
│ ├── SeamCarving.csproj
│ ├── Form1.resx
│ └── BitmapHelper.cs
└── SeamCarving.sln
└── StringMatching
├── StringMatching.sln
├── TestProject
├── Properties
│ └── AssemblyInfo.cs
├── PatternMatchingTest.cs
├── StringDiffTests.cs
└── TestProject.csproj
└── StringMatching
├── Properties
└── AssemblyInfo.cs
├── StringMatching.csproj
├── StringMatcher.cs
└── StringDiff.cs
/.gitignore:
--------------------------------------------------------------------------------
1 | _ReSharper*
2 | *.resharper*
3 | bin
4 | obj
5 | *.suo
6 | *.zip
7 | *.cache
8 | *.user
--------------------------------------------------------------------------------
/SeamCarving/Images/Desert_VerySimpleLandscape.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jcbozonier/Dynamic-Programming-Sample/master/SeamCarving/Images/Desert_VerySimpleLandscape.jpg
--------------------------------------------------------------------------------
/SeamCarving/SeamCarving/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SeamCarving/SeamCarving/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Windows.Forms;
5 |
6 | namespace SeamCarving
7 | {
8 | static class Program
9 | {
10 | ///
11 | /// The main entry point for the application.
12 | ///
13 | [STAThread]
14 | static void Main()
15 | {
16 | Application.EnableVisualStyles();
17 | Application.SetCompatibleTextRenderingDefault(false);
18 | Application.Run(new Form1());
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/SeamCarving/SeamCarving.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 10.00
3 | # Visual Studio 2008
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SeamCarving", "SeamCarving\SeamCarving.csproj", "{2E88758B-7B19-4151-8EFC-F9DDA5972FF1}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|Any CPU = Debug|Any CPU
9 | Release|Any CPU = Release|Any CPU
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {2E88758B-7B19-4151-8EFC-F9DDA5972FF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
13 | {2E88758B-7B19-4151-8EFC-F9DDA5972FF1}.Debug|Any CPU.Build.0 = Debug|Any CPU
14 | {2E88758B-7B19-4151-8EFC-F9DDA5972FF1}.Release|Any CPU.ActiveCfg = Release|Any CPU
15 | {2E88758B-7B19-4151-8EFC-F9DDA5972FF1}.Release|Any CPU.Build.0 = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/SeamCarving/SeamCarving/Form1.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Windows.Forms;
9 |
10 | namespace SeamCarving
11 | {
12 | public partial class Form1 : Form
13 | {
14 | public Form1()
15 | {
16 | InitializeComponent();
17 | var bitmap = new Bitmap(@"C:\Code\DynamicProgramming\SeamCarving\Images\Desert_VerySimpleLandscape.jpg");
18 | var newImage = ImagerBitmap.LaplaceGreyscale(bitmap);
19 | var bounds = new Rectangle(Point.Empty, newImage.Size);
20 |
21 | var imageEneryMatrix = new List>(bounds.Width);
22 |
23 | foreach(var xIndex in Enumerable.Range(0, bounds.Width))
24 | {
25 | var yIndexVector = new List();
26 | imageEneryMatrix.Add(yIndexVector);
27 | foreach(var yIndex in Enumerable.Range(0, bounds.Height))
28 | {
29 | yIndexVector.Add(newImage.GetPixel(xIndex, yIndex).GetBrightness());
30 | }
31 | }
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/SeamCarving/SeamCarving/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:2.0.50727.3053
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace SeamCarving.Properties
12 | {
13 |
14 |
15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")]
17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
18 | {
19 |
20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
21 |
22 | public static Settings Default
23 | {
24 | get
25 | {
26 | return defaultInstance;
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/StringMatching/StringMatching.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 10.00
3 | # Visual Studio 2008
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StringMatching", "StringMatching\StringMatching.csproj", "{7B62224E-B789-47EC-ACCA-DA37FA43A591}"
5 | EndProject
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestProject", "TestProject\TestProject.csproj", "{385C369E-1F02-4DC2-986C-ADBBA4C5AC47}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {7B62224E-B789-47EC-ACCA-DA37FA43A591}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {7B62224E-B789-47EC-ACCA-DA37FA43A591}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {7B62224E-B789-47EC-ACCA-DA37FA43A591}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {7B62224E-B789-47EC-ACCA-DA37FA43A591}.Release|Any CPU.Build.0 = Release|Any CPU
18 | {385C369E-1F02-4DC2-986C-ADBBA4C5AC47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {385C369E-1F02-4DC2-986C-ADBBA4C5AC47}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {385C369E-1F02-4DC2-986C-ADBBA4C5AC47}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {385C369E-1F02-4DC2-986C-ADBBA4C5AC47}.Release|Any CPU.Build.0 = Release|Any CPU
22 | EndGlobalSection
23 | GlobalSection(SolutionProperties) = preSolution
24 | HideSolutionNode = FALSE
25 | EndGlobalSection
26 | EndGlobal
27 |
--------------------------------------------------------------------------------
/SeamCarving/SeamCarving/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("SeamCarving")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("SeamCarving")]
13 | [assembly: AssemblyCopyright("Copyright © 2009")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("de12b6bd-1a6f-4a73-b48a-01ab92560128")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/StringMatching/TestProject/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("TestProject")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("TestProject")]
13 | [assembly: AssemblyCopyright("Copyright © 2009")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("09b066ee-7539-44a2-824c-75bf745cd043")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/StringMatching/StringMatching/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("StringMatching")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("StringMatching")]
13 | [assembly: AssemblyCopyright("Copyright © 2009")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("5cab46f4-d926-4980-862b-7e989d3a408c")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/StringMatching/TestProject/PatternMatchingTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using NUnit.Framework;
6 | using StringMatching;
7 |
8 | namespace TestProject
9 | {
10 | [TestFixture]
11 | public class Simple_strings
12 | {
13 | [Test]
14 | public void Simplest_strings_both_match()
15 | {
16 | Assert.IsTrue(StringMatcher.IsMatch("a", "a"));
17 | }
18 |
19 | [Test]
20 | public void Simplest_strings_neither_match()
21 | {
22 | Assert.IsFalse(StringMatcher.IsMatch("a", "z"));
23 | }
24 |
25 | [Test]
26 | public void Simplest_strings_simplest_pattern_matches()
27 | {
28 | Assert.IsTrue(StringMatcher.IsMatch(".", "z"));
29 | }
30 |
31 | [Test]
32 | public void Simplest_strings_simplest_pattern_asterisk_matches()
33 | {
34 | Assert.IsTrue(StringMatcher.IsMatch("*", "z"));
35 | }
36 | }
37 |
38 | [TestFixture]
39 | public class Off_by_one_matchers
40 | {
41 | [Test]
42 | public void String_off_by_one_case_1_matches()
43 | {
44 | Assert.IsTrue(StringMatcher.IsMatch("a.c.e", "abcde"));
45 | }
46 |
47 | [Test]
48 | public void String_off_by_one_case_2_no_match()
49 | {
50 | Assert.IsFalse(StringMatcher.IsMatch("a.c.", "abcde"));
51 | }
52 |
53 | }
54 |
55 | [TestFixture]
56 | public class Off_by_many_matchers
57 | {
58 | [Test]
59 | public void String_off_by_many_case_1_matches()
60 | {
61 | Assert.IsTrue(StringMatcher.IsMatch(".a*.j*", "cadeajmn"));
62 | }
63 |
64 | [Test]
65 | public void String_off_by_many_case_2_no_match()
66 | {
67 | Assert.IsFalse(StringMatcher.IsMatch("a.d*", "abcde"));
68 | }
69 |
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/SeamCarving/SeamCarving/Form1.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace SeamCarving
2 | {
3 | partial class Form1
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.myPicture = new System.Windows.Forms.PictureBox();
32 | ((System.ComponentModel.ISupportInitialize)(this.myPicture)).BeginInit();
33 | this.SuspendLayout();
34 | //
35 | // myPicture
36 | //
37 | this.myPicture.Location = new System.Drawing.Point(12, 12);
38 | this.myPicture.Name = "myPicture";
39 | this.myPicture.Size = new System.Drawing.Size(456, 426);
40 | this.myPicture.TabIndex = 0;
41 | this.myPicture.TabStop = false;
42 | //
43 | // Form1
44 | //
45 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
46 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
47 | this.ClientSize = new System.Drawing.Size(480, 450);
48 | this.Controls.Add(this.myPicture);
49 | this.Name = "Form1";
50 | this.Text = "Form1";
51 | ((System.ComponentModel.ISupportInitialize)(this.myPicture)).EndInit();
52 | this.ResumeLayout(false);
53 |
54 | }
55 |
56 | #endregion
57 |
58 | private System.Windows.Forms.PictureBox myPicture;
59 | }
60 | }
61 |
62 |
--------------------------------------------------------------------------------
/StringMatching/TestProject/StringDiffTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using NUnit.Framework;
6 | using StringMatching;
7 |
8 | namespace TestProject
9 | {
10 | [TestFixture]
11 | public class StringDiffTests
12 | {
13 | [Test]
14 | public void SimplestExecutionPlan()
15 | {
16 | var stringA = "a";
17 | var stringB = "a";
18 |
19 | var diff = new StringDiff();
20 | var executionPlan = diff.Between(stringA, stringB);
21 |
22 | Assert.AreEqual(0, executionPlan.Steps.Count);
23 | }
24 |
25 | [Test]
26 | public void SimplestDiff_Test()
27 | {
28 | var stringA = "a";
29 | var stringB = "b";
30 |
31 | var diff = new StringDiff();
32 | var executionPlan = diff.Between(stringA, stringB);
33 |
34 | Assert.AreEqual(1, executionPlan.Steps.Count);
35 | }
36 |
37 | [Test]
38 | public void MultiItem_Diff_Test()
39 | {
40 | var stringA = "abcba";
41 | var stringB = "bbcbb";
42 |
43 | var diff = new StringDiff();
44 | var executionPlan = diff.Between(stringA, stringB);
45 |
46 | Assert.AreEqual(2, executionPlan.Steps.Count);
47 | }
48 |
49 | [Test]
50 | public void MultiItem_Diff_Assymetrical_Test()
51 | {
52 | var stringA = "desk";
53 | var stringB = "pesticide";
54 |
55 | var diff = new StringDiff();
56 | var executionPlan = diff.Between(stringA, stringB);
57 |
58 | Assert.AreEqual(7, executionPlan.Steps.Count);
59 | }
60 |
61 | [Test]
62 | public void MultiItem_Diff_Horizontal_Assymetrical_Test()
63 | {
64 | var stringA = "bcdeffghi";
65 | var stringB = "abcdefghij";
66 |
67 | var diff = new StringDiff();
68 | var executionPlan = diff.Between(stringA, stringB);
69 |
70 | Assert.AreEqual(3, executionPlan.Steps.Count);
71 | }
72 |
73 | [Test]
74 | public void MultiItem_Diff_Assymetrical_Test_With_Print()
75 | {
76 | var stringA = "desk";
77 | var stringB = "pesticide";
78 |
79 | var diff = new StringDiff();
80 | var executionPlan = diff.Between(stringA, stringB);
81 |
82 | var printedPlan = executionPlan.PrintAllSteps();
83 | Assert.IsNotNullOrEmpty(printedPlan);
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/StringMatching/StringMatching/StringMatching.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 9.0.21022
7 | 2.0
8 | {7B62224E-B789-47EC-ACCA-DA37FA43A591}
9 | Library
10 | Properties
11 | StringMatching
12 | StringMatching
13 | v3.5
14 | 512
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | pdbonly
27 | true
28 | bin\Release\
29 | TRACE
30 | prompt
31 | 4
32 |
33 |
34 |
35 |
36 | 3.5
37 |
38 |
39 | 3.5
40 |
41 |
42 | 3.5
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
60 |
--------------------------------------------------------------------------------
/SeamCarving/SeamCarving/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:2.0.50727.3053
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace SeamCarving.Properties
12 | {
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources
26 | {
27 |
28 | private static global::System.Resources.ResourceManager resourceMan;
29 |
30 | private static global::System.Globalization.CultureInfo resourceCulture;
31 |
32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
33 | internal Resources()
34 | {
35 | }
36 |
37 | ///
38 | /// Returns the cached ResourceManager instance used by this class.
39 | ///
40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
41 | internal static global::System.Resources.ResourceManager ResourceManager
42 | {
43 | get
44 | {
45 | if ((resourceMan == null))
46 | {
47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SeamCarving.Properties.Resources", typeof(Resources).Assembly);
48 | resourceMan = temp;
49 | }
50 | return resourceMan;
51 | }
52 | }
53 |
54 | ///
55 | /// Overrides the current thread's CurrentUICulture property for all
56 | /// resource lookups using this strongly typed resource class.
57 | ///
58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
59 | internal static global::System.Globalization.CultureInfo Culture
60 | {
61 | get
62 | {
63 | return resourceCulture;
64 | }
65 | set
66 | {
67 | resourceCulture = value;
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/StringMatching/TestProject/TestProject.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 9.0.21022
7 | 2.0
8 | {385C369E-1F02-4DC2-986C-ADBBA4C5AC47}
9 | Library
10 | Properties
11 | TestProject
12 | TestProject
13 | v3.5
14 | 512
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | pdbonly
27 | true
28 | bin\Release\
29 | TRACE
30 | prompt
31 | 4
32 |
33 |
34 |
35 |
36 |
37 | 3.5
38 |
39 |
40 | 3.5
41 |
42 |
43 | 3.5
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | {7B62224E-B789-47EC-ACCA-DA37FA43A591}
56 | StringMatching
57 |
58 |
59 |
60 |
67 |
--------------------------------------------------------------------------------
/StringMatching/StringMatching/StringMatcher.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace StringMatching
7 | {
8 | public class StringMatcher
9 | {
10 | private const string _OffByOneLiteral = ".";
11 | private const string _OffByManyLiteral = "*";
12 |
13 | public static bool IsMatch(string pattern, string str)
14 | {
15 | var patternMatrix = _GetPatternMatrix(pattern, str);
16 |
17 | return _HasCompletePath(patternMatrix, pattern.Length-1, str.Length-1, pattern);
18 | }
19 |
20 | private static bool _HasCompletePath(IList> matrix, int patternIndex, int stringIndex, string pattern)
21 | {
22 | var result = false;
23 |
24 | if(patternIndex < 0 || stringIndex < 0)
25 | return false;
26 |
27 | if (patternIndex == 0 && stringIndex == 0 && matrix[patternIndex][stringIndex])
28 | {
29 | result = true;
30 | }
31 | else if(matrix[patternIndex][stringIndex])
32 | {
33 | var tempResult = _HasCompletePath(matrix, patternIndex - 1, stringIndex - 1, pattern);
34 | if(!tempResult && _HasCompletePath(matrix, patternIndex, stringIndex-1, pattern) && pattern[patternIndex] == '*')
35 | {
36 | tempResult = true;
37 | }
38 | result |= tempResult;
39 | }
40 |
41 | return result;
42 | }
43 |
44 | private static List> _GetPatternMatrix(string pattern, string str)
45 | {
46 | var patternMatrix = new List>(pattern.Length);
47 | for (var i = 0; i < pattern.Length; i++)
48 | patternMatrix.Add(new List(str.Length));
49 |
50 | //First fill out table
51 | foreach(var patternIndex in Enumerable.Range(0, pattern.Length))
52 | {
53 | var patternCharacter = pattern[patternIndex];
54 |
55 | var isLiteralMatch = patternCharacter != '*' && patternCharacter != '.';
56 | foreach(var stringIndex in Enumerable.Range(0, str.Length))
57 | {
58 | var stringCharacter = str[stringIndex];
59 |
60 | if(isLiteralMatch)
61 | {
62 | patternMatrix[patternIndex].Add(_IsMatch(patternCharacter, stringCharacter));
63 | }
64 | else
65 | {
66 | patternMatrix[patternIndex].Add(true);
67 | }
68 |
69 | }
70 | }
71 | return patternMatrix;
72 | }
73 |
74 | private static bool _IsMatch(char pattern, char str)
75 | {
76 | if (pattern == '*')
77 | return true;
78 | if(pattern == '.')
79 | return true;
80 | if(pattern == str)
81 | return true;
82 |
83 | return false;
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/SeamCarving/SeamCarving/SeamCarving.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 9.0.21022
7 | 2.0
8 | {2E88758B-7B19-4151-8EFC-F9DDA5972FF1}
9 | WinExe
10 | Properties
11 | SeamCarving
12 | SeamCarving
13 | v3.5
14 | 512
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 | true
25 |
26 |
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 |
37 | 3.5
38 |
39 |
40 | 3.5
41 |
42 |
43 | 3.5
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | Form
55 |
56 |
57 | Form1.cs
58 |
59 |
60 |
61 |
62 | Form1.cs
63 |
64 |
65 | ResXFileCodeGenerator
66 | Resources.Designer.cs
67 | Designer
68 |
69 |
70 | True
71 | Resources.resx
72 |
73 |
74 | SettingsSingleFileGenerator
75 | Settings.Designer.cs
76 |
77 |
78 | True
79 | Settings.settings
80 | True
81 |
82 |
83 |
84 |
91 |
--------------------------------------------------------------------------------
/SeamCarving/SeamCarving/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/SeamCarving/SeamCarving/Form1.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/StringMatching/StringMatching/StringDiff.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace StringMatching
7 | {
8 | public class StringDiff
9 | {
10 | public StringDeltaExecutionPlan Between(string a, string b)
11 | {
12 | var editDistanceMatrix = _GetDiffMatrix(a, b);
13 | var executionPlan = _CreateExecutionPlan(a, b, editDistanceMatrix);
14 | return executionPlan;
15 | }
16 |
17 | private StringDeltaExecutionPlan _CreateExecutionPlan(string oldString, string newString, List> editDistanceMatrix)
18 | {
19 | var executionPlanBuilder = new StringDeltaExecutionPlan(oldString, newString);
20 |
21 | // String from bottom right corner of the matrix and work our
22 | // way up to the upper left corner.
23 |
24 | var oldStringIndex = oldString.Length - 1;
25 | var newStringIndex = newString.Length - 1;
26 |
27 | var transformedString = oldString.Clone().ToString();
28 |
29 | while (oldStringIndex >= 0 || newStringIndex >= 0)
30 | {
31 | // Deal with current cell
32 |
33 | // Decide how to move.
34 | var leftPathIsValid = oldStringIndex > 0;
35 | var topPathIsValid = newStringIndex > 0;
36 |
37 | if(leftPathIsValid && topPathIsValid)
38 | {
39 | var leftPathValue = editDistanceMatrix[oldStringIndex - 1][newStringIndex];
40 | var topLeftPathValue = editDistanceMatrix[oldStringIndex - 1][newStringIndex - 1];
41 | var topPathValue = editDistanceMatrix[oldStringIndex][newStringIndex - 1];
42 |
43 | if(topLeftPathValue <= leftPathValue && topLeftPathValue <= topPathValue)
44 | {
45 | if(oldString[oldStringIndex] != newString[newStringIndex])
46 | {
47 | executionPlanBuilder.Swap(newStringIndex, oldStringIndex);
48 | }
49 | newStringIndex--;
50 | oldStringIndex--;
51 |
52 | continue;
53 | }
54 |
55 | if(leftPathValue <= topLeftPathValue && leftPathValue <= topPathValue)
56 | {
57 | executionPlanBuilder.Delete(oldStringIndex);
58 | oldStringIndex--;
59 |
60 | continue;
61 | }
62 |
63 | if(topPathValue <= topLeftPathValue && topPathValue <= leftPathValue)
64 | {
65 | executionPlanBuilder.Insert(newStringIndex, oldStringIndex);
66 | newStringIndex--;
67 |
68 | continue;
69 | }
70 | }
71 |
72 | if (leftPathIsValid &&
73 | editDistanceMatrix[oldStringIndex-1][newStringIndex] <= editDistanceMatrix[oldStringIndex][newStringIndex])
74 | {
75 | executionPlanBuilder.Delete(oldStringIndex);
76 | oldStringIndex--;
77 | continue;
78 | }
79 |
80 | if(topPathIsValid &&
81 | editDistanceMatrix[oldStringIndex][newStringIndex-1] <= editDistanceMatrix[oldStringIndex][newStringIndex])
82 | {
83 | executionPlanBuilder.Insert(newStringIndex, oldStringIndex);
84 | newStringIndex--;
85 | continue;
86 | }
87 |
88 | if (!leftPathIsValid && !topPathIsValid)
89 | {
90 | if(!executionPlanBuilder.FirstCharacterEquals(oldString[oldStringIndex]))
91 | {
92 | executionPlanBuilder.Swap(newStringIndex, oldStringIndex);
93 | }
94 | oldStringIndex--;
95 | newStringIndex--;
96 | }
97 | }
98 |
99 | return executionPlanBuilder;
100 | }
101 |
102 | private static List> _GetDiffMatrix(string oldString, string newString)
103 | {
104 | var editDistanceMatrix = new List>(oldString.Length);
105 | for (var i = 0; i < oldString.Length; i++)
106 | editDistanceMatrix.Add(new List(newString.Length));
107 |
108 | //First fill out table
109 | foreach (var oldCharacterIndex in Enumerable.Range(0, oldString.Length))
110 | {
111 | foreach (var newCharacterIndex in Enumerable.Range(0, newString.Length))
112 | {
113 | var editDistanceAtCell = _CalculateMinimumCellEditDistance(editDistanceMatrix, oldString, oldCharacterIndex, newString, newCharacterIndex);
114 |
115 | editDistanceMatrix[oldCharacterIndex].Add(editDistanceAtCell);
116 | }
117 | }
118 |
119 | return editDistanceMatrix;
120 | }
121 |
122 | private static int _CalculateMinimumCellEditDistance(List> matrix, string oldString, int oldCharacterIndex, string newString, int newCharacterIndex)
123 | {
124 | var oldChar = oldString[oldCharacterIndex];
125 | var newChar = newString[newCharacterIndex];
126 |
127 | var localEditDistance = oldChar == newChar ? 0 : 1;
128 |
129 | var leftArrayValue = _GetCellValue(matrix, oldCharacterIndex - 1, newCharacterIndex) + 1;
130 | var topLeftArrayValue = _GetCellValue(matrix, oldCharacterIndex - 1, newCharacterIndex - 1) + localEditDistance;
131 | var topArrayValue = _GetCellValue(matrix, oldCharacterIndex, newCharacterIndex - 1) + 1;
132 |
133 | var minEditDistance = Math.Min(Math.Min(leftArrayValue, topLeftArrayValue), topArrayValue);
134 |
135 | return minEditDistance;
136 | }
137 |
138 | private static int _GetCellValue(List> matrix, int oldCharacterIndex, int newCharacterIndex)
139 | {
140 | if (oldCharacterIndex < 0 && newCharacterIndex < 0)
141 | return 0;
142 | if (oldCharacterIndex < 0)
143 | return newCharacterIndex + 1;
144 | if (newCharacterIndex < 0)
145 | return oldCharacterIndex + 1;
146 | return matrix[oldCharacterIndex][newCharacterIndex];
147 |
148 | }
149 | }
150 |
151 | public class StringDeltaExecutionPlan
152 | {
153 | private string _OldString;
154 | private string _NewString;
155 | public readonly Stack Steps;
156 |
157 | public StringDeltaExecutionPlan(string oldString, string newString)
158 | {
159 | _OldString = oldString;
160 | _NewString = newString;
161 | Steps = new Stack();
162 | }
163 |
164 | public void Swap(int newStringIndex, int oldStringIndex)
165 | {
166 | Steps.Push(new SwapStep(newStringIndex, oldStringIndex));
167 | }
168 |
169 | public void Delete(int oldStringIndex)
170 | {
171 | Steps.Push(new DeleteStep(oldStringIndex));
172 | }
173 |
174 | public void Insert(int newStringIndex, int oldStringIndex)
175 | {
176 | Steps.Push(new InsertStep(oldStringIndex, newStringIndex));
177 | }
178 |
179 | public string PrintStep(int index)
180 | {
181 | var steps = Steps.ToArray();
182 | return steps[index].Print(_OldString, _NewString);
183 | }
184 |
185 | public string PrintAllSteps()
186 | {
187 | var result = "";
188 |
189 | var steps = Steps.ToArray();
190 | foreach(var step in steps)
191 | {
192 | result += step.Print(_OldString, _NewString) + "\n";
193 | }
194 |
195 | return result;
196 | }
197 |
198 | public bool FirstCharacterEquals(char oldCharacter)
199 | {
200 | if(Steps.Count > 0)
201 | {
202 | var firstStep = Steps.First();
203 |
204 | if(firstStep is InsertStep)
205 | {
206 | var insertStep = (InsertStep) firstStep;
207 | if (insertStep._OldStringIndex == 0)
208 | return _NewString[insertStep._NewStringIndex].Equals(oldCharacter);
209 | }
210 | }
211 |
212 | return _NewString[0].Equals(oldCharacter);
213 | }
214 | }
215 |
216 | public class SwapStep : Step
217 | {
218 | public int _NewStringIndex;
219 | public int _OldStringIndex;
220 |
221 | public SwapStep(int newStringIndex, int oldStringIndex)
222 | {
223 | _NewStringIndex = newStringIndex;
224 | _OldStringIndex = oldStringIndex;
225 | }
226 |
227 | public override string Print(string oldString, string newString)
228 | {
229 | return String.Format("Old character \"{0}\" swapped with new character \"{1}\"",
230 | oldString[_OldStringIndex],
231 | newString[_NewStringIndex]);
232 | }
233 | }
234 |
235 | public class DeleteStep : Step
236 | {
237 | private int _OldStringIndex;
238 |
239 | public DeleteStep(int oldStringIndex)
240 | {
241 | _OldStringIndex = oldStringIndex;
242 | }
243 |
244 | public override string Print(string oldString, string newString)
245 | {
246 | return String.Format("Deleted old character \"{0}\"", oldString[_OldStringIndex]);
247 | }
248 | }
249 |
250 | public class InsertStep : Step
251 | {
252 | public int _NewStringIndex;
253 | public int _OldStringIndex;
254 |
255 | public InsertStep(int oldStringIndex, int newStringIndex)
256 | {
257 | _NewStringIndex = newStringIndex;
258 | _OldStringIndex = oldStringIndex;
259 | }
260 |
261 | public override string Print(string oldString, string newString)
262 | {
263 | return String.Format("Inserted new character \"{0}\" at index {1}", newString[_NewStringIndex], _OldStringIndex);
264 | }
265 | }
266 |
267 | public abstract class Step
268 | {
269 | public abstract string Print(string oldString, string newString);
270 | }
271 | }
272 |
--------------------------------------------------------------------------------
/SeamCarving/SeamCarving/BitmapHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System;
6 | using System.Drawing;
7 | using System.Drawing.Imaging;
8 | using System.Drawing.Drawing2D;
9 | using System.IO;
10 |
11 | namespace SeamCarving
12 | {
13 | ///
14 | /// This class provides methods to Resize and Apply Filters to bitmap images.
15 | ///
16 | /// ideas from
17 | /// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp11152001.asp
18 | /// http://www.msnewsgroups.net/group/microsoft.public.dotnet.languages.csharp/topic9351.aspx
19 | ///
20 | public unsafe class ImagerBitmap
21 | {
22 | ///
23 | /// This struct is used to hold the RGB values when we find a pixel using the pointer
24 | ///
25 | private struct PixelData
26 | {
27 | public byte Blue;
28 | public byte Green;
29 | public byte Red;
30 | }
31 | ///
32 | /// This object contains pointer addressable information about the bitmap
33 | ///
34 | private BitmapData _bitmapData = null;
35 | ///
36 | /// The pointer to the upper left corner of the bitmap
37 | ///
38 | private byte* pBase = null;
39 | private Bitmap _bitmap = null;
40 | ///
41 | /// Get the Image we are working with
42 | ///
43 | public Bitmap Bitmap
44 | {
45 | get
46 | {
47 | return _bitmap;
48 | }
49 | }
50 | ///
51 | /// Constructor
52 | ///
53 | /// Bitmap to use as the basis of the Imager
54 | private ImagerBitmap(Bitmap b)
55 | {
56 | if (b.PixelFormat != PixelFormat.Format24bppRgb)
57 | {
58 | //Convert the image into Format24bppRgb since our unmanaged code
59 | //can walk that image type
60 | Bitmap b2 = new Bitmap(b.Size.Width, b.Size.Height, PixelFormat.Format24bppRgb);
61 | Graphics g = Graphics.FromImage(b2);
62 | g.DrawImage(b, new Point(0, 0));
63 | _bitmap = b2;
64 | g.Dispose();
65 | }
66 | else
67 | {
68 | _bitmap = b;
69 | }
70 | LockBitmap();
71 | }
72 | ///
73 | /// Load a pixel with color
74 | ///
75 | /// Column
76 | /// Row
77 | /// Color
78 | private void SetPixel(int x, int y, Color c)
79 | {
80 | PixelData* p = PixelAt(x, y);
81 | p->Red = c.R;
82 | p->Green = c.G;
83 | p->Blue = c.B;
84 | }
85 | ///
86 | /// Get a pixel
87 | ///
88 | /// Column
89 | /// Row
90 | /// Color
91 | private Color GetPixel(int x, int y)
92 | {
93 | PixelData* p = PixelAt(x, y);
94 | return Color.FromArgb((int)p->Red, (int)p->Green, (int)p->Blue);
95 | }
96 | ///
97 | /// Get the Grey value for a give pixel
98 | ///
99 | /// Column
100 | /// Row
101 | /// Grey value for the pixel
102 | private int GetGreyPixel(int column, int row)
103 | {
104 | return (int)((GetPixel(column, row).R * 0.3) + (GetPixel(column, row).G * 0.59)
105 | + (GetPixel(column, row).B * 0.11));
106 | }
107 | ///
108 | /// Use the 2 most signifigant bits from each of the values in the RGB to get an in value
109 | /// for the histogram
110 | ///
111 | /// Column
112 | /// Row
113 | /// Histogram Value
114 | public int GetRGBHistogramValue(int column, int row)
115 | {
116 | Color c = GetPixel(column, row);
117 | int val = 0;
118 | int tmp = 0;
119 | tmp = c.R;
120 | if (tmp - 128 > 0)
121 | {
122 | tmp -= 128;
123 | val += 32;
124 | }
125 | if (tmp - 64 > 0)
126 | {
127 | val += 16;
128 | }
129 | tmp = c.G;
130 | if (tmp - 128 > 0)
131 | {
132 | tmp -= 128;
133 | val += 8;
134 | }
135 | if (tmp - 64 > 0)
136 | {
137 | val += 4;
138 | }
139 | tmp = c.B;
140 | if (tmp - 128 > 0)
141 | {
142 | tmp -= 128;
143 | val += 2;
144 | }
145 | if (tmp - 64 > 0)
146 | {
147 | val += 1;
148 | }
149 | return val;
150 | }
151 | ///
152 | /// Lock the bitmap so we can use the pointers to access it
153 | ///
154 | private void LockBitmap()
155 | {
156 | _bitmapData = _bitmap.LockBits(new Rectangle(0, 0, _bitmap.Width, _bitmap.Height),
157 | ImageLockMode.ReadWrite, _bitmap.PixelFormat);
158 | pBase = (Byte*)_bitmapData.Scan0.ToPointer();
159 | }
160 | ///
161 | /// Get a pointer to a pixel
162 | ///
163 | /// Column
164 | /// Row
165 | ///
166 | private unsafe PixelData* PixelAt(int x, int y)
167 | {
168 | return (PixelData*)(pBase + y * _bitmapData.Stride + x * sizeof(PixelData));
169 | }
170 | ///
171 | /// Unlock the bitmap to end the pointer access session
172 | ///
173 | private void UnlockBitmap()
174 | {
175 | _bitmap.UnlockBits(_bitmapData);
176 | _bitmapData = null;
177 | pBase = null;
178 | }
179 | ///
180 | /// Get a 3x3 matrix of the pixles around the center
181 | ///
182 | /// Center Row
183 | /// Center Column
184 | /// 3x3 matrix of the pixles around the center
185 | private Color[,] Get3x3(int row, int column)
186 | {
187 | Color[,] c = new Color[3, 3];
188 | c[0, 0] = this.GetPixel(column - 1, row - 1);
189 | c[0, 1] = this.GetPixel(column - 1, row);
190 | c[0, 2] = this.GetPixel(column - 1, row + 1);
191 | c[1, 0] = this.GetPixel(column, row - 1);
192 | c[1, 1] = this.GetPixel(column, row);
193 | c[1, 2] = this.GetPixel(column, row + 1);
194 | c[2, 0] = this.GetPixel(column + 1, row - 1);
195 | c[2, 1] = this.GetPixel(column + 1, row);
196 | c[2, 2] = this.GetPixel(column + 1, row + 1);
197 | return c;
198 | }
199 | private int[,] GetGrey3x3(int row, int column)
200 | {
201 | int[,] c = new int[3, 3];
202 | c[0, 0] = this.GetGreyPixel(column - 1, row - 1);
203 | c[0, 1] = this.GetGreyPixel(column - 1, row);
204 | c[0, 2] = this.GetGreyPixel(column - 1, row + 1);
205 | c[1, 0] = this.GetGreyPixel(column, row - 1);
206 | c[1, 1] = this.GetGreyPixel(column, row);
207 | c[1, 2] = this.GetGreyPixel(column, row + 1);
208 | c[2, 0] = this.GetGreyPixel(column + 1, row - 1);
209 | c[2, 1] = this.GetGreyPixel(column + 1, row);
210 | c[2, 2] = this.GetGreyPixel(column + 1, row + 1);
211 | return c;
212 | }
213 | ///
214 | /// Get at 5x5 matrix of the pixels around the center
215 | ///
216 | /// Center Row
217 | /// Center Column
218 | /// 5x5 matrix of pixles around center
219 | private Color[,] Get5x5(int row, int column)
220 | {
221 | Color[,] c = new Color[5, 5];
222 | c[0, 0] = this.GetPixel(column - 2, row - 2);
223 | c[0, 1] = this.GetPixel(column - 2, row - 1);
224 | c[0, 2] = this.GetPixel(column - 2, row);
225 | c[0, 3] = this.GetPixel(column - 2, row + 1);
226 | c[0, 4] = this.GetPixel(column - 2, row + 2);
227 | c[1, 0] = this.GetPixel(column - 1, row - 2);
228 | c[1, 1] = this.GetPixel(column - 1, row - 1);
229 | c[1, 2] = this.GetPixel(column - 1, row);
230 | c[1, 3] = this.GetPixel(column - 1, row + 1);
231 | c[1, 4] = this.GetPixel(column - 1, row + 2);
232 | c[2, 0] = this.GetPixel(column, row - 2);
233 | c[2, 1] = this.GetPixel(column, row - 1);
234 | c[2, 2] = this.GetPixel(column, row);
235 | c[2, 3] = this.GetPixel(column, row + 1);
236 | c[2, 4] = this.GetPixel(column, row + 2);
237 | c[3, 0] = this.GetPixel(column + 1, row - 2);
238 | c[3, 1] = this.GetPixel(column + 1, row - 1);
239 | c[3, 2] = this.GetPixel(column + 1, row);
240 | c[3, 3] = this.GetPixel(column + 1, row + 1);
241 | c[3, 4] = this.GetPixel(column + 1, row + 2);
242 | c[4, 0] = this.GetPixel(column + 2, row - 2);
243 | c[4, 1] = this.GetPixel(column + 2, row - 1);
244 | c[4, 2] = this.GetPixel(column + 2, row);
245 | c[4, 3] = this.GetPixel(column + 2, row + 1);
246 | c[4, 4] = this.GetPixel(column + 2, row + 2);
247 | return c;
248 | }
249 | ///
250 | /// Perform laplace edge detection on the image
251 | ///
252 | /// Source Image
253 | /// Edges
254 | public static Bitmap Laplace(Bitmap b)
255 | {
256 | ImagerBitmap i = new ImagerBitmap(b.Clone() as Bitmap);
257 | ImagerBitmap i2 = new ImagerBitmap(b.Clone() as Bitmap);
258 | for (int column = 1; column < i.Bitmap.Width - 1; column++)
259 | {
260 | for (int row = 1; row < i.Bitmap.Height - 1; row++)
261 | {
262 | Color[,] c = i.Get3x3(row, column);
263 | int red = (((c[0, 0].R + c[0, 1].R + c[0, 2].R + c[1, 0].R + c[1, 2].R + c[2, 0].R
264 | + c[2, 1].R + c[2, 2].R) * -1) + (c[1, 1].R * 8)) + 128;
265 | int green = (((c[0, 0].G + c[0, 1].G + c[0, 2].G + c[1, 0].G + c[1, 2].G
266 | + c[2, 0].G + c[2, 1].G + c[2, 2].G) * -1) + (c[1, 1].G * 8)) + 128;
267 | int blue = (((c[0, 0].B + c[0, 1].B + c[0, 2].B + c[1, 0].B + c[1, 2].B + c[2, 0].B
268 | + c[2, 1].B + c[2, 2].B) * -1) + (c[1, 1].B * 8)) + 128;
269 | if (red >= 128) red = 0; else red = 255;
270 | if (green >= 128) green = 0; else green = 255;
271 | if (blue >= 128) blue = 0; else blue = 255;
272 | i2.SetPixel(column, row, Color.FromArgb(red, green, blue));
273 | }
274 | }
275 | i.UnlockBitmap();
276 | i2.UnlockBitmap();
277 | return i2.Bitmap.Clone() as Bitmap;
278 | }
279 | public static Bitmap LaplaceGreyscale(Bitmap b)
280 | {
281 | ImagerBitmap i = new ImagerBitmap(b.Clone() as Bitmap);
282 | ImagerBitmap i2 = new ImagerBitmap(b.Clone() as Bitmap);
283 | for (int column = 1; column < i.Bitmap.Width - 1; column++)
284 | {
285 | for (int row = 1; row < i.Bitmap.Height - 1; row++)
286 | {
287 | int[,] c = i.GetGrey3x3(row, column);
288 | int val = (((c[0, 0] + c[0, 1] + c[0, 2] + c[1, 0] + c[1, 2] + c[2, 0] + c[2, 1]
289 | + c[2, 2]) * -1) + (c[1, 1] * 8)) + 128;
290 | if (val >= 128) val = 0; else val = 255;
291 | i2.SetPixel(column, row, Color.FromArgb(val, val, val));
292 | }
293 | }
294 | i.UnlockBitmap();
295 | i2.UnlockBitmap();
296 | return i2.Bitmap.Clone() as Bitmap;
297 | }
298 |
299 | ///
300 | /// Subtract b2 from b1 and normalize the image
301 | ///
302 | /// Image
303 | /// Image
304 | /// Normalized Image
305 | public static Bitmap Subtract(Bitmap b1, Bitmap b2)
306 | {
307 | if (b1.Width != b2.Width || b1.Height != b2.Height)
308 | throw new Exception("Images not the same size cannot subtract");
309 | ImagerBitmap i = new ImagerBitmap(b1.Clone() as Bitmap);
310 | ImagerBitmap i2 = new ImagerBitmap(b2.Clone() as Bitmap);
311 | int[,] red = new int[i.Bitmap.Width, i.Bitmap.Height];
312 | int[,] blue = new int[i.Bitmap.Width, i.Bitmap.Height];
313 | int[,] green = new int[i.Bitmap.Width, i.Bitmap.Height];
314 | int redMax = 0;
315 | int redMin = 0;
316 | int redRange = 0;
317 | int blueMax = 0;
318 | int blueMin = 0;
319 | int blueRange = 0;
320 | int greenMax = 0;
321 | int greenMin = 0;
322 | int greenRange = 0;
323 | //fill the arrays with the subtracted values
324 | //Keep track of the min and max values for later
325 | for (int column = 0; column < i.Bitmap.Width; column++)
326 | {
327 | for (int row = 0; row < i.Bitmap.Height; row++)
328 | {
329 | Color c1 = i.GetPixel(column, row);
330 | Color c2 = i2.GetPixel(column, row);
331 | red[column, row] = c2.R - c1.R;
332 | blue[column, row] = c2.B - c1.B;
333 | green[column, row] = c2.G - c1.G;
334 | if (red[column, row] > redMax) redMax = red[column, row];
335 | if (red[column, row] < redMin) redMin = red[column, row];
336 | if (blue[column, row] > blueMax) blueMax = blue[column, row];
337 | if (blue[column, row] < blueMin) blueMin = blue[column, row];
338 | if (green[column, row] > greenMax) greenMax = green[column, row];
339 | if (green[column, row] < greenMin) greenMin = green[column, row];
340 | }
341 | }
342 | //find the range of the min an max
343 | redRange = Math.Abs(redMax - redMin);
344 | blueRange = Math.Abs(blueMax - blueMin);
345 | greenRange = Math.Abs(greenRange - greenMin);
346 | //Normalize the values in the arrays and load the result image
347 | for (int column = 0; column < i.Bitmap.Width; column++)
348 | {
349 | for (int row = 0; row < i.Bitmap.Height; row++)
350 | {
351 | if (redRange != 0)
352 | red[column, row] = 255 - (((redMax - red[column, row]) * 255) / redRange);
353 | if (blueRange != 0)
354 | blue[column, row] = 255 - (((blueMax - blue[column, row]) * 255) / blueRange);
355 | if (greenRange != 0)
356 | green[column, row] = 255 - (((greenMax - green[column, row]) * 255) / greenRange);
357 | if (red[column, row] < 0)
358 | red[column, row] = 0;
359 | if (blue[column, row] < 0)
360 | blue[column, row] = 0;
361 | if (green[column, row] < 0)
362 | green[column, row] = 0;
363 | i2.SetPixel(column, row, Color.FromArgb(red[column, row], green[column, row],
364 | blue[column, row]));
365 | }
366 | }
367 | i.UnlockBitmap();
368 | i2.UnlockBitmap();
369 | return i2.Bitmap.Clone() as Bitmap;
370 | }
371 | ///
372 | /// Get the red pixels from the bitmap
373 | ///
374 | /// Image to Process
375 | /// Filtered Image
376 | public static Bitmap GetRedBitmap(Bitmap b)
377 | {
378 | ImagerBitmap i = new ImagerBitmap(b.Clone() as Bitmap);
379 | for (int column = 0; column < i.Bitmap.Width; column++)
380 | {
381 | for (int row = 0; row < i.Bitmap.Height; row++)
382 | {
383 | i.SetPixel(column, row, Color.FromArgb(i.GetPixel(column, row).R, 0, 0));
384 | }
385 | }
386 | i.UnlockBitmap();
387 | return i.Bitmap.Clone() as Bitmap;
388 | }
389 | ///
390 | /// Get the Blue Pixes from the bitmap
391 | ///
392 | /// Image to Process
393 | /// Filtered Image
394 | public static Bitmap GetBlueBitmap(Bitmap b)
395 | {
396 | ImagerBitmap i = new ImagerBitmap(b.Clone() as Bitmap);
397 | for (int column = 0; column < i.Bitmap.Width; column++)
398 | {
399 | for (int row = 0; row < i.Bitmap.Height; row++)
400 | {
401 | i.SetPixel(column, row, Color.FromArgb(0, 0, i.GetPixel(column, row).B));
402 | }
403 | }
404 | i.UnlockBitmap();
405 | return i.Bitmap.Clone() as Bitmap;
406 | }
407 | ///
408 | /// Get the green pixels from the image
409 | ///
410 | /// Image to Process
411 | /// Filtered Image
412 | public static Bitmap GetGreenBitmap(Bitmap b)
413 | {
414 | ImagerBitmap i = new ImagerBitmap(b.Clone() as Bitmap);
415 | for (int column = 0; column < i.Bitmap.Width; column++)
416 | {
417 | for (int row = 0; row < i.Bitmap.Height; row++)
418 | {
419 | i.SetPixel(column, row, Color.FromArgb(0, i.GetPixel(column, row).G, 0));
420 | }
421 | }
422 | i.UnlockBitmap();
423 | return i.Bitmap.Clone() as Bitmap;
424 | }
425 | ///
426 | /// Make the image Grey scale
427 | ///
428 | /// Image to Process
429 | /// Filtered Image
430 | public static Bitmap GetGreyScaleBitmap(Bitmap b)
431 | {
432 | ImagerBitmap i = new ImagerBitmap(b.Clone() as Bitmap);
433 | for (int column = 0; column < i.Bitmap.Width; column++)
434 | {
435 | for (int row = 0; row < i.Bitmap.Height; row++)
436 | {
437 | int val = i.GetGreyPixel(column, row);
438 | i.SetPixel(column, row, Color.FromArgb(val, val, val));
439 | }
440 | }
441 | i.UnlockBitmap();
442 | return i.Bitmap.Clone() as Bitmap;
443 | }
444 | ///
445 | /// Make the image black and white
446 | ///
447 | /// Image to Process
448 | /// Filtered Image
449 | public static Bitmap GetBlackAndWhiteBitmap(Bitmap b)
450 | {
451 | ImagerBitmap i = new ImagerBitmap(b.Clone() as Bitmap);
452 | double[] histogram = new double[256];
453 | for (int column = 0; column < i.Bitmap.Width; column++)
454 | {
455 | for (int row = 0; row < i.Bitmap.Height; row++)
456 | {
457 | histogram[i.GetGreyPixel(column, row)]++;
458 | }
459 | }
460 | //find the position of the max value on the left
461 | int leftK = 0;
462 | for (int k = 0; k < 128; k++)
463 | {
464 | if (histogram[k] > histogram[leftK]) leftK = k;
465 | }
466 | //find the position of the max value on the right
467 | int rightK = 0;
468 | for (int k = 128; k < 256; k++)
469 | {
470 | if (histogram[k] > histogram[rightK]) rightK = k;
471 | }
472 | //find the min value between the 2 local maxes
473 | int localMin = rightK;
474 | for (int k = leftK; k < rightK; k++)
475 | {
476 | if (histogram[k] < histogram[localMin]) localMin = k;
477 | }
478 | for (int column = 0; column < i.Bitmap.Width; column++)
479 | {
480 | for (int row = 0; row < i.Bitmap.Height; row++)
481 | {
482 | int val = (i.GetPixel(column, row).R + i.GetPixel(column, row).G
483 | + i.GetPixel(column, row).B) / 3;
484 | if (val > localMin)
485 | val = 255;
486 | else
487 | val = 0;
488 | i.SetPixel(column, row, Color.FromArgb(val, val, val));
489 | }
490 | }
491 | i.UnlockBitmap();
492 | return i.Bitmap.Clone() as Bitmap;
493 | }
494 | public static Bitmap GetBlackAndWhiteBitmap2(Bitmap b)
495 | {
496 | ImagerBitmap i = new ImagerBitmap(b.Clone() as Bitmap);
497 | double[] histogram = new double[256];
498 | for (int column = 0; column < i.Bitmap.Width; column++)
499 | {
500 | for (int row = 0; row < i.Bitmap.Height; row++)
501 | {
502 | histogram[i.GetGreyPixel(column, row)]++;
503 | }
504 | }
505 | double k = b.Width * b.Height;
506 | double half = k / 2;
507 | int middle = 0;
508 | while (k > half)
509 | {
510 | k = k - histogram[middle];
511 | middle++;
512 | }
513 | for (int column = 0; column < i.Bitmap.Width; column++)
514 | {
515 | for (int row = 0; row < i.Bitmap.Height; row++)
516 | {
517 | int val = (i.GetPixel(column, row).R + i.GetPixel(column, row).G
518 | + i.GetPixel(column, row).B) / 3;
519 | if (val > middle)
520 | val = 255;
521 | else
522 | val = 0;
523 | i.SetPixel(column, row, Color.FromArgb(val, val, val));
524 | }
525 | }
526 | i.UnlockBitmap();
527 | return i.Bitmap.Clone() as Bitmap;
528 | }
529 | ///
530 | /// Perform a Box filter using a 3x3 Mask
531 | ///
532 | /// Image to Process
533 | /// Filtered Image
534 | public static Bitmap Box3x3(Bitmap b)
535 | {
536 | ImagerBitmap i = new ImagerBitmap(b.Clone() as Bitmap);
537 | ImagerBitmap i2 = new ImagerBitmap(b.Clone() as Bitmap);
538 | for (int column = 1; column < i.Bitmap.Width - 1; column++)
539 | {
540 | for (int row = 1; row < i.Bitmap.Height - 1; row++)
541 | {
542 | Color[,] c = i.Get3x3(row, column);
543 | int red = (c[0, 0].R + c[0, 1].R + c[0, 2].R + c[1, 0].R + c[1, 2].R + c[2, 0].R
544 | + c[2, 1].R + c[2, 2].R + c[1, 1].R) / 9;
545 | int green = (c[0, 0].G + c[0, 1].G + c[0, 2].G + c[1, 0].G + c[1, 2].G + c[2, 0].G
546 | + c[2, 1].G + c[2, 2].G + c[1, 1].G) / 9;
547 | int blue = (c[0, 0].B + c[0, 1].B + c[0, 2].B + c[1, 0].B + c[1, 2].B + c[2, 0].B
548 | + c[2, 1].B + c[2, 2].B + c[1, 1].B) / 9;
549 | i2.SetPixel(column, row, Color.FromArgb(red, green, blue));
550 | }
551 | }
552 | i.UnlockBitmap();
553 | i2.UnlockBitmap();
554 | return i2.Bitmap.Clone() as Bitmap;
555 | }
556 | ///
557 | /// Perform a Bionomial filter using a 3x3 Mask
558 | ///
559 | /// Image to Process
560 | /// Filtered Image
561 | public static Bitmap Binomial3x3(Bitmap b)
562 | {
563 | ImagerBitmap i = new ImagerBitmap(b.Clone() as Bitmap);
564 | ImagerBitmap i2 = new ImagerBitmap(b.Clone() as Bitmap);
565 | for (int column = 1; column < i.Bitmap.Width - 1; column++)
566 | {
567 | for (int row = 1; row < i.Bitmap.Height - 1; row++)
568 | {
569 | Color[,] c = i.Get3x3(row, column);
570 | int red = ((c[0, 0].R * 1) + (c[0, 1].R * 2) + (c[0, 2].R * 1) + (c[1, 0].R * 2)
571 | + (c[1, 1].R * 4) + (c[1, 2].R * 2) + (c[2, 0].R * 1) + (c[2, 1].R * 2)
572 | + (c[2, 2].R * 1)) / 16;
573 | int green = ((c[0, 0].G * 1) + (c[0, 1].G * 2) + (c[0, 2].G * 1) + (c[1, 0].G * 2)
574 | + (c[1, 1].G * 4) + (c[1, 2].G * 2) + (c[2, 0].G * 1) + (c[2, 1].G * 2)
575 | + (c[2, 2].G * 1)) / 16;
576 | int blue = ((c[0, 0].B * 1) + (c[0, 1].B * 2) + (c[0, 2].B * 1) + (c[1, 0].B * 2)
577 | + (c[1, 1].B * 4) + (c[1, 2].B * 2) + (c[2, 0].B * 1) + (c[2, 1].B * 2)
578 | + (c[2, 2].B * 1)) / 16;
579 | i2.SetPixel(column, row, Color.FromArgb(red, green, blue));
580 | }
581 | }
582 | i.UnlockBitmap();
583 | i2.UnlockBitmap();
584 | return i2.Bitmap.Clone() as Bitmap;
585 | }
586 | ///
587 | /// Perform a Median filter using a 3x3 mask
588 | ///
589 | /// Image to Process
590 | /// Filtered Image
591 | public static Bitmap Median3x3(Bitmap b)
592 | {
593 | ImagerBitmap i = new ImagerBitmap(b.Clone() as Bitmap);
594 | ImagerBitmap i2 = new ImagerBitmap(b.Clone() as Bitmap);
595 | for (int column = 1; column < i.Bitmap.Width - 1; column++)
596 | {
597 | for (int row = 1; row < i.Bitmap.Height - 1; row++)
598 | {
599 | Color[,] c = i.Get3x3(row, column);
600 | int red = Median(c[0, 0].R, c[0, 1].R, c[0, 2].R, c[1, 0].R, c[1, 1].R, c[1, 2].R,
601 | c[2, 0].R, c[2, 1].R, c[2, 2].R);
602 | int green = Median(c[0, 0].G, c[0, 1].G, c[0, 2].G, c[1, 0].G, c[1, 1].G,
603 | c[1, 2].G, c[2, 0].G, c[2, 1].G, c[2, 2].G);
604 | int blue = Median(c[0, 0].B, c[0, 1].B, c[0, 2].B, c[1, 0].B, c[1, 1].B, c[1, 2].B,
605 | c[2, 0].B, c[2, 1].B, c[2, 2].B);
606 | i2.SetPixel(column, row, Color.FromArgb(red, green, blue));
607 | }
608 | }
609 | i.UnlockBitmap();
610 | i2.UnlockBitmap();
611 | return i2.Bitmap.Clone() as Bitmap;
612 | }
613 | ///
614 | /// Perform a Box filter using a 5x5 Mask
615 | ///
616 | /// Image to Process
617 | /// Filtered Image
618 | public static Bitmap Box5x5(Bitmap b)
619 | {
620 | ImagerBitmap i = new ImagerBitmap(b.Clone() as Bitmap);
621 | ImagerBitmap i2 = new ImagerBitmap(b.Clone() as Bitmap);
622 | for (int column = 2; column < i.Bitmap.Width - 2; column++)
623 | {
624 | for (int row = 2; row < i.Bitmap.Height - 2; row++)
625 | {
626 | Color[,] c = i.Get5x5(row, column);
627 | int red = (c[0, 0].R + c[0, 1].R + c[0, 2].R + c[0, 3].R + c[0, 4].R + c[1, 0].R
628 | + c[1, 1].R + c[1, 2].R + c[1, 3].R + c[1, 4].R + c[2, 0].R + c[2, 1].R
629 | + c[2, 2].R + c[2, 3].R + c[2, 4].R + c[3, 0].R + c[3, 1].R + c[3, 2].R
630 | + c[3, 3].R + c[3, 4].R + c[4, 0].R + c[4, 1].R + c[4, 2].R + c[4, 3].R
631 | + c[4, 4].R) / 25;
632 | int green = (c[0, 0].G + c[0, 1].G + c[0, 2].G + c[0, 3].G + c[0, 4].G + c[1, 0].G
633 | + c[1, 1].G + c[1, 2].G + c[1, 3].G + c[1, 4].G + c[2, 0].G + c[2, 1].G
634 | + c[2, 2].G + c[2, 3].G + c[2, 4].G + c[3, 0].G + c[3, 1].G + c[3, 2].G
635 | + c[3, 3].G + c[3, 4].G + c[4, 0].G + c[4, 1].G + c[4, 2].G + c[4, 3].G
636 | + c[4, 4].G) / 25;
637 | int blue = (c[0, 0].B + c[0, 1].B + c[0, 2].B + c[0, 3].B + c[0, 4].B + c[1, 0].B
638 | + c[1, 1].B + c[1, 2].B + c[1, 3].B + c[1, 4].B + c[2, 0].B + c[2, 1].B
639 | + c[2, 2].B + c[2, 3].B + c[2, 4].B + c[3, 0].B + c[3, 1].B + c[3, 2].B
640 | + c[3, 3].B + c[3, 4].B + c[4, 0].B + c[4, 1].B + c[4, 2].B + c[4, 3].B
641 | + c[4, 4].B) / 25;
642 | i2.SetPixel(column, row, Color.FromArgb(red, green, blue));
643 | }
644 | }
645 | i.UnlockBitmap();
646 | i2.UnlockBitmap();
647 | return i2.Bitmap.Clone() as Bitmap;
648 | }
649 | ///
650 | /// Perform a Binomial filter using a 5x5 Mask
651 | ///
652 | /// Image to Process
653 | /// Filtered Image
654 | public static Bitmap Binomial5x5(Bitmap b)
655 | {
656 | ImagerBitmap i = new ImagerBitmap(b.Clone() as Bitmap);
657 | ImagerBitmap i2 = new ImagerBitmap(b.Clone() as Bitmap);
658 | for (int column = 2; column < i.Bitmap.Width - 2; column++)
659 | {
660 | for (int row = 2; row < i.Bitmap.Height - 2; row++)
661 | {
662 | Color[,] c = i.Get5x5(row, column);
663 | int red = ((c[0, 0].R * 1) + (c[0, 1].R * 4) + (c[0, 2].R * 6) + (c[0, 3].R * 4)
664 | + (c[0, 4].R * 1) + (c[1, 0].R * 4) + (c[1, 1].R * 16) + (c[1, 2].R * 24)
665 | + (c[1, 3].R * 16) + (c[1, 4].R * 4) + (c[2, 0].R * 6) + (c[2, 1].R * 24)
666 | + (c[2, 2].R * 36) + (c[2, 3].R * 24) + (c[2, 4].R * 6) + (c[3, 0].R * 4)
667 | + (c[3, 1].R * 16) + (c[3, 2].R * 24) + (c[3, 3].R * 16) + (c[3, 4].R * 4)
668 | + (c[4, 0].R * 1) + (c[4, 1].R * 4) + (c[4, 2].R * 6) + (c[4, 3].R * 4)
669 | + (c[4, 4].R * 1)) / 256;
670 | int green = ((c[0, 0].G * 1) + (c[0, 1].G * 4) + (c[0, 2].G * 6) + (c[0, 3].G * 4)
671 | + (c[0, 4].G * 1) + (c[1, 0].G * 4) + (c[1, 1].G * 16) + (c[1, 2].G * 24)
672 | + (c[1, 3].G * 16) + (c[1, 4].G * 4) + (c[2, 0].G * 6) + (c[2, 1].G * 24)
673 | + (c[2, 2].G * 36) + (c[2, 3].G * 24) + (c[2, 4].G * 6) + (c[3, 0].G * 4)
674 | + (c[3, 1].G * 16) + (c[3, 2].G * 24) + (c[3, 3].G * 16) + (c[3, 4].G * 4)
675 | + (c[4, 0].G * 1) + (c[4, 1].G * 4) + (c[4, 2].G * 6) + (c[4, 3].G * 4)
676 | + (c[4, 4].G * 1)) / 256;
677 | int blue = ((c[0, 0].B * 1) + (c[0, 1].B * 4) + (c[0, 2].B * 6) + (c[0, 3].B * 4)
678 | + (c[0, 4].B * 1) + (c[1, 0].B * 4) + (c[1, 1].B * 16) + (c[1, 2].B * 24)
679 | + (c[1, 3].B * 16) + (c[1, 4].B * 4) + (c[2, 0].B * 6) + (c[2, 1].B * 24)
680 | + (c[2, 2].B * 36) + (c[2, 3].B * 24) + (c[2, 4].B * 6) + (c[3, 0].B * 4)
681 | + (c[3, 1].B * 16) + (c[3, 2].B * 24) + (c[3, 3].B * 16) + (c[3, 4].B * 4)
682 | + (c[4, 0].B * 1) + (c[4, 1].B * 4) + (c[4, 2].B * 6) + (c[4, 3].B * 4)
683 | + (c[4, 4].B * 1)) / 256;
684 | i2.SetPixel(column, row, Color.FromArgb(red, green, blue));
685 | }
686 | }
687 | i.UnlockBitmap();
688 | i2.UnlockBitmap();
689 | return i2.Bitmap.Clone() as Bitmap;
690 | }
691 | ///
692 | /// Perform a Median fiter using a 5x5 Mask
693 | ///
694 | /// Image to Process
695 | /// Filtered Image
696 | public static Bitmap Median5x5(Bitmap b)
697 | {
698 | ImagerBitmap i = new ImagerBitmap(b.Clone() as Bitmap);
699 | ImagerBitmap i2 = new ImagerBitmap(b.Clone() as Bitmap);
700 | for (int column = 2; column < i.Bitmap.Width - 2; column++)
701 | {
702 | for (int row = 2; row < i.Bitmap.Height - 2; row++)
703 | {
704 | Color[,] c = i.Get5x5(row, column);
705 | int red = Median(c[0, 0].R, c[0, 1].R, c[0, 2].R, c[0, 3].R, c[0, 4].R, c[1, 0].R,
706 | c[1, 1].R, c[1, 2].R, c[1, 3].R, c[1, 4].R, c[2, 0].R, c[2, 1].R, c[2, 2].R,
707 | c[2, 3].R, c[2, 4].R, c[3, 0].R, c[3, 1].R, c[3, 2].R, c[3, 3].R, c[3, 4].R,
708 | c[4, 0].R, c[4, 1].R, c[4, 2].R, c[4, 3].R, c[4, 4].R);
709 | int green = Median(c[0, 0].G, c[0, 1].G, c[0, 2].G, c[0, 3].G, c[0, 4].G, c[1, 0].G,
710 | c[1, 1].G, c[1, 2].G, c[1, 3].G, c[1, 4].G, c[2, 0].G, c[2, 1].G, c[2, 2].G,
711 | c[2, 3].G, c[2, 4].G, c[3, 0].G, c[3, 1].G, c[3, 2].G, c[3, 3].G, c[3, 4].G,
712 | c[4, 0].G, c[4, 1].G, c[4, 2].G, c[4, 3].G, c[4, 4].G);
713 | int blue = Median(c[0, 0].B, c[0, 1].B, c[0, 2].B, c[0, 3].B, c[0, 4].B, c[1, 0].B,
714 | c[1, 1].B, c[1, 2].B, c[1, 3].B, c[1, 4].B, c[2, 0].B, c[2, 1].B, c[2, 2].B,
715 | c[2, 3].B, c[2, 4].B, c[3, 0].B, c[3, 1].B, c[3, 2].B, c[3, 3].B, c[3, 4].B,
716 | c[4, 0].B, c[4, 1].B, c[4, 2].B, c[4, 3].B, c[4, 4].B);
717 | i2.SetPixel(column, row, Color.FromArgb(red, green, blue));
718 | }
719 | }
720 | i.UnlockBitmap();
721 | i2.UnlockBitmap();
722 | return i2.Bitmap.Clone() as Bitmap;
723 | }
724 | ///
725 | /// Find the Median value in an array of int's
726 | ///
727 | /// Array of values
728 | /// Median value
729 | private static int Median(params int[] values)
730 | {
731 | Array.Sort(values);
732 | return values[((values.Length - 1) / 2) + 1];
733 | }
734 | ///
735 | /// Resize an image
736 | ///
737 | /// Image to resize
738 | /// Width in pixels
739 | /// Height in pixels
740 | /// New Image
741 | public static Bitmap Resize(Bitmap b, int width, int height)
742 | {
743 | Bitmap b2 = new Bitmap(width, height, PixelFormat.Format24bppRgb);
744 | Graphics g = Graphics.FromImage(b2);
745 | g.DrawImage(b, new Rectangle(0, 0, width, height), 0, 0, b.Width, b.Height,
746 | GraphicsUnit.Pixel);
747 | g.Dispose();
748 | return b2;
749 | }
750 |
751 | public static void GenerateExcelFile(Bitmap b)
752 | {
753 | ImagerBitmap i = new ImagerBitmap(b.Clone() as Bitmap);
754 | string fileName = "output.txt";
755 | int f = 0;
756 | using (StreamWriter sw = new StreamWriter(fileName, false))
757 | {
758 | sw.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}", "Index", "Row", "Column", "Red",
759 | "Green", "Blue", "Gray");
760 | for (int column = 0; column < i.Bitmap.Width; column++)
761 | {
762 | for (int row = 0; row < i.Bitmap.Height; row++)
763 | {
764 | f++;
765 | Color c = i.GetPixel(column, row);
766 | int g = i.GetGreyPixel(column, row);
767 | sw.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}", f,
768 | row, column, c.R, c.G, c.B, g);
769 | }
770 | }
771 | }
772 | i.UnlockBitmap();
773 | System.Diagnostics.Process.Start(fileName);
774 | }
775 | }
776 | }
777 |
--------------------------------------------------------------------------------