1: /// <summary>
2: /// Does thermal erosion on the image
3: /// </summary>
4: /// <param name="OriginalImage">Image to manipulate</param>
5: /// <param name="T">Threshold value</param>
6: /// <param name="C">Change value</param>
7: /// <param name="Iterations">Number of iterations</param>
8: /// <returns>A bitmap image</returns>
9: public static Bitmap ThermalErosion(Bitmap OriginalImage,float T,float C,int Iterations)
10: { 11: Bitmap BlackAndWhiteImage = Image.ConvertBlackAndWhite(OriginalImage);
12: BitmapData BlackAndWhiteData = Image.LockImage(BlackAndWhiteImage);
13: int BlackAndWhitePixelSize = Image.GetPixelSize(BlackAndWhiteData);
14: float[] HeightDifferences = new float[8];
15: for (int i = 0; i < Iterations; ++i)
16: { 17: for (int x = 0; x < BlackAndWhiteImage.Width; ++x)
18: { 19: for (int y = 0; y < BlackAndWhiteImage.Height; ++y)
20: { 21: int X1 = x - 1;
22: int Y1 = y - 1;
23: X1=Math.MathHelper.Clamp(X1, BlackAndWhiteImage.Width-1, 0);
24: Y1=Math.MathHelper.Clamp(Y1, BlackAndWhiteImage.Height-1, 0);
25: int X2 = x + 1;
26: int Y2 = y + 1;
27: X2=Math.MathHelper.Clamp(X2, BlackAndWhiteImage.Width-1, 0);
28: Y2=Math.MathHelper.Clamp(Y2, BlackAndWhiteImage.Height-1, 0);
29: HeightDifferences[0] = GetHeightDifferences(x, y, X1, Y1, BlackAndWhiteData, BlackAndWhitePixelSize);
30: HeightDifferences[1] = GetHeightDifferences(x, y, x, Y1, BlackAndWhiteData, BlackAndWhitePixelSize);
31: HeightDifferences[2] = GetHeightDifferences(x, y, X2, Y1, BlackAndWhiteData, BlackAndWhitePixelSize);
32: HeightDifferences[3] = GetHeightDifferences(x, y, X1, y, BlackAndWhiteData, BlackAndWhitePixelSize);
33: HeightDifferences[4] = GetHeightDifferences(x, y, X2, y, BlackAndWhiteData, BlackAndWhitePixelSize);
34: HeightDifferences[5] = GetHeightDifferences(x, y, X1, Y2, BlackAndWhiteData, BlackAndWhitePixelSize);
35: HeightDifferences[6] = GetHeightDifferences(x, y, x, Y2, BlackAndWhiteData, BlackAndWhitePixelSize);
36: HeightDifferences[7] = GetHeightDifferences(x, y, X2, Y2, BlackAndWhiteData, BlackAndWhitePixelSize);
37: float MaxDifference = 0.0f;
38: float DifferenceTotal = 0.0f;
39: float NumberOver = 0;
40: for (int z = 0; z < 8; ++z)
41: { 42: if (HeightDifferences[z] > MaxDifference)
43: { 44: MaxDifference = HeightDifferences[z];
45: }
46: if (HeightDifferences[z] > T)
47: { 48: DifferenceTotal += HeightDifferences[z];
49: ++NumberOver;
50: }
51: }
52: float Height = GetHeight(x, y, BlackAndWhiteData, BlackAndWhitePixelSize);
53: if (X1 != x && Y1 != y && HeightDifferences[0] != 0.0f && DifferenceTotal != 0.0f)
54: { 55: Height = GetHeight(X1, Y1, BlackAndWhiteData, BlackAndWhitePixelSize);
56: Height = Height + C * (MaxDifference - T) * (HeightDifferences[0] / DifferenceTotal);
57: Height = Math.MathHelper.Clamp(Height, 1.0f, -1.0f);
58: SetHeight(X1, Y1, Height, BlackAndWhiteData, BlackAndWhitePixelSize);
59: }
60: if (Y1 != y && HeightDifferences[1] != 0.0f && DifferenceTotal != 0.0f)
61: { 62: Height = GetHeight(x, Y1, BlackAndWhiteData, BlackAndWhitePixelSize);
63: Height = Height + C * (MaxDifference - T) * (HeightDifferences[1] / DifferenceTotal);
64: Height = Math.MathHelper.Clamp(Height, 1.0f, -1.0f);
65: SetHeight(x, Y1, Height, BlackAndWhiteData, BlackAndWhitePixelSize);
66: }
67: if (X2 != x && Y1 != y && HeightDifferences[2] != 0.0f && DifferenceTotal != 0.0f)
68: { 69: Height = GetHeight(X2, Y1, BlackAndWhiteData, BlackAndWhitePixelSize);
70: Height = Height + C * (MaxDifference - T) * (HeightDifferences[2] / DifferenceTotal);
71: Height = Math.MathHelper.Clamp(Height, 1.0f, -1.0f);
72: SetHeight(X2, Y1, Height, BlackAndWhiteData, BlackAndWhitePixelSize);
73: }
74: if (X1 != x && HeightDifferences[3] != 0.0f && DifferenceTotal != 0.0f)
75: { 76: Height = GetHeight(X1, y, BlackAndWhiteData, BlackAndWhitePixelSize);
77: Height = Height + C * (MaxDifference - T) * (HeightDifferences[3] / DifferenceTotal);
78: Height = Math.MathHelper.Clamp(Height, 1.0f, -1.0f);
79: SetHeight(X1, y, Height, BlackAndWhiteData, BlackAndWhitePixelSize);
80: }
81: if (X2 != x && HeightDifferences[4] != 0.0f && DifferenceTotal != 0.0f)
82: { 83: Height = GetHeight(X2, y, BlackAndWhiteData, BlackAndWhitePixelSize);
84: Height = Height + C * (MaxDifference - T) * (HeightDifferences[4] / DifferenceTotal);
85: Height = Math.MathHelper.Clamp(Height, 1.0f, -1.0f);
86: SetHeight(X2, y, Height, BlackAndWhiteData, BlackAndWhitePixelSize);
87: }
88: if (X1 != x && Y2 != y && HeightDifferences[5] != 0.0f && DifferenceTotal != 0.0f)
89: { 90: Height = GetHeight(X1, Y2, BlackAndWhiteData, BlackAndWhitePixelSize);
91: Height = Height + C * (MaxDifference - T) * (HeightDifferences[5] / DifferenceTotal);
92: Height = Math.MathHelper.Clamp(Height, 1.0f, -1.0f);
93: SetHeight(X1, Y2, Height, BlackAndWhiteData, BlackAndWhitePixelSize);
94: }
95: if (Y2 != y && HeightDifferences[6] != 0.0f && DifferenceTotal != 0.0f)
96: { 97: Height = GetHeight(x, Y2, BlackAndWhiteData, BlackAndWhitePixelSize);
98: Height = Height + C * (MaxDifference - T) * (HeightDifferences[6] / DifferenceTotal);
99: Height = Math.MathHelper.Clamp(Height, 1.0f, -1.0f);
100: SetHeight(x, Y2, Height, BlackAndWhiteData, BlackAndWhitePixelSize);
101: }
102: if (X2 != x && Y2 != y && HeightDifferences[7] != 0.0f && DifferenceTotal != 0.0f)
103: { 104: Height = GetHeight(X2, Y2, BlackAndWhiteData, BlackAndWhitePixelSize);
105: Height = Height + C * (MaxDifference - T) * (HeightDifferences[7] / DifferenceTotal);
106: Height = Math.MathHelper.Clamp(Height, 1.0f, -1.0f);
107: SetHeight(X2, Y2, Height, BlackAndWhiteData, BlackAndWhitePixelSize);
108: }
109: if (DifferenceTotal != 0.0f)
110: { 111: Height = GetHeight(x, y, BlackAndWhiteData, BlackAndWhitePixelSize);
112: Height = Height + (MaxDifference - (NumberOver * MaxDifference * T / DifferenceTotal));
113: Height = Math.MathHelper.Clamp(Height, 1.0f, -1.0f);
114: SetHeight(x, y, Height, BlackAndWhiteData, BlackAndWhitePixelSize);
115: }
116: }
117: }
118: }
119: Image.UnlockImage(BlackAndWhiteImage, BlackAndWhiteData);
120: return BlackAndWhiteImage;
121: }
122:
123: private static float GetHeightDifferences(int x, int y, int X1, int Y1, BitmapData BlackAndWhiteData, int BlackAndWhitePixelSize)
124: { 125: Color TempColor = Image.GetPixel(BlackAndWhiteData, x, y, BlackAndWhitePixelSize);
126: float Height = GetHeight(TempColor);
127: TempColor = Image.GetPixel(BlackAndWhiteData, X1, Y1, BlackAndWhitePixelSize);
128: float Height2 = GetHeight(TempColor);
129: return Height - Height2;
130: }
131:
132: private static void SetHeight(int x, int y, float Value,BitmapData Data,int PixelSize)
133: { 134: Value *= 0.5f;
135: Value += 0.5f;
136: int Value2 = (int)(Value * 255.0f);
137: Color TempColor = Color.FromArgb(Value2, Value2, Value2);
138: Image.SetPixel(Data, x, y, TempColor, PixelSize);
139: }
140:
141: private static float GetHeight(int x, int y, BitmapData BlackAndWhiteData, int BlackAndWhitePixelSize)
142: { 143: Color TempColor = Image.GetPixel(BlackAndWhiteData, x, y, BlackAndWhitePixelSize);
144: return GetHeight(TempColor);
145: }
146:
147: private static float GetHeight(Color Color)
148: { 149: return (float)Color.R / 255.0f;
150: }