image processing - Fastest Sobel Edge Detection C# -
i want make program implements sobel edge detection. code :
private bitmap sobeledgedetect(bitmap ori) { 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; (int = 0; < width; i++) { (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; (int = 1; < b.width - 1; i++) { (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; (int wi = -1; wi < 2; wi++) { (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); //bb.setpixel (i, j, color.fromargb(allpixr[i,j],allpixg[i,j],allpixb[i,j])); else bb.setpixel(i, j, color.transparent); } } return bb; }
i want using lockbits program can run faster, still not understand how use it. give explanation or example code?
you need use lockbits
instead of getpixel
, setpixel
.
so create bitmapdata
object contains of pixel data:
// lock input bitmap's bits system.drawing.imaging.bitmapdata bmpdata = original.lockbits(new rectangle(0, 0, original.width, original.height), system.drawing.imaging.imagelockmode.read, original.pixelformat);
then, can address of first scan line (i.e. first row of pixels):
intptr ptr = bmpdata.scan0;
now have 2 choices. if you're happy mark function unsafe
can access pixels directly using pointer arithmetic, this
byte* ppixels = (byte*)ptr.topointer();
which gives pointer first byte of rgb pixel (assuming 24bpp). can access individual pixel @ (x,y)
using pointer arithmetic. first determine how many bytes per pixel (if don't know)
int nbytesperpixel = image.getpixelformatsize(original.pixelformat) / 8;
then calculate index pixel want
byte* ppixelatxy = ppixels + (y * bmpdata.stride) + (x * nbytesperpixel);
this gives unsafe
access pixels in bitmap
can input , output bitmaps fastest speed. note use unsafe code, need mark function unsafe , edit project properties.
if don't want use unsafe
code, can still speed things copying of pixel data byte
array before processing , copy afterwards. msdn example showed
// address of first line. intptr ptr = bmpdata.scan0; // declare array hold bytes of bitmap. int bytes = math.abs(bmpdata.stride) * bmp.height; byte[] rgbvalues = new byte[bytes]; // copy rgb values array. system.runtime.interopservices.marshal.copy(ptr, rgbvalues, 0, bytes); // set every third value 255. 24bpp bitmap red. (int counter = 2; counter < rgbvalues.length; counter += 3) rgbvalues[counter] = 255; // copy rgb values bitmap system.runtime.interopservices.marshal.copy(rgbvalues, 0, ptr, bytes);
whichever method use, when have finished pixel data, must release using unlockbits
original.unlockbits(bmpdata);
Comments
Post a Comment