Click here to Skip to main content
15,894,740 members
Please Sign up or sign in to vote.
3.00/5 (3 votes)
See more:
Hi:
I have developed code to scan different sections of an image on background panel, after Otsu Thresholding has been applied to the image, and add up pixel values. After this it should evaluate whether the values are above or below a set threshold value. If any of those sections are above the threshold value a rectangle should be drawn around the sections.

The code below shows the array population and scan and a poor attempt at drawing on the image.
C#
Bitmap myImage;
myImage = (Bitmap)Image.FromFile(openFileDialog1.FileName);
panel1.BackgroundImage = myImage;

// Array for keeping the sums of each row of pixels
float[] resultArray = new float[myImage.Height];

// Populate the array with data from each row of pixels, using the brightness value
for (int i = 0; i > 26 && i < 39; i++)
{

    float value1 = 0;
    for (int j = 0; j > 22 && j < 35; j++)
    {
        value1 += myImage.GetPixel(j, i).GetBrightness();
    }
    resultArray[i] = value1;

    if (value1 > 0)
    {

        Pen pen = new Pen(Color.Red, 2);
        Graphics g = panel1.CreateGraphics();
        g.DrawRectangle(pen, 10, 10, 50, 50);
    }


This is just one array for the first section. I guess the best thing to do would be to create a function for the drawing part and just pass it the values of the arrays from a switch, case1, case2, etc. But my main concern is getting help to draw around the section detailed above. I have set the if condition to value > 0 for now just to be sure and test it works.
Thank you.
Posted
Comments
Sergey Alexandrovich Kryukov 25-Feb-13 12:24pm    
You are doing it wrong. It will get you nowhere, because if unacceptable performance. SetPixel/SetPixel is too slow.
—SA
Sergey Alexandrovich Kryukov 25-Feb-13 12:25pm    
And don't create Graphics...
—SA
defunktlemon 25-Feb-13 12:30pm    
you want me to use LockPixels?
Sergey Alexandrovich Kryukov 25-Feb-13 13:47pm    
No, you want to use LockPixels. Of course. :-)
I answered, please see Solution 1.
—SA

1 solution

Yes, if you really need to access individual pixels, the only reasonable way to go is using System.Drawing.Bitmap.LockBits:
http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.lockbits.aspx[^].

Now, if you are creating the instance of Graphics somewhere using its constructor and draw, the graphics will not persist on screen. You need to override System.Windows.Graphics.Control.OnPaint or handle the event System.Windows.Graphics.Control.Paint and do all your rendering in the handler, using the instance of Graphics passed to the handler in the event arguments. Please see my past answers:
What kind of playful method is Paint? (DataGridViewImageCell.Paint(...))[^] (the background is explained here),
Drawing Lines between mdi child forms[^],
capture the drawing on a panel[^],
How to speed up my vb.net application?[^].

—SA
 
Share this answer
 
v2
Comments
defunktlemon 25-Feb-13 16:34pm    
ok. I have gotten the lockbits, or lickbits as you like to call it :), into the program.

But no image loads into the panel? Can I use a panel or should it be picturebox? If I am not mistaken you are not a fan of picturebox as much as get / set pixels :)
Sergey Alexandrovich Kryukov 25-Feb-13 16:42pm    
Fist, not need to use PictureBox, ever. This is not about being a fun or not. This control is totally redundant in principle, you can do everything without it. It just depends on what you are doing. Is something simple, it just a read-to-use control, can simplify things; in other cases help you at all, if you modify an image in any ways, only adds a hassle...
What is image loads? No. Due to the need for LockBits, you just an image as an intermediate container of data. When the image is done, you can draw it using Graphics.DrawImage, in OnPaint or Paint handler, or put this image in a PictureBox...
Will you accept the answer formally now (green button)?
—SA
defunktlemon 25-Feb-13 16:41pm    
I have a question about this method Sergey. As stated in the original problem above, I would like for this to scan the image in a few different sections and draw around those sections which have a certain pixel value higher than a threshold set. It is possible to do that with this method, right?
Sergey Alexandrovich Kryukov 25-Feb-13 16:43pm    
I understand. This algorithm really requires access to individual bits, that's why I recommended to use LockBits (thanks for a fix of my typo; I updated the text).
—SA
defunktlemon 25-Feb-13 16:50pm    
I think this may be way too advanced for me - i'm just a newbie. Don't you think it is better for a newbie to not worry about performance so much and just use the Get / Set pixels as they are easier?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900