Click here to Skip to main content
14,447,156 members
Rate this:
Please Sign up or sign in to vote.
See more:
i make a code for this algorithm
(my picture have been greyscale before it)
1. get value pixel (0,0) for seed pixel
2. compare value seed pixel with one neighbor pixel
3. if value of no.3 less than treshold (T), go to next pixel and go to no.2
4. if value of no.3 more than treshold (T), change pixel to white(also for next 10 pixel), and get new seed value pixel.

this is my code

private void button4_Click(object sender, EventArgs e)
        {
            // GDI+ still lies to us - the return format is BGR, NOT RGB.
            BitmapData bmData = RImage.LockBits(new Rectangle(0, 0, RImage.Width, RImage.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

            int stride = bmData.Stride;
            System.IntPtr Scan0 = bmData.Scan0;

            unsafe
            {
                byte* p = (byte*)(void*)Scan0;

                int nOffset = stride - RImage.Width * 3;

                for (int y = 0; y < RImage.Height; ++y)
                {                   
                    for (int x = 0; x < RImage.Width; ++x)
                    {  
                        if (x == 0)
                        {
                            //get value of seed pixel if x==0
                            Color col = new Color();
                            col = RImage.GetPixel(x, y);
                            seedR = Convert.ToByte(col.R.ToString());
                            seedG = Convert.ToByte(col.G.ToString());
                            seedB = Convert.ToByte(col.B.ToString());
                        }
                        //compare value seed pixel and pixel now
                        if ((seedR - p[0] >= tred) || (p[0] - seedR >= tred))
                        {
                            //change value pixel now
                            p[0] = p[1] = p[2] = 0;
                            //change value pixel for next 10 pixel
                            for (x = (x+1); x <= 10; ++x)
                            {
                                p[0] = p[1] = p[2] = 0;                                
                            }
                            //get new value of new seed pixel
                            Color col = new Color();
                            col = RImage.GetPixel(x, y);
                            seedR = Convert.ToByte(col.R.ToString());
                            seedG = Convert.ToByte(col.G.ToString());
                            seedB = Convert.ToByte(col.B.ToString());
                        }                        
                    }
                    p += nOffset;
                }
            }

            RImage.UnlockBits(bmData);
        }



but this code error if running
what false with my code??
(this program for segmented lesi skin cancer)
Posted
Comments
Pete O'Hanlon 30-Nov-10 7:37am
   
What error do you get? Where does this error occur?
gunkrr 30-Nov-10 7:44am
   
vshost.exe has stopped working

in line
seedR = Convert.ToByte(col.R.ToString());
seedG = Convert.ToByte(col.G.ToString());
seedB = Convert.ToByte(col.B.ToString());

before it i use this code but also same error i get
seedR = col.R;
seedG = col.G;
seedB = col.B;

this code i mean for getting value of pixel
Rate this:
Please Sign up or sign in to vote.

Solution 2

First of all you dont need:
Color col = new Color();

because GetPixel(x,y) will return instance of Color class.

You can not use GetPixel() after you call LockBits() on same bitmap. That's why you get memory errors.

One solution is to use 'safe' code - do not call LockBits() and use GetPixel() to read from bitmap and SetPixel() to write to it. This can be slow on larger bitmaps, but you don't have to worry about bits per pixel (GDI does that).

Faster (unsafe) solution is to call LockBits() and then read pixel data through pointer:
seedR = p[x]
seedR = p[x+1]
seedR = p[x+2]

and write pixel data:
p[x]=p[x+1]=p[x+2]=0

Also your inner loop is not good, change it to something like:
for(int i=0; i<10; i++)
{
    p[x]=p[x+1]=p[x+2]=0; 
    x++;
}


This will only work for 24bpp bitmaps. For any other you'll need more pointer arithmetic :)
   
v2
Comments
gunkrr 30-Nov-10 23:07pm
   
i have correct my code and follow code above

private void button4_Click(object sender, EventArgs e)
{
// GDI+ still lies to us - the return format is BGR, NOT RGB.
BitmapData bmData = RImage.LockBits(new Rectangle(0, 0, RImage.Width, RImage.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;

unsafe
{
byte* p = (byte*)(void*)Scan0;

int nOffset = stride - RImage.Width * 3;

for (int y = 0; y < RImage.Height; ++y)
{
for (int x = 0; x < RImage.Width; ++x)
{
if (x == 0)
{
//RImage.GetPixel(x, y);
seedR = p[x];
seedG = p[x+1];
seedB = p[x+2];
}

if ((seedR - p[x] >= tred) || (p[x] - seedR >= tred))
{
//taruh value p dlu disini
for (int i=1; i <= 5; ++i)
{
p[x] = p[x + 1] = p[x + 2] = 0;
x++;
}

//RImage.GetPixel(x, y);
seedR = p[x];
seedG = p[x + 1];
seedB = p[x + 2];
}
p += 3;
}
p += nOffset;
}
}

RImage.UnlockBits(bmData);
}


but the result i have white area for 1/3 of my image
(i try change value tred but the result same)
whats wrong??
my goal is segmentation my image based or value every near pixel
Rate this:
Please Sign up or sign in to vote.

Solution 1

If vshost has stopped working, this would suggest that you have a memory problem here. As you are using unsafe code, it's quite likely that your code is working with memory that it shouldn't be.
   
Comments
sjelen 30-Nov-10 11:08am
   
Right,
You can not use GetPixel() after you call LockBits() on same bitmap. That's why you get memory errors.
Dalek Dave 30-Nov-10 11:21am
   
Good Call.
Rate this:
Please Sign up or sign in to vote.

Solution 3

This Should Help:

unsafe
            {
                byte* p = (byte*)(void*)Scan0;

                int nOffset = stride - RImage.Width * 3;

                for (int y = 0; y < RImage.Height; ++y)
                {
                    for (int x = 0; x < RImage.Width; ++x)
                    {
                        int offset = y * RImage.Width * 3 + x * 3;
                        if (x == 0)
                        {
                            //get value of seed pixel if x==0
                            Color col = Color.FromArgb(p[offset], p[offset + 1], p[offset + 2]);
                            //col = bmData.GetPixel(x, y);
                            seedR = Convert.ToByte(col.R.ToString());
                            c = Convert.ToByte(col.G.ToString());
                            seedB = Convert.ToByte(col.B.ToString());
                        }
                        //compare value seed pixel and pixel now
                        if ((seedR - p[0] >= tred) || (p[0] - seedR >= tred))
                        {
                            //change value pixel now
                            p[0] = p[1] = p[2] = 0;
                            //change value pixel for next 10 pixel
                            for (x = (x + 1); x <= 10; ++x)
                            {
                                p[0] = p[1] = p[2] = 0;
                            }
                            //get new value of new seed pixel
                            Color col = Color.FromArgb(p[offset], p[offset + 1], p[offset + 2]);
                            seedR = Convert.ToByte(col.R.ToString());
                            seedG = Convert.ToByte(col.G.ToString());
                            seedB = Convert.ToByte(col.B.ToString());
                        }
                    }
                    p += nOffset;
                }
            }
   
Comments
sjelen 30-Nov-10 11:11am
   
why create Color instance from bytes, then convert color components to strings, just to convert those strings back into bytes?
cerriun 30-Nov-10 11:58am
   
nevermind, i'am just correct the issue lines. )))
gunkrr 30-Nov-10 23:28pm
   
i have try this code

unsafe
{
byte* p = (byte*)(void*)Scan0;

int nOffset = stride - RImage.Width * 3;

for (int y = 0; y < RImage.Height; ++y)
{
for (int x = 0; x < RImage.Width; ++x)
{
int offset = y * RImage.Width * 3 + x * 3;
if (x == 0)
{
//get value of seed pixel if x==0
Color col = Color.FromArgb(p[offset], p[offset + 1], p[offset + 2]);
//col = bmData.GetPixel(x, y);
seedR = col.R;
seedG = col.G;
seedB = col.B;
}
//compare value seed pixel and pixel now
if ((seedR - p[0] >= tred) || (p[0] - seedR >= tred))
{
//change value pixel now
p[0] = p[1] = p[2] = 0;
//change value pixel for next 10 pixel
for (x = (x + 1); x <= 10; ++x)
{
p[0] = p[1] = p[2] = 0;
}
//get new value of new seed pixel
Color col = Color.FromArgb(p[offset], p[offset + 1], p[offset + 2]);
seedR = col.R;
seedG = col.G;
seedB = col.B;
}
}
p += nOffset;
}
}


but i cant see changes my image
whats problem?

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




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100