Plus Rapide Sobel Détection De Bord C#
Je veux faire un programme qui implémente sobel détection de bord.
C'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 < 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;
}
je veux à l'aide de lockbits donc, mon programme peut courir plus vite, mais j'ai toujours pas à comprendre comment l'utiliser.
quelqu'un pourrait-il donner une explication ou un exemple de code?
- Votre code d'origine avait l'algorithme de Sobel, mais a été lente en raison de
GetPixel
etSetPixel
. Maintenant, votre code doit utiliserLockBits
sur les deux images (entrée et sortie) et accéder aux pixels par(x,y)
comme je l'ai démontré dans ma réponse. Vous êtes très proche maintenant - n'abandonnez pas. - pourriez-vous me dire, dont l'une de la partie de mon code devrait échange de lockbits? je me sens très à la dépression. thx
Vous devez vous connecter pour publier un commentaire.
Vous avez vraiment besoin d'utiliser
LockBits
au lieu deGetPixel
etSetPixel
.Ainsi, vous créez un
BitmapData
objet qui contient toutes les données de pixels:Ensuite, vous pouvez obtenir l'adresse de la première ligne de balayage (c'est à dire la première ligne de pixels):
Maintenant, vous avez deux choix. Si vous êtes heureux de marquer votre fonction en tant que
unsafe
ensuite, vous pouvez accéder aux pixels directement en utilisant l'arithmétique des pointeurs, comme cequi vous donne un pointeur vers le premier octet d'une de pixels RVB (en supposant que 24bpp). Ensuite, vous pouvez accéder à un pixel individuel à
(x,y)
en utilisant l'arithmétique des pointeurs. D'abord vous déterminez le nombre d'octets par pixel (si vous ne la connaissez pas déjà)Puis calculer l'indice pour le pixel que vous voulez
Cela vous donne
unsafe
accès aux pixels dans unBitmap
que vous pouvez faire pour l'entrée et la sortie des bitmaps pour la vitesse la plus rapide. Notez que pour utiliser code non sécurisé, vous avez besoin de marque de votre fonction comme dangereux et modifier les propriétés de votre projet.Si vous ne souhaitez pas utiliser
unsafe
de code, vous pouvez accélérer les choses en copiant toutes les données de pixels d'unebyte
tableau avant le traitement puis la copier par la suite. Comme le MSDN exemple montréQuelle que soit la méthode que vous utilisez, lorsque vous avez terminé avec les données de pixel, vous doit de le libérer à l'aide de
UnlockBits