Comment auto recadrer une image?
Je suis en train de faire une application de numérisation. Cette application va scanner le document et l'affichage de l'image dans une zone de l'image. Le problème, je suis confronté à des images (Documents de l'image qui a gardé dans le scanner ou dire "réel" de l'image) est l'affichage à l'intérieur d'une image d'arrière-plan (couleur d'arrière-plan est également en train de changer) sa ressembler à cette image.
J'ai essayé beaucoup de choses mais rien ne me donnant un résultat parfait, j'ai essayé avec un forge.net. Voici le code que j'ai essayé.
public static System.Drawing.Image AforgeAutoCrop(Bitmap selectedImage)
{
Bitmap autoCropImage = null;
try
{
autoCropImage = selectedImage;
//create grayscale filter (BT709)
Grayscale filter = new Grayscale(0.2125, 0.7154, 0.0721);
Bitmap grayImage = filter.Apply(autoCropImage);
//create instance of skew checker
DocumentSkewChecker skewChecker = new DocumentSkewChecker();
//get documents skew angle
double angle = skewChecker.GetSkewAngle(grayImage);
//create rotation filter
RotateBilinear rotationFilter = new RotateBilinear(-angle);
rotationFilter.FillColor = Color.White;
//rotate image applying the filter
Bitmap rotatedImage = rotationFilter.Apply(grayImage);
new ContrastStretch().ApplyInPlace(grayImage);
new Threshold(100).ApplyInPlace(grayImage);
BlobCounter bc = new BlobCounter();
bc.FilterBlobs = true;
//bc.MinWidth = 500;
//bc.MinHeight = 500;
bc.ProcessImage(grayImage);
Rectangle[] rects = bc.GetObjectsRectangles();
MemoryStream writeName = new MemoryStream();
if (rects.Length == 0)
{
System.Windows.Forms.MessageBox.Show("No rectangle found in image ");
}
else if (rects.Length == 1)
{
Bitmap cropped = new Crop(rects[0]).Apply(autoCropImage);
autoCropImage = cropped;
//pictureBox1.Image = cropped;
}
else if (rects.Length > 1)
{
//get largets rect
Console.WriteLine("Using largest rectangle found in image ");
var r2 = rects.OrderByDescending(r => r.Height * r.Width).ToList();
//var r2 = rects.OrderByDescending(r => r.Height < 1500 && r.Width < 1000).ToList();
Bitmap cropped = new Crop(r2[0]).Apply(autoCropImage);
Graphics gr = Graphics.FromImage(cropped);
gr.DrawRectangles(new Pen(Color.Red), rects);
autoCropImage = cropped;
//pictureBox1.Image = cropped;
}
else
{
Console.WriteLine("Huh? on image ");
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
return autoCropImage;
}
"Pas de résultat" est très loin d'être une véritable question de droit de vote pour fermer. En passant, je ne voudrais pas essayer quelque chose comme ça à l'aide de GDI+, mieux utiliser un outil comme ImageMagick (imagemagick.org/script/index.php), ou le correspondant .NET API (imagemagick.codeplex.com)
il est très utile merci. J'ai essayé AForge au lieu de ImageMagick. Merci encore.
il est très utile merci. J'ai essayé AForge au lieu de ImageMagick. Merci encore.
OriginalL'auteur Rakesh | 2012-08-02
Vous devez vous connecter pour publier un commentaire.
Je suppose que vous avez toujours une image avec un distinctes de premier plan et d'arrière-plan, et vous voulez faire quelque chose comme un zélé de la récolte de l'arrière-plan.
Dans ce cas, je voudrais faire quelque chose de similaire à la région ayant progressé de manière. Commencer à un point où vous avez la garantie d'un pixel d'arrière-plan.
Obtenir une autre image (ou d'une matrice ou quoi que ce soit), initialisé à zéros, et de définir le pixel correspondant de la valeur à 1. Si tous les pixels voisins sont à une valeur de seuil de l'image d'origine, se déplacer vers eux de manière récursive et de définir leurs valeurs de pixels à 0.
Qui est:
Maintenant, la carte doit avoir tous les pixels du fond 1 et présente que 2. Vous pouvez changer cela pour permettre à de multiples objets et les seuils et ainsi de suite. Vous pourriez seuil à un changement de valeur plutôt qu'une valeur absolue.
Ensuite, il suffit de trouver le min et le max de x et de y et de stocker les pixels de cette gamme à une nouvelle image.
J'espère que cela allait dans le sens de ce que vous avez besoin.
Look here pour la manipulation de pixels. Regardez ici pour le recadrage. Le reste devrait être assez simple à traduire en C/C++/C# si vous êtes assez familier avec eux.
Ok je vais essayer votre solution et sera mis à jour ici. En espérant que cela va résoudre mon problème ..Merci Bill..:-)
OriginalL'auteur Bill
j'ai changé votre code à cela et fonctionne bien.
grâce
OriginalL'auteur mostafa hk
Vous pouvez utiliser AForge.NET Le Traitement De L'Image
Détecteur de bord: http://www.aforgenet.com/framework/features/edge_detectors_filters.html
Alors u peut utiliser EdgeDetector de trouver les frontières de votre livre: aforgenet.com/framework/features/edge_detectors_filters.html
OriginalL'auteur Nickon
Mostafa HK code a fonctionné pour moi. J'utilise cette fonction pour pré-traiter YouTube vignettes de bande de bords noirs, un problème commun), et j'ai dû faire quelques corrections mineures à son code:
1) se débarrasser de la rotation (pas sûr de ce que c'était)
2) j'ai abaissé le seuil de 100 à 25.
3) Lors du clonage de l'image finale, j'ai effectuer le clone de l'original autoCropImage et pas le rotatedImage (encore une fois, pas sûr de ce que la rotation a été pour).
Je pense que le vrai secret de la sauce était d'abaisser le seuil. Cela a réduit le nombre de rectangles le code a été de trouver, et je suis maintenant correctement découpé toutes les formes de vignettes (grand écran avec du noir sur le haut et le bas ET en plein écran noir sur la gauche et la droite).
https://stackoverflow.com/search?q=youtube+vignette+culture
OriginalL'auteur Frog Pr1nce