2011-09-03 2 views
0

Je dessine région ROI rectangulaire en assombrissant la zone à l'extérieur de celui-ci comme dans cette image http://www.codeproject.com/script/Membership/Uploads/4613314/roi.jpgOptimisation de la région du dessin d'intérêt (ROI) dans l'image

Mais image.MakeTransparent prend trop de temps. Quel est le meilleur moyen d'augmenter la vitesse de dessin?

void DrawRoi(Bitmap Image, RectangleF rect) 
{ 
     Rectangle roi = new Rectangle(); 

     roi.X = (int)((float)Image.Width * rect.X); 
     roi.Y = (int)((float)Image.Height * rect.Y); 
     roi.Width = (int)((float)Image.Width * rect.Width); 
     roi.Height = (int)((float)Image.Height * rect.Height); 

     Stopwatch timer = new Stopwatch(); 
     timer.Start(); 
     // graphics manipulation takes about 240ms on 1080p image 
     using (Bitmap roiMaskImage = CreateRoiMaskImage(ImageWithRoi.Width, ImageWithRoi.Height, roi)) 
     { 
       using (Graphics g = Graphics.FromImage(ImageWithRoi)) 
       {         
         g.DrawImage(Image, 0, 0); 
         g.DrawImage(roiMaskImage, 0, 0); 
         Pen borderPen = CreateRoiBorderPen(ImageWithRoi); 
         g.DrawRectangle(borderPen, roi); 
       } 
     } 
     Debug.WriteLine("roi graphics: {0}ms", timer.ElapsedMilliseconds); 
     this.imagePictureBox.Image = ImageWithRoi; 
} 

Bitmap CreateRoiMaskImage(int width, int height, Rectangle roi) 
{ 
     Bitmap image = new Bitmap(width, height, PixelFormat.Format32bppArgb); 
     using (Graphics g = Graphics.FromImage(image)) 
     { 
       SolidBrush dimBrush = new SolidBrush(Color.FromArgb(64, 0, 0, 0)); 
       g.FillRectangle(dimBrush, 0, 0, width, height); 
       SolidBrush roiBrush = new SolidBrush(Color.Red); 
       g.FillRectangle(roiBrush, roi); 
       image.MakeTransparent(Color.Red); 
       return image; 
     }     
} 

Pen CreateRoiBorderPen(Bitmap image) 
{ 
     float width = ((float)(image.Width + image.Height) * 2.5f)/(float)(640 + 480); 
     if (width < 1.0f) 
       width = 1.0f; 
     Pen pen = new Pen(Color.FromArgb(255, 0, 255, 0), width); 
     return pen; 
} 
+0

GPU? 1080p semble trop pour le traitement sur le processeur, esp. avec C#. –

+0

non, je voulais dire opération sur les données d'image brutes, même sur 640x480, il faut environ 36ms sur i3 Intel –

Répondre

1

Je ne vois aucune raison d'appeler .MakeTransparent. Lorsque vous créez votre image de masque

Bitmap image = new Bitmap(width, height, PixelFormat.Format32bppArgb); 

est déjà transparent. Il vaudrait mieux dessiner le dimBrush en quatre rectangles séparés (zones au-dessus/en dessous/à gauche de/à droite de ROI) à la place et éviter de dessiner dans la zone qui est déjà transparente!

+0

merci de suggérer que je vais essayer votre suggestion et de revenir à vous –

2

Ne manipulez pas l'image du tout. Dessinez simplement la "gradation" sur le dessus de votre image. Vous pouvez obtenir le même effet par exemple par

1) Dessin d'une grande région semi-transparente sur toute l'image, avec la région clip ensemble pour votre retour sur investissement

// Assume for simplicity the image is size w*h, and the graphics is the same size. 
// The ROI is a rectangle named roiRect. 
g.DrawImageUnscaled(image, 0, 0 , w, h); 
g.SetClip(roiRect); 
g.FillRectangle(new SolidBrush(Color.FromArgb(128, Color.Black)), 0, 0, w, h); 
g.ResetClip();  

2) Dessin l'image, puis le rectangle de gradation, puis la partie roi de l'image en plus de cela.

3) Dessiner 4 rectangles séparés haut/droit/gauche/bas pour omettre votre ROI.

+0

Je me demande quelle approche sera la plus rapide, pourriez-vous mettre tout extrait de code pour 1) au moins –

+0

Je ne sais pas lequel sera le plus rapide. Probablement # 1. Ajout d'un exemple de code (que je n'ai pas essayé, mais il montre l'idée générale). –

0

Jetez un oeil à la classe WriteableBitmap. Dans la méthode WritePixels, vous pouvez définir une ROI avec un Int32Rect.