|
|
|
@ -19,8 +19,8 @@
|
|
|
|
|
<img src="images/gaborfilter3.png" alt="gaborfilter"><br />
|
|
|
|
|
</p><br /><br />
|
|
|
|
|
<h3 id="-parameters-"><strong>함수 원형</strong></h3>
|
|
|
|
|
<pre style ="background-color: #f8f8f8;">
|
|
|
|
|
<code class="lang-cpp">
|
|
|
|
|
<pre style="background-color: #f8f8f8;">
|
|
|
|
|
<code class="lang-cpp">
|
|
|
|
|
cv::Mat cv::getGaborKernel(cv::Size ksize, <span class="hljs-keyword">double</span> sigma, <span class="hljs-keyword">double</span> theta, <span class="hljs-keyword">double</span> lambd, <span class="hljs-keyword">double</span> gamma, <span class="hljs-keyword">double</span> psi = CV_PI*<span class="hljs-number">0.5</span>, <span class="hljs-keyword">int</span> ktype = CV_64F)
|
|
|
|
|
</code>
|
|
|
|
|
</pre><br />
|
|
|
|
@ -84,12 +84,12 @@
|
|
|
|
|
</div>
|
|
|
|
|
<br />
|
|
|
|
|
<div>
|
|
|
|
|
<canvas @ref="srcCanvas" width="256" height="256" style="border:1px solid gray;">
|
|
|
|
|
Your browser does not support the HTML5 canvas tag.
|
|
|
|
|
</canvas>
|
|
|
|
|
<canvas @ref="dstCanvas" width="256" height="256" style="border:1px solid gray;">
|
|
|
|
|
Your browser does not support the HTML5 canvas tag.
|
|
|
|
|
</canvas>
|
|
|
|
|
<canvas @ref="srcCanvas" width="256" height="256" style="border:1px solid gray;">
|
|
|
|
|
Your browser does not support the HTML5 canvas tag.
|
|
|
|
|
</canvas>
|
|
|
|
|
<canvas @ref="dstCanvas" width="256" height="256" style="border:1px solid gray;">
|
|
|
|
|
Your browser does not support the HTML5 canvas tag.
|
|
|
|
|
</canvas>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<p>Threshold (0 ~ 255)</p>
|
|
|
|
@ -102,8 +102,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@code {
|
|
|
|
|
private Mat? srcMat;
|
|
|
|
|
private Mat? srcMat2;
|
|
|
|
|
//private Mat? srcMat;
|
|
|
|
|
//private Mat? srcMat2;
|
|
|
|
|
private byte[] imageBytes_rgba = new byte[256 * 256 * 4];
|
|
|
|
|
private byte[] imageBytes_rgba2 = new byte[256 * 256 * 4];
|
|
|
|
|
private ElementReference srcCanvas;
|
|
|
|
|
private ElementReference dstCanvas;
|
|
|
|
|
private ElementReference srcCanvas2;
|
|
|
|
@ -122,12 +124,12 @@
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
srcMat?.Dispose();
|
|
|
|
|
srcMat2?.Dispose();
|
|
|
|
|
//srcMat?.Dispose();
|
|
|
|
|
//srcMat2?.Dispose();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
await base.OnInitializedAsync();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -136,55 +138,120 @@
|
|
|
|
|
if (!firstRender)
|
|
|
|
|
return;
|
|
|
|
|
await base.OnAfterRenderAsync(firstRender);
|
|
|
|
|
int width = 256;
|
|
|
|
|
int height = 256;
|
|
|
|
|
|
|
|
|
|
var imageBytes = await httpClient.GetByteArrayAsync("/images/mandrill.bmp");
|
|
|
|
|
srcMat ??= Mat.FromImageData(imageBytes);
|
|
|
|
|
if(srcMat.Width < 256 || srcMat.Height < 256)
|
|
|
|
|
{
|
|
|
|
|
Cv2.PyrUp(srcMat, srcMat, new Size(256, 256));
|
|
|
|
|
}
|
|
|
|
|
//srcMat ??= Mat.FromImageData(imageBytes);
|
|
|
|
|
//if(srcMat.Width < 256 || srcMat.Height < 256)
|
|
|
|
|
//{
|
|
|
|
|
// Cv2.PyrUp(srcMat, srcMat, new Size(256, 256));
|
|
|
|
|
//}
|
|
|
|
|
srcCanvasClient ??= new CanvasClient(jsRuntime, srcCanvas);
|
|
|
|
|
dstCanvasClient ??= new CanvasClient(jsRuntime, dstCanvas);
|
|
|
|
|
|
|
|
|
|
await srcCanvasClient.DrawMatAsync(srcMat);
|
|
|
|
|
|
|
|
|
|
//await srcCanvasClient.DrawMatAsync(srcMat);
|
|
|
|
|
|
|
|
|
|
var imageBytes2 = await httpClient.GetByteArrayAsync("/images/lenna.bmp");
|
|
|
|
|
srcMat2 ??= Mat.FromImageData(imageBytes2);
|
|
|
|
|
if(srcMat2.Width > 256 || srcMat2.Height > 256)
|
|
|
|
|
unsafe
|
|
|
|
|
{
|
|
|
|
|
Cv2.PyrDown(srcMat2, srcMat2, new Size(256, 256));
|
|
|
|
|
fixed (byte* pImageByte = imageBytes, pImageBytes_rgba = imageBytes_rgba)
|
|
|
|
|
{
|
|
|
|
|
var pRgb = pImageByte;
|
|
|
|
|
var pRgba = pImageBytes_rgba;
|
|
|
|
|
|
|
|
|
|
for (int y = 0; y < height; y++)
|
|
|
|
|
{
|
|
|
|
|
for (int x = 0; x < width; x++)
|
|
|
|
|
{
|
|
|
|
|
// RGB 채널 복사
|
|
|
|
|
*(pRgba++) = *(pRgb++); // R
|
|
|
|
|
*(pRgba++) = *(pRgb++); // G
|
|
|
|
|
*(pRgba++) = *(pRgb++); // B
|
|
|
|
|
|
|
|
|
|
// 알파 채널 추가
|
|
|
|
|
*(pRgba++) = 255; // A
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
imageBytes_rgba = FlipVertical(imageBytes_rgba, width, height);
|
|
|
|
|
ConvertBgrToRgba(imageBytes_rgba);
|
|
|
|
|
|
|
|
|
|
await srcCanvasClient.DrawPixelsAsync(imageBytes_rgba);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var imageBytes2 = await httpClient.GetByteArrayAsync("/images/lenna256.bmp");
|
|
|
|
|
//srcMat2 ??= Mat.FromImageData(imageBytes2);
|
|
|
|
|
//if(srcMat2.Width > 256 || srcMat2.Height > 256)
|
|
|
|
|
//{
|
|
|
|
|
// Cv2.PyrDown(srcMat2, srcMat2, new Size(256, 256));
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
srcCanvasClient2 ??= new CanvasClient(jsRuntime, srcCanvas2);
|
|
|
|
|
dstCanvasClient2 ??= new CanvasClient(jsRuntime, dstCanvas2);
|
|
|
|
|
|
|
|
|
|
await srcCanvasClient2.DrawMatAsync(srcMat2);
|
|
|
|
|
//await srcCanvasClient2.DrawMatAsync(srcMat2);
|
|
|
|
|
|
|
|
|
|
unsafe
|
|
|
|
|
{
|
|
|
|
|
fixed (byte* pImageByte = imageBytes2, pImageBytes_rgba = imageBytes_rgba2)
|
|
|
|
|
{
|
|
|
|
|
var pRgb = pImageByte;
|
|
|
|
|
var pRgba = pImageBytes_rgba;
|
|
|
|
|
|
|
|
|
|
for (int y = 0; y < height; y++)
|
|
|
|
|
{
|
|
|
|
|
for (int x = 0; x < width; x++)
|
|
|
|
|
{
|
|
|
|
|
// RGB 채널 복사
|
|
|
|
|
*(pRgba++) = *(pRgb++); // R
|
|
|
|
|
*(pRgba++) = *(pRgb++); // G
|
|
|
|
|
*(pRgba++) = *(pRgb++); // B
|
|
|
|
|
|
|
|
|
|
// 알파 채널 추가
|
|
|
|
|
*(pRgba++) = 255; // A
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
imageBytes_rgba2 = FlipVertical(imageBytes_rgba2, width, height);
|
|
|
|
|
ConvertBgrToRgba(imageBytes_rgba2);
|
|
|
|
|
|
|
|
|
|
//await srcCanvasClient2.DrawPixelsAsync(imageBytes2);
|
|
|
|
|
await srcCanvasClient2.DrawPixelsAsync(imageBytes_rgba2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task Grayscale()
|
|
|
|
|
{
|
|
|
|
|
if (srcMat is null)
|
|
|
|
|
throw new InvalidOperationException($"{nameof(srcMat)} is null");
|
|
|
|
|
if (dstCanvasClient is null)
|
|
|
|
|
throw new InvalidOperationException($"{nameof(dstCanvasClient)} is null");
|
|
|
|
|
//if (srcMat is null)
|
|
|
|
|
// throw new InvalidOperationException($"{nameof(srcMat)} is null");
|
|
|
|
|
//if (dstCanvasClient is null)
|
|
|
|
|
// throw new InvalidOperationException($"{nameof(dstCanvasClient)} is null");
|
|
|
|
|
|
|
|
|
|
using var grayMat = new Mat();
|
|
|
|
|
Cv2.CvtColor(srcMat, grayMat, ColorConversionCodes.BGR2GRAY);
|
|
|
|
|
//using var grayMat = new Mat();
|
|
|
|
|
//Cv2.CvtColor(srcMat, grayMat, ColorConversionCodes.BGR2GRAY);
|
|
|
|
|
|
|
|
|
|
byte[] gray = new byte[imageBytes_rgba.Length];
|
|
|
|
|
imageBytes_rgba.CopyTo(gray, 0);
|
|
|
|
|
|
|
|
|
|
ConvertRgbaToGray(gray);
|
|
|
|
|
|
|
|
|
|
await dstCanvasClient.DrawMatAsync(grayMat);
|
|
|
|
|
//await dstCanvasClient.DrawMatAsync(grayMat);
|
|
|
|
|
await dstCanvasClient.DrawPixelsAsync(gray);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task PseudoColor()
|
|
|
|
|
{
|
|
|
|
|
if (srcMat is null)
|
|
|
|
|
throw new InvalidOperationException($"{nameof(srcMat)} is null");
|
|
|
|
|
if (dstCanvasClient is null)
|
|
|
|
|
throw new InvalidOperationException($"{nameof(dstCanvasClient)} is null");
|
|
|
|
|
//if (srcMat is null)
|
|
|
|
|
// throw new InvalidOperationException($"{nameof(srcMat)} is null");
|
|
|
|
|
//if (dstCanvasClient is null)
|
|
|
|
|
// throw new InvalidOperationException($"{nameof(dstCanvasClient)} is null");
|
|
|
|
|
|
|
|
|
|
Mat srcMat = new Mat(256, 256, MatType.CV_8UC4, imageBytes_rgba);
|
|
|
|
|
using var grayMat = new Mat();
|
|
|
|
|
using var dstMat = new Mat();
|
|
|
|
|
Cv2.CvtColor(srcMat, grayMat, ColorConversionCodes.BGR2GRAY);
|
|
|
|
|
//Cv2.CvtColor(srcMat, grayMat, ColorConversionCodes.BGR2GRAY);
|
|
|
|
|
Cv2.ApplyColorMap(grayMat, dstMat, ColormapTypes.Jet);
|
|
|
|
|
|
|
|
|
|
await dstCanvasClient.DrawMatAsync(dstMat);
|
|
|
|
@ -192,62 +259,76 @@
|
|
|
|
|
|
|
|
|
|
private async Task Threshold()
|
|
|
|
|
{
|
|
|
|
|
if (srcMat is null)
|
|
|
|
|
throw new InvalidOperationException($"{nameof(srcMat)} is null");
|
|
|
|
|
if (dstCanvasClient is null)
|
|
|
|
|
throw new InvalidOperationException($"{nameof(dstCanvasClient)} is null");
|
|
|
|
|
|
|
|
|
|
using var grayMat = new Mat();
|
|
|
|
|
using var dstMat = new Mat(srcMat.Size(), MatType.CV_8UC1);
|
|
|
|
|
Cv2.CvtColor(srcMat, grayMat, ColorConversionCodes.BGR2GRAY);
|
|
|
|
|
//Cv2.Threshold(grayMat, dstMat, 127, 255, ThresholdTypes.Binary);
|
|
|
|
|
|
|
|
|
|
for(int i=0; i<grayMat.Rows; i++)
|
|
|
|
|
{
|
|
|
|
|
for(int j=0; j<grayMat.Cols; j++)
|
|
|
|
|
{
|
|
|
|
|
byte pixelValue = grayMat.At<byte>(i, j);
|
|
|
|
|
byte newValue = (Convert.ToInt32(pixelValue) > valthreshold) ? (byte)255 : (byte)0;
|
|
|
|
|
dstMat.Set<byte>(i, j, newValue);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await dstCanvasClient.DrawMatAsync(dstMat);
|
|
|
|
|
//if (srcMat is null)
|
|
|
|
|
// throw new InvalidOperationException($"{nameof(srcMat)} is null");
|
|
|
|
|
//if (dstCanvasClient is null)
|
|
|
|
|
// throw new InvalidOperationException($"{nameof(dstCanvasClient)} is null");
|
|
|
|
|
//
|
|
|
|
|
//using var grayMat = new Mat();
|
|
|
|
|
//using var dstMat = new Mat(srcMat.Size(), MatType.CV_8UC1);
|
|
|
|
|
//Cv2.CvtColor(srcMat, grayMat, ColorConversionCodes.BGR2GRAY);
|
|
|
|
|
////Cv2.Threshold(grayMat, dstMat, 127, 255, ThresholdTypes.Binary);
|
|
|
|
|
//
|
|
|
|
|
//for (int i = 0; i < grayMat.Rows; i++)
|
|
|
|
|
//{
|
|
|
|
|
// for (int j = 0; j < grayMat.Cols; j++)
|
|
|
|
|
// {
|
|
|
|
|
// byte pixelValue = grayMat.At<byte>(i, j);
|
|
|
|
|
// byte newValue = (Convert.ToInt32(pixelValue) > valthreshold) ? (byte)255 : (byte)0;
|
|
|
|
|
// dstMat.Set<byte>(i, j, newValue);
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//await dstCanvasClient.DrawMatAsync(dstMat);
|
|
|
|
|
|
|
|
|
|
byte[] th = new byte[imageBytes_rgba.Length];
|
|
|
|
|
imageBytes_rgba.CopyTo(th, 0);
|
|
|
|
|
|
|
|
|
|
ConvertRgbaToGray(th);
|
|
|
|
|
Threshold(th, valthreshold);
|
|
|
|
|
|
|
|
|
|
await dstCanvasClient.DrawPixelsAsync(th);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task GaborFilter()
|
|
|
|
|
{
|
|
|
|
|
if (srcMat2 is null)
|
|
|
|
|
throw new InvalidOperationException($"{nameof(srcMat2)} is null");
|
|
|
|
|
if (dstCanvasClient2 is null)
|
|
|
|
|
throw new InvalidOperationException($"{nameof(dstCanvasClient2)} is null");
|
|
|
|
|
|
|
|
|
|
using var grayMat = new Mat(srcMat2.Size(), MatType.CV_32F);
|
|
|
|
|
Cv2.CvtColor(srcMat2, grayMat, ColorConversionCodes.BGR2GRAY);
|
|
|
|
|
|
|
|
|
|
//if (srcMat2 is null)
|
|
|
|
|
// throw new InvalidOperationException($"{nameof(srcMat2)} is null");
|
|
|
|
|
//if (dstCanvasClient2 is null)
|
|
|
|
|
// throw new InvalidOperationException($"{nameof(dstCanvasClient2)} is null");
|
|
|
|
|
//
|
|
|
|
|
//using var grayMat = new Mat(srcMat2.Size(), MatType.CV_32F);
|
|
|
|
|
//Cv2.CvtColor(srcMat2, grayMat, ColorConversionCodes.BGR2GRAY);
|
|
|
|
|
//
|
|
|
|
|
int kernel_size = valKernelSize;
|
|
|
|
|
double sigma = valSigma;
|
|
|
|
|
double theta = valTheta * Cv2.PI / 180.0;
|
|
|
|
|
double lambd = valLambd;
|
|
|
|
|
double gamma = valGamma;
|
|
|
|
|
double psi = valPsi * Cv2.PI / 180.0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mat rst = new Mat();
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
//Mat gabor_filter = Cv2.GetGaborKernel(new Size(kernel_size, kernel_size), sigma, theta, lambd, gamma, psi, ktype);
|
|
|
|
|
//Mat kenel = new Mat(5, 5, MatType.CV_8UC1);
|
|
|
|
|
//Cv2.Filter2D(grayMat, rst, grayMat.Type(), kenel);
|
|
|
|
|
|
|
|
|
|
Mat gabor_filter = Gabor2DFilter.CreateGaborKernel(kernel_size, sigma, theta, lambd, gamma, psi);
|
|
|
|
|
rst = Gabor2DFilter.Filter2D(grayMat, gabor_filter);
|
|
|
|
|
}
|
|
|
|
|
catch(Exception e)
|
|
|
|
|
{
|
|
|
|
|
String log = e.Message;
|
|
|
|
|
}
|
|
|
|
|
await dstCanvasClient2.DrawMatAsync(rst);
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//Mat rst = new Mat();
|
|
|
|
|
//try
|
|
|
|
|
//{
|
|
|
|
|
// //Mat gabor_filter = Cv2.GetGaborKernel(new Size(kernel_size, kernel_size), sigma, theta, lambd, gamma, psi, ktype);
|
|
|
|
|
// //Mat kenel = new Mat(5, 5, MatType.CV_8UC1);
|
|
|
|
|
// //Cv2.Filter2D(grayMat, rst, grayMat.Type(), kenel);
|
|
|
|
|
//
|
|
|
|
|
// Mat gabor_filter = Gabor2DFilter.CreateGaborKernel(kernel_size, sigma, theta, lambd, gamma, psi);
|
|
|
|
|
// rst = Gabor2DFilter.Filter2D(grayMat, gabor_filter);
|
|
|
|
|
//}
|
|
|
|
|
//catch (Exception e)
|
|
|
|
|
//{
|
|
|
|
|
// String log = e.Message;
|
|
|
|
|
//}
|
|
|
|
|
//await dstCanvasClient2.DrawMatAsync(rst);
|
|
|
|
|
|
|
|
|
|
Mat srcMat = new Mat(256, 256, MatType.CV_8UC4, imageBytes_rgba2);
|
|
|
|
|
Cv2.CvtColor(srcMat, srcMat, ColorConversionCodes.BGRA2GRAY);
|
|
|
|
|
Mat gaborfilter = Gabor2DFilter.CreateGaborKernel(kernel_size, sigma, theta, lambd, gamma, psi);
|
|
|
|
|
Mat rstMat = Gabor2DFilter.Filter2D(srcMat, gaborfilter);
|
|
|
|
|
await dstCanvasClient2.DrawMatAsync(rstMat);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class Gabor2DFilter
|
|
|
|
@ -255,21 +336,10 @@
|
|
|
|
|
public static Mat CreateGaborKernel(int ksize, double sigma, double theta, double lambd, double gamma, double psi)
|
|
|
|
|
{
|
|
|
|
|
int center = ksize / 2;
|
|
|
|
|
Mat kernel = new Mat(ksize, ksize, MatType.CV_32F);
|
|
|
|
|
Mat kernel = new Mat(ksize, ksize, MatType.CV_32FC1);
|
|
|
|
|
double sigmaX = sigma;
|
|
|
|
|
double sigmaY = sigma / gamma;
|
|
|
|
|
|
|
|
|
|
//for (int y = -center; y <= center; y++)
|
|
|
|
|
//{
|
|
|
|
|
// for (int x = -center; x <= center; x++)
|
|
|
|
|
// {
|
|
|
|
|
// double xPrime = x * Math.Cos(theta) + y * Math.Sin(theta);
|
|
|
|
|
// double yPrime = -x * Math.Sin(theta) + y * Math.Cos(theta);
|
|
|
|
|
// double value = Math.Exp(-0.5 * (xPrime * xPrime / (sigmaX * sigmaX) + yPrime * yPrime / (sigmaY * sigmaY)));
|
|
|
|
|
// value *= Math.Cos(2 * Math.PI * xPrime / lambd + psi);
|
|
|
|
|
// kernel.Set<float>(center + y, center + x, Convert.ToSingle(value));
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|
unsafe
|
|
|
|
|
{
|
|
|
|
|
for (int y = -center; y <= center; y++)
|
|
|
|
@ -300,36 +370,10 @@
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
//for (int y = 0; y < src.Rows; y++)
|
|
|
|
|
//{
|
|
|
|
|
// for (int x = 0; x < src.Cols; x++)
|
|
|
|
|
// {
|
|
|
|
|
// double sum = 0.0;
|
|
|
|
|
//
|
|
|
|
|
// for (int kRow = 0; kRow < kernelRows; kRow++)
|
|
|
|
|
// {
|
|
|
|
|
// int yy = y + kRow - kernelCenterY;
|
|
|
|
|
//
|
|
|
|
|
// for (int kCol = 0; kCol < kernelCols; kCol++)
|
|
|
|
|
// {
|
|
|
|
|
// int xx = x + kCol - kernelCenterX;
|
|
|
|
|
//
|
|
|
|
|
// if (xx >= 0 && xx < src.Cols && yy >= 0 && yy < src.Rows)
|
|
|
|
|
// {
|
|
|
|
|
// byte pixelValue = src.At<byte>(yy, xx);
|
|
|
|
|
// double kernelValue = kernel.At<double>(kRow, kCol);
|
|
|
|
|
// sum += Convert.ToDouble(pixelValue) * kernelValue;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// byte resultValue = dst.At<byte>(y, x);
|
|
|
|
|
// resultValue = (byte)Math.Clamp(sum, 0, 255);
|
|
|
|
|
// dst.Set<byte>(y, x, resultValue);
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|
unsafe
|
|
|
|
|
{
|
|
|
|
|
double* kernelData = (double*)kernel.DataPointer;
|
|
|
|
|
|
|
|
|
|
for (int y = 0; y < src.Rows; y++)
|
|
|
|
|
{
|
|
|
|
|
for (int x = 0; x < src.Cols; x++)
|
|
|
|
@ -342,11 +386,11 @@
|
|
|
|
|
for (int kCol = 0; kCol < kernelCols; kCol++)
|
|
|
|
|
{
|
|
|
|
|
int xx = x + kCol - kernelCenterX;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (xx >= 0 && xx < src.Cols && yy >= 0 && yy < src.Rows)
|
|
|
|
|
{
|
|
|
|
|
byte* pixelValue = src.DataPointer + yy * src.Step() + xx * src.ElemSize();
|
|
|
|
|
double kernelValue = kernel.At<double>(kRow, kCol);
|
|
|
|
|
double kernelValue = *(kernelData + kRow * kernelCols + kCol);
|
|
|
|
|
sum += Convert.ToDouble(*pixelValue) * kernelValue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -357,16 +401,75 @@
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch(Exception ex)
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
String log = ex.Message;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return dst;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public byte[] FlipVertical(byte[] pixels, int width, int height)
|
|
|
|
|
{
|
|
|
|
|
byte[] flippedPixels = new byte[pixels.Length];
|
|
|
|
|
int rowBytes = width * 4; // 각 행의 바이트 수 (RGBA 채널)
|
|
|
|
|
|
|
|
|
|
for (int y = 0; y < height; y++)
|
|
|
|
|
{
|
|
|
|
|
for (int x = 0; x < rowBytes; x++)
|
|
|
|
|
{
|
|
|
|
|
flippedPixels[(height - 1 - y) * rowBytes + x] = pixels[y * rowBytes + x];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return flippedPixels;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ConvertBgrToRgba(byte[] pixels)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < pixels.Length; i += 4)
|
|
|
|
|
{
|
|
|
|
|
byte temp = pixels[i]; // B 채널
|
|
|
|
|
pixels[i] = pixels[i + 2]; // R 채널
|
|
|
|
|
pixels[i + 2] = temp;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ConvertRgbaToGray(byte[] pixels)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < pixels.Length; i += 4)
|
|
|
|
|
{
|
|
|
|
|
byte r = pixels[i];
|
|
|
|
|
byte g = pixels[i + 1];
|
|
|
|
|
byte b = pixels[i + 2];
|
|
|
|
|
// byte a = pixels[i + 3]; // 알파 채널은 사용하지 않음
|
|
|
|
|
|
|
|
|
|
// 그레이스케일 값 계산
|
|
|
|
|
byte grayValue = (byte)((r * 0.299) + (g * 0.587) + (b * 0.114));
|
|
|
|
|
pixels[i] = grayValue;
|
|
|
|
|
pixels[i + 1] = grayValue;
|
|
|
|
|
pixels[i + 2] = grayValue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Threshold(byte[] pixels, int threshold)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < pixels.Length; i += 4)
|
|
|
|
|
{
|
|
|
|
|
byte r = pixels[i];
|
|
|
|
|
byte g = pixels[i + 1];
|
|
|
|
|
byte b = pixels[i + 2];
|
|
|
|
|
|
|
|
|
|
if(r != g || r!= b)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pixels[i] = pixels[i + 1] = pixels[i + 2] = Convert.ToInt32(r) > threshold ? Convert.ToByte(255) : Convert.ToByte(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|