728x90
반응형
728x170
■ Bitmap 클래스 : 회선 필터(Convolution Filter) 사용하기 예제
using System.Drawing;
...
Bitmap sourceBitmap;
...
Bitmap targetBitmap = BitmapHelper.ApplyConvolutionFilter(sourceBitmap, Matrix.GaussianBlur3x3);
728x90
■ Bitmap 클래스 : 회선 필터(Convolution Filter) 사용하기
▶ BitmapHelper.cs
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace TestProject
{
/// <summary>
/// 비트맵 헬퍼
/// </summary>
public static class BitmapHelper
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region 회선 필터 적용하기 - ApplyConvolutionFilter(sourceBitmap, filterArray, factor, bias)
/// <summary>
/// 회선 필터 적용하기
/// </summary>
/// <param name="sourceBitmap">소스 비트맵</param>
/// <param name="filterArray">필터 배열</param>
/// <param name="factor">인자</param>
/// <param name="bias">바이어스</param>
/// <returns>비트맵</returns>
public static Bitmap ApplyConvolutionFilter(Bitmap sourceBitmap, double[,] filterArray, double factor = 1, int bias = 0)
{
BitmapData sourceBitmapData = sourceBitmap.LockBits
(
new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height),
ImageLockMode.ReadOnly,
PixelFormat.Format32bppArgb
);
byte[] sourceByteArray = new byte[sourceBitmapData.Stride * sourceBitmapData.Height];
byte[] targetByteArray = new byte[sourceBitmapData.Stride * sourceBitmapData.Height];
Marshal.Copy(sourceBitmapData.Scan0, sourceByteArray, 0, sourceByteArray.Length);
sourceBitmap.UnlockBits(sourceBitmapData);
double blue = 0.0;
double green = 0.0;
double red = 0.0;
int filterWidth = filterArray.GetLength(1);
int filterHeight = filterArray.GetLength(0);
int filterOffset = (filterWidth - 1) / 2;
int sourceOffset = 0;
int targetOffset = 0;
for(int offsetY = filterOffset; offsetY < sourceBitmap.Height - filterOffset; offsetY++)
{
for(int offsetX = filterOffset; offsetX < sourceBitmap.Width - filterOffset; offsetX++)
{
blue = 0;
green = 0;
red = 0;
targetOffset = offsetY * sourceBitmapData.Stride + offsetX * 4;
for(int filterY = -filterOffset; filterY <= filterOffset; filterY++)
{
for(int filterX = -filterOffset; filterX <= filterOffset; filterX++)
{
sourceOffset = targetOffset + (filterX * 4) + (filterY * sourceBitmapData.Stride);
blue += (double)(sourceByteArray[sourceOffset]) *
filterArray[filterY + filterOffset, filterX + filterOffset];
green += (double)(sourceByteArray[sourceOffset + 1]) *
filterArray[filterY + filterOffset, filterX + filterOffset];
red += (double)(sourceByteArray[sourceOffset + 2]) *
filterArray[filterY + filterOffset, filterX + filterOffset];
}
}
blue = factor * blue + bias;
green = factor * green + bias;
red = factor * red + bias;
blue = (blue > 255 ? 255 : (blue < 0 ? 0 : blue ));
green = (green > 255 ? 255 : (green < 0 ? 0 : green));
red = (red > 255 ? 255 : (red < 0 ? 0 : red ));
targetByteArray[targetOffset ] = (byte)(blue);
targetByteArray[targetOffset + 1] = (byte)(green);
targetByteArray[targetOffset + 2] = (byte)(red);
targetByteArray[targetOffset + 3] = 255;
}
}
Bitmap targetBitmap = new Bitmap(sourceBitmap.Width, sourceBitmap.Height);
BitmapData targetBitmapData = targetBitmap.LockBits
(
new Rectangle(0, 0, targetBitmap.Width, targetBitmap.Height),
ImageLockMode.WriteOnly,
PixelFormat.Format32bppArgb
);
Marshal.Copy(targetByteArray, 0, targetBitmapData.Scan0, targetByteArray.Length);
targetBitmap.UnlockBits(targetBitmapData);
return targetBitmap;
}
#endregion
}
}
300x250
▶ Matrix.cs
namespace TestProject
{
/// <summary>
/// 매트릭스
/// </summary>
public static class Matrix
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region MEAN 3X3 - Mean3X3
/// <summary>
/// MEAN 3X3
/// </summary>
public static double[,] Mean3X3
{
get
{
return new double[,]
{
{ 1, 1, 1, },
{ 1, 1, 1, },
{ 1, 1, 1, }
};
}
}
#endregion
#region MEAN 5X5 - Mean5X5
/// <summary>
/// MEAN 5X5
/// </summary>
public static double[,] Mean5X5
{
get
{
return new double[,]
{
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 }
};
}
}
#endregion
#region MEAN 7X7 - Mean7X7
/// <summary>
/// MEAN 7X7
/// </summary>
public static double[,] Mean7X7
{
get
{
return new double[,]
{
{ 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1 },
};
}
}
#endregion
#region MEAN 9X9 - Mean9X9
/// <summary>
/// MEAN 9X9
/// </summary>
public static double[,] Mean9X9
{
get
{
return new double[,]
{
{ 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1 }
};
}
}
#endregion
#region GAUSSIAN BLUR 3X3 - GaussianBlur3X3
/// <summary>
/// GAUSSIAN BLUR 3X3
/// </summary>
public static double[,] GaussianBlur3X3
{
get
{
return new double[,]
{
{ 1, 2, 1, },
{ 2, 4, 2, },
{ 1, 2, 1, }
};
}
}
#endregion
#region GAUSSIAN BLUR 5X5 - GaussianBlur5X5
/// <summary>
/// GAUSSIAN BLUR 5X5
/// </summary>
public static double[,] GaussianBlur5X5
{
get
{
return new double[,]
{
{ 2, 04, 05, 04, 2 },
{ 4, 09, 12, 09, 4 },
{ 5, 12, 15, 12, 5 },
{ 4, 09, 12, 09, 4 },
{ 2, 04, 05, 04, 2 }
};
}
}
#endregion
#region MOTION BLUR 5X5 - MotionBlur5X5
/// <summary>
/// MOTION BLUR 5X5
/// </summary>
public static double[,] MotionBlur5X5
{
get
{
return new double[,]
{
{ 1, 0, 0, 0, 1 },
{ 0, 1, 0, 1, 0 },
{ 0, 0, 1, 0, 0 },
{ 0, 1, 0, 1, 0 },
{ 1, 0, 0, 0, 1 }
};
}
}
#endregion
#region MOTION BLUR 5X5 AT 45 DEGREES - MotionBlur5X5At45Degrees
/// <summary>
/// MOTION BLUR 5X5 AT 45 DEGREES
/// </summary>
public static double[,] MotionBlur5X5At45Degrees
{
get
{
return new double[,]
{
{ 0, 0, 0, 0, 1 },
{ 0, 0, 0, 1, 0 },
{ 0, 0, 1, 0, 0 },
{ 0, 1, 0, 0, 0 },
{ 1, 0, 0, 0, 0 }
};
}
}
#endregion
#region MOTION BLUR 5X5 AT 135 DEGREES - MotionBlur5X5At135Degrees
/// <summary>
/// MOTION BLUR 5X5 AT 135 DEGREES
/// </summary>
public static double[,] MotionBlur5X5At135Degrees
{
get
{
return new double[,]
{
{ 1, 0, 0, 0, 0 },
{ 0, 1, 0, 0, 0 },
{ 0, 0, 1, 0, 0 },
{ 0, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 1 }
};
}
}
#endregion
#region MOTION BLUR 7X7 - MotionBlur7X7
/// <summary>
/// MOTION BLUR 7X7
/// </summary>
public static double[,] MotionBlur7X7
{
get
{
return new double[,]
{
{ 1, 0, 0, 0, 0, 0, 1 },
{ 0, 1, 0, 0, 0, 1, 0 },
{ 0, 0, 1, 0, 1, 0, 0 },
{ 0, 0, 0, 1, 0, 0, 0 },
{ 0, 0, 1, 0, 1, 0, 0 },
{ 0, 1, 0, 0, 0, 1, 0 },
{ 1, 0, 0, 0, 0, 0, 1 }
};
}
}
#endregion
#region MOTION BLUR 7X7 AT 45 DEGREES - MotionBlur7X7At45Degrees
/// <summary>
/// MOTION BLUR 7X7 AT 45 DEGREES
/// </summary>
public static double[,] MotionBlur7X7At45Degrees
{
get
{
return new double[,]
{
{ 0, 0, 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 1, 0, 0 },
{ 0, 0, 0, 1, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 0 },
{ 0, 1, 0, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0, 0, 0 }
};
}
}
#endregion
#region MOTION BLUR 7X7 AT 135 DEGREES - MotionBlur7X7At135Degrees
/// <summary>
/// MOTION BLUR 7X7 AT 135 DEGREES
/// </summary>
public static double[,] MotionBlur7X7At135Degrees
{
get
{
return new double[,]
{
{ 1, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 0 },
{ 0, 0, 0, 1, 0, 0, 0 },
{ 0, 0, 0, 0, 1, 0, 0 },
{ 0, 0, 0, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 0, 0, 1 }
};
}
}
#endregion
#region MOTION BLUR 9X9 - MotionBlur9X9
/// <summary>
/// MOTION BLUR 9X9
/// </summary>
public static double[,] MotionBlur9X9
{
get
{
return new double[,]
{
{ 1, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 0, 1, 0, 0, 0, 0, 0, 1, 0 },
{ 0, 0, 1, 0, 0, 0, 1, 0, 0 },
{ 0, 0, 0, 1, 0, 1, 0, 0, 0 },
{ 0, 0, 0, 0, 1, 0, 0, 0, 0 },
{ 0, 0, 0, 1, 0, 1, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 1, 0, 0 },
{ 0, 1, 0, 0, 0, 0, 0, 1, 0 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 1 }
};
}
}
#endregion
#region MOTION BLUR 9X9 AT 45 DEGREES - MotionBlur9X9At45Degrees
/// <summary>
/// MOTION BLUR 9X9 AT 45 DEGREES
/// </summary>
public static double[,] MotionBlur9X9At45Degrees
{
get
{
return new double[,]
{
{ 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 0, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 0, 0, 1, 0, 0 },
{ 0, 0, 0, 0, 0, 1, 0, 0, 0 },
{ 0, 0, 0, 0, 1, 0, 0, 0, 0 },
{ 0, 0, 0, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0 }
};
}
}
#endregion
#region MOTION BLUR 9X9 AT 135 DEGREES - MotionBlur9X9At135Degrees
/// <summary>
/// MOTION BLUR 9X9 AT 135 DEGREES
/// </summary>
public static double[,] MotionBlur9X9At135Degrees
{
get
{
return new double[,]
{
{ 1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 1, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 1, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 1, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 1 }
};
}
}
#endregion
}
}
728x90
반응형
그리드형(광고전용)
'C# > WinForm' 카테고리의 다른 글
[C#/WINFORM] Bitmap 클래스 : 네거티브 비트맵 구하기 (0) | 2020.08.08 |
---|---|
[C#/WINFORM] Bitmap 클래스 : 회색조 비트맵 구하기 (0) | 2020.08.08 |
[C#/WINFORM] Bitmap 클래스 : 투명 비트맵 구하기 (0) | 2020.08.08 |
[C#/WINFORM] Bitmap 클래스 : 32비트 ARGB 포맷 비트맵 구하기 (0) | 2020.08.08 |
[C#/WINFORM] Bitmap 클래스 : 중앙값 필터(Median Filter) 사용하기 (0) | 2020.08.08 |
[C#/WINFORM] Bitmap 클래스 : 회선 필터(Convolution Filter) 사용하기 (0) | 2020.08.08 |
[C#/WINFORM] Bitmap 클래스 : 타겟 너비 비율에 맞는 비트맵 구하기 (0) | 2020.08.08 |
[C#/WINFORM] 삼변 측량(trilateration) 하기 (0) | 2020.08.08 |
[C#/WINFORM] 원과 원 교차점 찾기 (0) | 2020.08.08 |
[C#/WINFORM] 타원형 호로 두 포인트 연결하기 (0) | 2020.08.07 |
[C#/WINFORM] 원의 중간점을 지나는 호 그리기 (0) | 2020.08.07 |
댓글을 달아 주세요