Edge Detection (including edge detection algorithms for operators such as Robert ts, Sobel, Prewitt, and Kirsch)
Public class edgedetect: imageinfo
{
/*************************************** *********************
*
* Robert ts, Sobel, Prewitt, Kirsch, gausslaplacian
* Horizontal detection, vertical detection, edge enhancement, and edge balancing
*
**************************************** ********************/
///
/// Perform gradient operations on the two images
///
///Bitmap 1
///Bitmap 2
///
Private bitmap gradient (Bitmap B1, bitmap B2)
{
Int width = b1.width;
Int Height = b1.height;
Bitmapdata data1 = b1.lockbits (New rectangle (0, 0, width, height ),
Imagelockmode. readwrite, pixelformat. format32bppargb );
Bitmapdata data2 = b2.lockbits (New rectangle (0, 0, width, height ),
Imagelockmode. readonly, pixelformat. format32bppargb );
Unsafe
{
Byte * P1 = (byte *) data1.scan0;
Byte * P2 = (byte *) data2.scan0;
Int offset = data1.stride-width * BPP;
For (INT y = 0; y {
For (INT x = 0; X {
For (INT I = 0; I {
Int power = (INT) math. SQRT (P1 [I] * P1 [I] + P2 [I] * P2 [I]);
P1 [I] = (byte) (power> 255? 255: power );
} // I
P1 + = BPP;
P2 + = BPP;
} // X
P1 + = offset;
P2 + = offset;
} // Y
}
B1.unlockbits (data1 );
B2.unlockbits (data2 );
Bitmap dstimage = (Bitmap) b1.clone ();
B1.dispose ();
B2.dispose ();
Return dstimage;
} // End of gradient
///
/// Perform Edge Detection Based on the Roberts operator
///
///Bitmap stream
///
Public Bitmap (Bitmap B)
{
Int width = B. width;
Int Height = B. height;
Bitmap dstimage = new Bitmap (width, height );
Bitmapdata srcdata = B. lockbits (New rectangle (0, 0, width, height ),
Imagelockmode. readonly, pixelformat. format32bppargb );
Bitmapdata dstdata = dstimage. lockbits (New rectangle (0, 0, width, height ),
Imagelockmode. writeonly, pixelformat. format32bppargb );
Int stride = srcdata. stride;
Int offset = stride-width * BPP;
Unsafe
{
Byte * src = (byte *) srcdata. scan0;
Byte * DST = (byte *) dstdata. scan0;
Int A, B; // A (x-1, Y-1) B (X, Y-1)
Int C, D; // C (x-1, Y) d (x, y)
// Point to the first line
SRC + = stride;
DST + = stride;
// Do not process the top and left
For (INT y = 1; y {
// Point to the first column of each row
SRC + = BPP;
DST + = BPP;
For (INT x = 1; X {
For (INT I = 0; I {
A = SRC [I-stride-bpp];
B = SRC [I-stride];
C = SRC [I-bpp];
D = SRC [I];
DST [I] = (byte) (math. SQRT (a-d) * (a-d) + (B-c) * (B-c )));
} // I
DST [3] = SRC [3];
SRC + = BPP;
DST + = BPP;
} // X
SRC + = offset;
DST + = offset;
} // Y
}
B. unlockbits (srcdata );
Dstimage. unlockbits (dstdata );
B. Dispose ();
Return dstimage;
} // End of Robert TS
///
/// Perform Edge Detection Based on the Sobel operator
///
///Bitmap stream
///
Public bitmap Sobel (Bitmap B)
{
Matrix3x3 M = new matrix3x3 ();
//-1-2-1
// 0 0 0
// 1 2 1
M. INIT (0 );
M. topleft = M. topright =-1;
M. bottomleft = M. bottomright = 1;
M. topmid =-2;
M. bottommid = 2;
Bitmap b1 = M. convolute (Bitmap) B. Clone ());
//-1 0 1
//-2 0 2
//-1 0 1
M. INIT (0 );
M. topleft = M. bottomleft =-1;
M. topright = M. bottomright = 1;
M. midleft =-2;
M. midright = 2;
Bitmap b2 = M. convolute (Bitmap) B. Clone ());
// 0 1 2
//-1 0 1
//-2-1 0
M. INIT (0 );
M. topmid = M. midright = 1;
M. midleft = M. bottommid =-1;
M. topright = 2;
M. bottomleft =-2;
Bitmap B3 = M. convolute (Bitmap) B. Clone ());
//-2-1 0
//-1 0 1
// 0 1 2
M. INIT (0 );
M. topmid = M. midleft =-1;
M. midright = M. bottommid = 1;
M. topleft =-2;
M. bottomright = 2;
Bitmap B4 = M. convolute (Bitmap) B. Clone ());
// Gradient operation
B = gradient (b1, b2), gradient (B3, b4 ));
B1.dispose (); b2.dispose (); b3.dispose (); b4.dispose ();
Return B;
} // End of Sobel
///
/// Perform edge detection by Prewitt operator
///
///Bitmap stream
///
Public bitmap Prewitt (Bitmap B)
{
Matrix3x3 M = new matrix3x3 ();
//-1-1-1
// 0 0 0
// 1 1 1
M. INIT (0 );
M. topleft = M. topmid = M. topright =-1;
M. bottomleft = M. bottommid = M. bottomright = 1;
Bitmap b1 = M. convolute (Bitmap) B. Clone ());
//-1 0 1
//-1 0 1
//-1 0 1
M. INIT (0 );
M. topleft = M. midleft = M. bottomleft =-1;
M. topright = M. midright = M. bottomright = 1;
Bitmap b2 = M. convolute (Bitmap) B. Clone ());
//-1-1 0
//-1 0 1
// 0 1 1
M. INIT (0 );
M. topleft = M. midleft = M. topmid =-1;
M. bottommid = M. bottomright = M. midright = 1;
Bitmap B3 = M. convolute (Bitmap) B. Clone ());
// 0 1 1
//-1 0 1
//-1-1 0
M. INIT (0 );
M. topmid = M. topright = M. midright = 1;
M. midleft = M. bottomleft = M. bottommid =-1;
Bitmap B4 = M. convolute (Bitmap) B. Clone ());
// Gradient operation
B = gradient (b1, b2), gradient (B3, b4 ));
B1.dispose (); b2.dispose (); b3.dispose (); b4.dispose ();
Return B;
} // End of Prewitt
///
/// Perform edge detection by the kirsch operator
///
///Bitmap stream
///
Public bitmap Kirsch (Bitmap B)
{
Matrix3x3 M = new matrix3x3 ();
// 5 5 5
//-3 0-3
//-3-3-3
M. INIT (-3 );
M. Center = 0;
M. topleft = M. topmid = M. topright = 5;
Bitmap b1 = M. convolute (Bitmap) B. Clone ());
//-3 5 5
//-3 0 5
//-3-3-3
M. INIT (-3 );
M. Center = 0;
M. topmid = M. topright = M. midright = 5;
Bitmap b2 = M. convolute (Bitmap) B. Clone ());
//-3-3 5
//-3 0 5
//-3-3 5
M. INIT (-3 );
M. Center = 0;
M. topright = M. midright = M. bottomright = 5;
Bitmap B3 = M. convolute (Bitmap) B. Clone ());
//-3-3-3
//-3 0 5
//-3 5 5
M. INIT (-3 );
M. Center = 0;
M. midright = M. bottomright = M. bottommid = 5;
Bitmap B4 = M. convolute (Bitmap) B. Clone ());
//-3-3-3
//-3 0-3
// 5 5 5
M. INIT (-3 );
M. Center = 0;
M. bottomleft = M. bottommid = M. bottomright = 5;
Bitmap B5 = M. convolute (Bitmap) B. Clone ());
//-3-3-3
// 5 0-3
// 5 5-3
M. INIT (-3 );
M. Center = 0;
M. midleft = M. bottomleft = M. bottommid = 5;
Bitmap B6 = M. convolute (Bitmap) B. Clone ());
// 5-3-3
// 5 0-3
// 5-3-3
M. INIT (-3 );
M. Center = 0;
M. topleft = M. midleft = M. bottomleft = 5;
Bitmap B7 = M. convolute (Bitmap) B. Clone ());
// 5 5-3
// 5 0-3
//-3-3-3
M. INIT (-3 );
M. Center = 0;
M. topleft = M. midleft = M. topmid = 5;
Bitmap B8 = M. convolute (Bitmap) B. Clone ());
// Gradient operation
Bitmap B9 = gradient (b1, b2), gradient (B3, b4 ));
Bitmap B10 = gradient (B5, B6), gradient (B7, B8 ));
B = gradient (B9, B10 );
B1.dispose (); b2.dispose (); b3.dispose (); b4.dispose ();
B5.dispose (); b6.dispose (); b7.dispose (); b8.dispose ();
B9.dispose (); b10.dispose ();
Return B;
} // End of Kirsch
///
/// Perform Edge Detection Based on the gausslaplacian Operator
///
//////
Public bitmap gausslaplacian (Bitmap B)
{
Int [,] kernel = {
{-2,-4,-4,-4,-2 },
{-4, 0, 8, 0,-4 },
{-4, 8, 24, 8,-4 },
{-4, 0, 8, 0,-4 },
{-2,-4,-4,-4,-2}
};
Matrixnxn M = new matrixnxn ();
M. kernel = kernel;
Return M. convolute (B );
} // End of gausslaplacian
///
/// Perform Edge Detection Based on the horizontal edge detection operator
///
//////
Public bitmap edgedetecthorizontal (Bitmap B)
{
Int [,] kernel = {
{0, 0, 0, 0, 0, 0, 0 },
{0, 0, 0, 0, 0, 0, 0 },
{-1,-1,-1,-1,-1,-1,-1 },
{0, 0, 0, 0, 0, 0, 0 },
{1, 1, 1, 1, 1, 1, 1 },
{0, 0, 0, 0, 0, 0, 0 },
{0, 0, 0, 0, 0, 0, 0 },
};
Matrixnxn M = new matrixnxn ();
M. kernel = kernel;
Return M. convolute (B );
} // End of edgedetecthorizontal
///
/// Perform edge detection by vertical edge detection operators
///
//////
Public bitmap edgedetectvertical (Bitmap B)
{
Int [,] kernel = {
{0, 0,-1, 0, 1, 0, 0 },
{0, 0,-1, 0, 1, 0, 0 },
{0, 0,-1, 0, 1, 0, 0 },
{0, 0,-1, 0, 1, 0, 0 },
{0, 0,-1, 0, 1, 0, 0 },
{0, 0,-1, 0, 1, 0, 0 },
{0, 0,-1, 0, 1, 0, 0 },
};
Matrixnxn M = new matrixnxn ();
M. kernel = kernel;
Return M. convolute (B );
} // End of edgedetectvertical
///
/// Edge enhancement
///
///Bitmap stream
///Threshold
///
Public bitmap edgeenhance (Bitmap B, int threshold)
{
Int width = B. width;
Int Height = B. height;
Bitmap dstimage = (Bitmap) B. Clone ();
Bitmapdata srcdata = B. lockbits (New rectangle (0, 0, width, height ),
Imagelockmode. readonly, pixelformat. format32bppargb );
Bitmapdata dstdata = dstimage. lockbits (New rectangle (0, 0, width, height ),
Imagelockmode. writeonly, pixelformat. format32bppargb );
// Actual Image Processing Area
// Ignore the leftmost column and rightmost column
// Ignore the top and bottom rows
Int recttop = 1;
Int rectbottom = height-1;
Int rectleft = 1;
Int rectright = width-1;
Unsafe
{
Byte * src = (byte *) srcdata. scan0;
Byte * DST = (byte *) dstdata. scan0;
Int stride = srcdata. stride;
Int offset = stride-width * BPP;
Int pixel = 0;
Int maxpixel = 0;
// Point to 1st rows
SRC + = stride;
DST + = stride;
For (INT y = recttop; y {
// Point to 1st pixels in each row
SRC + = BPP;
DST + = BPP;
For (INT x = rectleft; X {
// Alpha
DST [3] = SRC [3];
// Process the three-point volume of B, G, and r
For (INT I = 0; I {
// Top right-bottom left
Maxpixel = SRC [I-stride + BPP]-Src [I + stride-bpp];
If (maxpixel // top left-bottom right
Pixel = SRC [I-stride-bpp]-Src [I + stride + BPP];
If (pixel if (pixel> maxpixel) maxpixel = pixel;
// Top-bottom
Pixel = SRC [I-stride]-Src [I + stride];
If (pixel if (pixel> maxpixel) maxpixel = pixel;
// Left-right
Pixel = SRC [I-bpp]-Src [I + BPP];
If (pixel if (pixel> maxpixel) maxpixel = pixel;
// Threshold Value Determination
If (maxpixel
DST [I] = (byte) maxpixel;
}
// Move one pixel to the backend
SRC + = BPP;
DST + = BPP;
} // X
// Move to the next row
// Note that you need to move one more column here, because there is still one column on the rightmost side.
SRC + = offset + BPP;
DST + = offset + BPP;
} // Y
}
// B. unlockbits (srcdata );
Dstimage. unlockbits (dstdata );
B. Dispose ();
Return dstimage;
} // End of edgeenhance
}
This article is transferred from
Http://blog.csdn.net/wtuyzh/archive/2006/07/05/881518.aspx