Détection Sobel Edge C # la plus rapide

Je veux faire un programme qui implémente la détection de bord sobel. Ceci est mon 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; 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  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; } 

Je veux utiliser lockbits pour que mon programme puisse fonctionner plus rapidement, mais je ne comprends toujours pas comment l’utiliser. Quelqu’un pourrait-il donner une explication ou un exemple de code?

Vous devez vraiment utiliser LockBits au lieu de GetPixel et SetPixel .

Vous créez donc un object BitmapData contenant toutes les données de pixels:

 // lock the 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); 

Ensuite, vous pouvez obtenir l’adresse de la première ligne de balayage (c’est-à-dire la première ligne de pixels):

 IntPtr ptr = bmpData.Scan0; 

Maintenant vous avez deux choix. Si vous souhaitez marquer votre fonction comme unsafe vous pouvez accéder aux pixels directement à l’aide de l’arithmétique de pointeur, comme ceci

 byte* pPixels = (byte*)ptr.ToPointer(); 

qui vous donne un pointeur sur le premier octet d’un pixel RVB (en supposant 24bpp). Vous pouvez ensuite accéder à un pixel individuel en (x,y) aide de l’arithmétique de pointeur. D’abord, vous déterminez le nombre d’octets par pixel (si vous ne le savez pas déjà)

 int nBytesPerPixel = Image.GetPixelFormatSize(original.PixelFormat) / 8; 

Puis calcule l’index au pixel que tu veux

 byte* pPixelAtXY = pPixels + (y * bmpData.Ssortingde) + (x * nBytesPerPixel); 

Cela vous donne un access unsafe sécurisé aux pixels d’une image Bitmap ce que vous pouvez faire pour les bitmaps d’entrée et de sortie pour une vitesse plus rapide. Notez que pour utiliser du code non sécurisé, vous devez marquer votre fonction comme non sécurisée et modifier les propriétés de votre projet .

Si vous ne souhaitez pas utiliser de code unsafe , vous pouvez toujours accélérer les choses en copiant toutes les données de pixels dans un tableau d’ byte avant le traitement, puis en les recopiant. Comme le montre l’exemple MSDN

 // Get the address of the first line. IntPtr ptr = bmpData.Scan0; // Declare an array to hold the bytes of the bitmap. int bytes = Math.Abs(bmpData.Ssortingde) * bmp.Height; byte[] rgbValues = new byte[bytes]; // Copy the RGB values into the array. System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes); // Set every third value to 255. A 24bpp bitmap will look red. for (int counter = 2; counter < rgbValues.Length; counter += 3) rgbValues[counter] = 255; // Copy the RGB values back to the bitmap System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes); 

Quelle que soit la méthode que vous utilisez, lorsque vous avez terminé avec les données en pixels, vous devez les libérer en utilisant UnlockBits

 original.UnlockBits(bmpData);