나는 엣지 검출 알고리즘을 구현 한 프로그램을 만든다. 하지만 프로세스에 시간이 오래 걸립니다. getpixel 및 setpixel 대신 lockbits 및 안전하지 않은 상태 사용에 대해 읽었지만 여전히 사용 방법을 알고 있습니다.Lockbit를 사용한 엣지 검출 C#
이 내 예제 코드입니다 : 내가 fastbitmap 클래스를 사용하고, 나는 이런 식으로 구현
private Bitmap SobelEdgeDetect(Bitmap original)
{
Bitmap b = original;
Bitmap bb = original;
int width = b.Width;
int height = b.Height;
int[,] gx = new int[,] { { -1, 0, 1 }, { -2, 0, 2 }, { -1, 0, 1 } };
int[,] gy = new int[,] { { 1, 2, 1 }, { 0, 0, 0 }, { -1, -2, -1 } };
int[,] allPixR = new int[width, height];
int[,] allPixG = new int[width, height];
int[,] allPixB = new int[width, height];
int limit = 128 * 128;
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
allPixR[i, j] = b.GetPixel(i, j).R;
allPixG[i, j] = b.GetPixel(i, j).G;
allPixB[i, j] = b.GetPixel(i, j).B;
}
}
int new_rx = 0, new_ry = 0;
int new_gx = 0, new_gy = 0;
int new_bx = 0, new_by = 0;
int rc, gc, bc;
for (int i = 1; i < b.Width - 1; i++)
{
for (int j = 1; j < b.Height - 1; j++)
{
new_rx = 0;
new_ry = 0;
new_gx = 0;
new_gy = 0;
new_bx = 0;
new_by = 0;
rc = 0;
gc = 0;
bc = 0;
for (int wi = -1; wi < 2; wi++)
{
for (int hw = -1; hw < 2; hw++)
{
rc = allPixR[i + hw, j + wi];
new_rx += gx[wi + 1, hw + 1] * rc;
new_ry += gy[wi + 1, hw + 1] * rc;
gc = allPixG[i + hw, j + wi];
new_gx += gx[wi + 1, hw + 1] * gc;
new_gy += gy[wi + 1, hw + 1] * gc;
bc = allPixB[i + hw, j + wi];
new_bx += gx[wi + 1, hw + 1] * bc;
new_by += gy[wi + 1, hw + 1] * bc;
}
}
if (new_rx * new_rx + new_ry * new_ry > limit || new_gx * new_gx + new_gy * new_gy > limit || new_bx * new_bx + new_by * new_by > limit)
bb.SetPixel(i, j, Color.Black);
else
bb.SetPixel(i, j, Color.Transparent);
}
}
return bb;
}
:
private Bitmap SobelEdgeDetectTwo(Bitmap original)
{
int width = original.Width;
int height = original.Height;
Bitmap result = new Bitmap(width,height);
FastBitmap b = new FastBitmap(original);
FastBitmap bb = new FastBitmap(result);
b.LockBitmap();
bb.LockBitmap();
int[,] gx = new int[,] { { -1, 0, 1 }, { -2, 0, 2 }, { -1, 0, 1 } };
int[,] gy = new int[,] { { 1, 2, 1 }, { 0, 0, 0 }, { -1, -2, -1 } };
int[,] allPixR = new int[width, height];
int[,] allPixG = new int[width, height];
int[,] allPixB = new int[width, height];
int limit = 128 * 128;
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
var pixel = b.GetPixel(i,j);
allPixR[i, j] = pixel.Red;
allPixG[i, j] = pixel.Green;
allPixB[i, j] = pixel.Blue;
}
}
int new_rx = 0, new_ry = 0;
int new_gx = 0, new_gy = 0;
int new_bx = 0, new_by = 0;
int rc, gc, bc;
for (int i = 1; i < width - 1; i++)
{
for (int j = 1; j < height - 1; j++)
{
new_rx = 0;
new_ry = 0;
new_gx = 0;
new_gy = 0;
new_bx = 0;
new_by = 0;
rc = 0;
gc = 0;
bc = 0;
for (int wi = -1; wi < 2; wi++)
{
for (int hw = -1; hw < 2; hw++)
{
rc = allPixR[i + hw, j + wi];
new_rx += gx[wi + 1, hw + 1] * rc;
new_ry += gy[wi + 1, hw + 1] * rc;
gc = allPixG[i + hw, j + wi];
new_gx += gx[wi + 1, hw + 1] * gc;
new_gy += gy[wi + 1, hw + 1] * gc;
bc = allPixB[i + hw, j + wi];
new_bx += gx[wi + 1, hw + 1] * bc;
new_by += gy[wi + 1, hw + 1] * bc;
}
}
if (new_rx * new_rx + new_ry * new_ry > limit || new_gx * new_gx + new_gy * new_gy > limit || new_bx * new_bx + new_by * new_by > limit)
{
PixelData p = new PixelData(Color.Black);
bb.SetPixel(i, j, p);
}
else
{
PixelData p = new PixelData(Color.Transparent);
bb.SetPixel(i, j, p);
}
}
}
b.UnlockBitmap();
bb.UnlockBitmap();
return result;
}
을하지만, 이미지가 전혀 변경되지 않습니다. 내 코드의 어느 부분이 실수인지 조언 해 주시겠습니까?
+1. FastBitmap 주셔서 감사합니다. Bitmap.GetPixel의 끔찍한 감속을 발견 한 후 항상 수동으로 LockBits를 사용했습니다. – Samuel
나는 도형을 오래 전에 그리는 프로그램을 만들었습니다. 예, Set 및 GetPixel은 매우 느립니다. 그러나 FastBitmap과 같은 클래스를 사용하면 쉽게 해결할 수 있습니다. 포인터 로직을 숨 깁니다. – Carra
오류에 대한 내 문제가 해결되었습니다. 위의 함수에 FastBitmap 클래스를 구현할 수 있지만 이미지가 전혀 변경되지 않습니다. – christ2702