From 6fa9d80f6f517fb97cd11f3158262070b52bbf8c Mon Sep 17 00:00:00 2001
From: pinb
-
+
+
cv::Mat cv::getGaborKernel(cv::Size ksize, double sigma, double theta, double lambd, double gamma, double psi = CV_PI*0.5, int ktype = CV_64F)
@@ -84,12 +84,12 @@
-
-
+
+
Threshold (0 ~ 255)
@@ -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(i, j);
- byte newValue = (Convert.ToInt32(pixelValue) > valthreshold) ? (byte)255 : (byte)0;
- dstMat.Set(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(i, j);
+ // byte newValue = (Convert.ToInt32(pixelValue) > valthreshold) ? (byte)255 : (byte)0;
+ // dstMat.Set(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(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(yy, xx);
- // double kernelValue = kernel.At(kRow, kCol);
- // sum += Convert.ToDouble(pixelValue) * kernelValue;
- // }
- // }
- // }
- //
- // byte resultValue = dst.At(y, x);
- // resultValue = (byte)Math.Clamp(sum, 0, 255);
- // dst.Set(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(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);
+ }
}
}
\ No newline at end of file