Hi. I am implementing the Kuwahara Filter in c#. The code for this is given below.

unsafe
            {
                Bitmap bmps = (Bitmap)pictureBox1.Image;
                Bitmap bmpd = (Bitmap)pictureBox1.Image.Clone();
                BitmapData bms = bmps.LockBits(new Rectangle(0, 0, bmps.Width, bmps.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
                BitmapData bmd = bmpd.LockBits(new Rectangle(0, 0, bmpd.Width, bmpd.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
                byte* b1 = (byte*)(void*)bms.Scan0.ToPointer();
                byte* b2 = (byte*)(void*)bmd.Scan0.ToPointer();
                b2 += (2 * bmd.Width * 3 + 2 * 3);
                float[] bm = { (float)0.0, (float)0.0, (float)0.0, (float)0.0 };
                float[] gm = { (float)0.0, (float)0.0, (float)0.0, (float)0.0 };
                float[] rm = { (float)0.0, (float)0.0, (float)0.0, (float)0.0 };
                float s, yy;
                float[] bx = { (float)0.0, (float)0.0, (float)0.0, (float)0.0 };
                float[] gx = { (float)0.0, (float)0.0, (float)0.0, (float)0.0 };
                float[] rx = { (float)0.0, (float)0.0, (float)0.0, (float)0.0 };
                float[] mi = { (float)0.0, (float)0.0, (float)0.0, (float)0.0 };
                float[] mv = { (float)0.0, (float)0.0, (float)0.0, (float)0.0 };
                int x, y, ctr = 0, ctr1 = 0,i1,j1;
                int r;
                try
                {
                    for (int i = 2; i <= pictureBox1.Height - 2; i++)
                    {
                        i1 = i;
                        for (int j = 2; j <= pictureBox1.Width - 2; j++)
                        {
                            j1 = j;
                            //region 1
                            //bb = gg = rr = 0;
                            x = i - 2;
                            y = j - 2;
                            while (true)
                            {
                                if (ctr == 3)
                                {
                                    x = x + 1;
                                    y = j - 2;
                                    ctr = 0;
                                    continue;
                                }
                                mi[0] += (float)((float)((float)b2[x * bmd.Stride + y] * 0.11) + (float)((float)b2[x * bmd.Stride + y + 1] * 0.59) + (float)((float)b2[x * bmd.Stride + y + 1] * 0.3));
                                bm[0] += (float)b2[x * bmd.Stride + y];
                                gm[0] += (float)b2[x * bmd.Stride + y + 1];
                                rm[0] += (float)b2[x * bmd.Stride + y + 2];
                                y = y + 3;
                                ++ctr;
                                ++ctr1;
                                if (ctr1 == 9)
                                    break;
                            }
                            mi[0] /= 9;
                            bm[0] /= 9;
                            gm[0] /= 9;
                            rm[0] /= 9;
                            for (x = i - 2; x <= i; x++)
                            {
                                for (y = j - 2; y <= j; y++)
                                {
                                    mv[0] += (float)Math.Pow((float)((float)((float)b2[x * bmd.Stride + y] * 0.11) + (float)((float)b2[x * bmd.Stride + y + 1] * 0.59) + (float)((float)b2[x * bmd.Stride + y + 1] * 0.3)) - mi[0], 2);
                                    //gg += (float)Math.Pow(b2[x * bmd.Stride + y + 1], 2);
                                    //rr += (float)Math.Pow(b2[x * bmd.Stride + y + 2], 2);
                                }
                            }
                            mv[0] /= 9;
                            //bx[0] = bb / 9;
                            //gx[0] = gg / 9;
                            //rx[0] = rr / 9;

                            //region 2
                            ctr = 0;
                            ctr1 = 0;
                            //bb = gg = rr = 0;
                            x = i - 2;
                            y = 3*j;
                            while (true)
                            {
                                if (ctr == 3)
                                {
                                    x = x + 1;
                                    y = j - 2;
                                    ctr = 0;
                                    continue;
                                }
                                mi[1] += (float)((float)((float)b2[x * bmd.Stride + y] * 0.11) + (float)((float)b2[x * bmd.Stride + y + 1] * 0.59) + (float)((float)b2[x * bmd.Stride + y + 1] * 0.3));
                                bm[1] += (float)b2[x * bmd.Stride + y];
                                gm[1] += (float)b2[x * bmd.Stride + y + 1];
                                rm[1] += (float)b2[x * bmd.Stride + y + 2];
                                y = y + 3;
                                ++ctr;
                                ++ctr1;
                                if (ctr1 == 9)
                                    break;
                            }
                            mi[1] /= 9;
                            bm[1] /= 9;
                            gm[1] /= 9;
                            rm[1] /= 9;
                            for (x = i - 2; x <= i; x++)
                            {
                                for (y = j - 2; y <= j; y++)
                                {
                                    mv[1] += (float)Math.Pow((float)((float)((float)b2[x * bmd.Stride + y] * 0.11) + (float)((float)b2[x * bmd.Stride + y + 1] * 0.59) + (float)((float)b2[x * bmd.Stride + y + 1] * 0.3)) - mi[0], 2);
                                    //gg += (float)Math.Pow(b2[x * bmd.Stride + y + 1], 2);
                                    //rr += (float)Math.Pow(b2[x * bmd.Stride + y + 2], 2);
                                }
                            }
                            mv[1] /= 9;
                            //bx[0] = bb / 9;
                            //gx[0] = gg / 9;
                            //rx[0] = rr / 9;

                            //region 3
                            ctr = 0;
                            ctr1 = 0;
                            //bb = gg = rr = 0;
                            x = i;
                            y = 3 * j;
                            while (true)
                            {
                                if (ctr == 3)
                                {
                                    x = x + 1;
                                    y = j - 2;
                                    ctr = 0;
                                    continue;
                                }
                                mi[2] += (float)((float)((float)b2[x * bmd.Stride + y] * 0.11) + (float)((float)b2[x * bmd.Stride + y + 1] * 0.59) + (float)((float)b2[x * bmd.Stride + y + 1] * 0.3));
                                bm[2] += (float)b2[x * bmd.Stride + y];
                                gm[2] += (float)b2[x * bmd.Stride + y + 1];
                                rm[2] += (float)b2[x * bmd.Stride + y + 2];
                                y = y + 3;
                                ++ctr;
                                ++ctr1;
                                if (ctr1 == 9)
                                    break;
                            }
                            mi[2] /= 9;
                            bm[2] /= 9;
                            gm[2] /= 9;
                            rm[2] /= 9;
                            for (x = i - 2; x <= i; x++)
                            {
                                for (y = j - 2; y <= j; y++)
                                {
                                    mv[2] += (float)Math.Pow((float)((float)((float)b2[x * bmd.Stride + y] * 0.11) + (float)((float)b2[x * bmd.Stride + y + 1] * 0.59) + (float)((float)b2[x * bmd.Stride + y + 1] * 0.3)) - mi[0], 2);
                                    //gg += (float)Math.Pow(b2[x * bmd.Stride + y + 1], 2);
                                    //rr += (float)Math.Pow(b2[x * bmd.Stride + y + 2], 2);
                                }
                            }
                            mv[2] /= 9;
                            //bx[0] = bb / 9;
                            //gx[0] = gg / 9;
                            //rx[0] = rr / 9;

                            //region 4
                            ctr = 0;
                            ctr1 = 0;
                            //bb = gg = rr = 0;
                            x = i;
                            y = j - 2;
                            while (true)
                            {
                                if (ctr == 3)
                                {
                                    x = x + 1;
                                    y = j - 2;
                                    ctr = 0;
                                    continue;
                                }
                                mi[3] += (float)((float)((float)b2[x * bmd.Stride + y] * 0.11) + (float)((float)b2[x * bmd.Stride + y + 1] * 0.59) + (float)((float)b2[x * bmd.Stride + y + 1] * 0.3));
                                bm[3] += (float)b2[x * bmd.Stride + y];
                                gm[3] += (float)b2[x * bmd.Stride + y + 1];
                                rm[3] += (float)b2[x * bmd.Stride + y + 2];
                                y = y + 3;
                                ++ctr;
                                ++ctr1;
                                if (ctr1 == 9)
                                    break;
                            }
                            mi[3] /= 9;
                            bm[3] /= 9;
                            gm[3] /= 9;
                            rm[3] /= 9;
                            for (x = i - 2; x <= i; x++)
                            {
                                for (y = j - 2; y <= j; y++)
                                {
                                    mv[3] += (float)Math.Pow((float)((float)((float)b2[x * bmd.Stride + y] * 0.11) + (float)((float)b2[x * bmd.Stride + y + 1] * 0.59) + (float)((float)b2[x * bmd.Stride + y + 1] * 0.3)) - mi[0], 2);
                                    //gg += (float)Math.Pow(b2[x * bmd.Stride + y + 1], 2);
                                    //rr += (float)Math.Pow(b2[x * bmd.Stride + y + 2], 2);
                                }
                            }
                            mv[3] /= 9;
                            //bx[0] = bb / 9;
                            //gx[0] = gg / 9;
                            //rx[0] = rr / 9;

                            s = mv[0];
                            r = 1;
                            for (int h = 1; h <= 3; h++)
                            {
                                yy = mv[h];
                                if (yy < s)
                                {
                                    s = yy;
                                    r = h + 1;
                                }
                            }
                            textBox1.Text = r.ToString();
                            if (r == 1)
                            {
                                b2[0] = (byte)bm[0];
                                b2[1] = (byte)gm[0];
                                b2[2] = (byte)rm[0];
                                b2 += 3;
                            }
                            else if (r == 2)
                            {
                                b2[0] = (byte)bm[1];
                                b2[1] = (byte)gm[1];
                                b2[2] = (byte)rm[1];
                                b2 += 3;
                            }
                            else if (r == 3)
                            {
                                b2[0] = (byte)bm[2];
                                b2[1] = (byte)gm[2];
                                b2[2] = (byte)rm[2];
                                b2 += 3;
                            }
                            else if (r == 4)
                            {
                                b2[0] = (byte)bm[3];
                                b2[1] = (byte)gm[3];
                                b2[2] = (byte)rm[3];
                                b2 += 3;
                            }
                            //switch (r)
                            /*{
                                case 1: 
                                    b2[0] = (byte)bm[0];
                                    b2[1] = (byte)gm[0];
                                    b2[2] = (byte)rm[0];
                                    b2 += 3;
                                    break;
                                case 2: 
                                    b2[0] = (byte)bm[1];
                                    b2[1] = (byte)gm[1];
                                    b2[2] = (byte)rm[1];
                                    b2 += 3;
                                    break;
                                case 3: 
                                    b2[0] = (byte)bm[2];
                                    b2[1] = (byte)gm[2];
                                    b2[2] = (byte)rm[2];
                                    b2 += 3;
                                    break;
                                case 4: 
                                    b2[0] = (byte)bm[3];
                                    b2[1] = (byte)gm[3];
                                    b2[2] = (byte)rm[3];
                                    b2 += 3;
                                    break;
                            }*/
                            textBox2.Text = j.ToString();
                            j = j1;
                            textBox2.Text += j.ToString();
                            if (j <= pictureBox1.Width - 2)
                                continue;
                        }
                        i = i1;
                        if (i <= pictureBox1.Height - 2)
                            continue;
                    }
                }
                catch (Exception ex)
                {
                }
                textBox1.Text += "HERE. Did not go into next iteration";
                bmpd.Save(@"C:\users\pashok\kuwaop.jpg");
                bmps.UnlockBits(bms);
                bmpd.UnlockBits(bmd);
                pictureBox2.Refresh();
                pictureBox2.Image = (Image)(new Bitmap(@"C:\users\pashok\kuwaop.jpg"));
                pictureBox2.Visible = true;
            }

The problem I am facing is that this the for loop(i&j) run only once. Inspite of giving break points and verifying, I still am not able to figure out the error. Can someone help me. Its kinda urgent

Recommended Answers

All 18 Replies

ok, two things:
1) your loop is only running once because you arent setting ctr1 back to zero before your first while loop so it starts at 9, gets incremented once and never hits the if(ctr1==9) break; statement. insert ctr1 = 0; between lines 32 and 33. Your code was hitting an exception because of the counter. It wasnt critical so the app stays open, but the following message: "A first chance exception of type 'System.AccessViolationException' occurred in.." was shown in Output and the code stops executing.

2) with the loops running properly you are still getting the distortion you had in the first post you made about this. This is the third post you have made, the third time i have taken the time to find the problem and i'm hoping it wont be the third time you ignore me. I posted you revised code in your first thread. It fixed a few minor errors and dealt with the distortion. It doesnt work fully as it removes a border 2 pixels wide from the image. This is because you are processing the pixles from 2 to pictureBox.Width - 2 and 2 to picturebox.Height - 2, but the filter itself is applied to the rest of the image.

Hey thnx man.. regarding the second point u mentioned.. i have made the changes, but this code is an old file i am using for testing.. tats why u saw these mistakes again..sorry abt tat

Glad to help :) I take it the code changes i gave you originally worked for you then?
Where possible, always try to leave some feedback on threads that have been answered. If you had left a note to say you implemented the changes and they worked then anyone who reads the thread in future will know the code is sound. It also lets me know that you read the post and the code helped you out :)

Also, remember to mark threads as solved if your question has been answered.

Hey, thanks a lot for the reply. Unfortunately enough, my system crashed yest and so I lost all the data I had stored. So I am yet to implement this code again. I will def post what happens, over here. Cheers!!!

Ryshad, the code that I have pasted above is using pointers directly and not the bmat/gmat/rmat arrays. Is it possible for you to check if the coding is right?

Dear Ryshad,

I implemented the changes and the output is perfect. Exactly what I want.

Thanks a lot

I already ran it, its not working. With ctr1 set back to zero as i showed you, the loops run but the image is still distorted. As i said, you need to account for the padding in bitmapdata objects when you write to the output image.
Also, how are you going to apply the filter to the pixels at the edge of the image? or are you just going to copy them directly as they are?

the changes from the original post?

yes, the changes from the original post

great, glad its all working at last :D It took a little time and a lot of patience, but we got you there.

I have just one doubt. In the orig thread, when you added the coding regarding padding, you have set the width 2 borders to black. What should I do if it should be the original

so you want the outside 2 pixel border to be the original unfiltered pixels?

Yes, that is how I want it. I gave this code for it, but I dont know if it is right.

b1 = (byte*)(void*)bms.Scan0.ToPointer();
                b2 = (byte*)(void*)bmd.Scan0.ToPointer();

                for (int i = 0; i < bmd.Height; i++)
                {
                    for (int j = 0; j < bmd.Width; j++)
                    {
                        if(b2[0]==0&&b2[1]==0&&b2[2]==0)
                        {
                            b2[0] = b1[0];
                            b2[1] = b1[1];
                            b2[2] = b1[2];
                            b2 += 3;
                            b1 += 3;
                        }
                    }
                }

rather than trying to manually add the pixels in, try this:

unsafe
            {
                Bitmap bmps = (Bitmap)pictureBox1.Image;
                Bitmap bmpd = (Bitmap)pictureBox1.Image.Clone(); //go back to cloning the image as before
                BitmapData bms = bmps.LockBits(new Rectangle(0, 0, bmps.Width, bmps.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); //may want to throw in a check to ensure the image pixel format matches this
                BitmapData bmd = bmpd.LockBits(new Rectangle(0, 0, bmpd.Width, bmpd.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
                
                //calculate padding of source image
                padding = bms.Stride - (bms.Width * 3);

                byte* b1 = (byte*)(void*)bms.Scan0.ToPointer();
                byte* b2 = (byte*)(void*)bmd.Scan0.ToPointer();
                
                for (int i = 0; i < pictureBox1.Height; i++)
                {
                    for (int j = 0; j < pictureBox1.Width; j++)
                    {

                        bmat[i, j] = (int)b1[0];
                        gmat[i, j] = (int)b1[1];
                        rmat[i, j] = (int)b1[2];
                        b1 += 3;
                    }

                    //this moves the pointer past the padding at the end
                    //of the row and on to the next row of the images pixels
                    b1 += padding; 
                }

                //calculate padding of new image
                //by adding the 2 pixel border at left you have increased image width so alter padding calculation.
                padding = bms.Stride - ((pictureBox1.Width - 2) * 3);

                //move b2 forward by 2 rows
                b2 += bms.Stride * 2;

                for (int i = 2; i < pictureBox1.Height - 2; i++)
                {
                    
                    //ignore first two pixels of each row
                    b2 += 6;
                    for (int j = 2; j < pictureBox1.Width - 2; j++)
                    {
                        bb = gg = rr = 0;
                        bm[0] = (bmat[i - 2, j - 2] + bmat[i - 1, j - 2] + bmat[i, j - 2] + bmat[i - 2, j - 1] + bmat[i - 1, j - 1] + bmat[i, j - 1] + bmat[i - 2, j] + bmat[i - 1, j] + bmat[i, j]) / 9;
                        gm[0] = (gmat[i - 2, j - 2] + gmat[i - 1, j - 2] + gmat[i, j - 2] + gmat[i - 2, j - 1] + gmat[i - 1, j - 1] + gmat[i, j - 1] + gmat[i - 2, j] + gmat[i - 1, j] + gmat[i, j]) / 9;
                        rm[0] = (rmat[i - 2, j - 2] + rmat[i - 1, j - 2] + rmat[i, j - 2] + rmat[i - 2, j - 1] + rmat[i - 1, j - 1] + rmat[i, j - 1] + rmat[i - 2, j] + rmat[i - 1, j] + rmat[i, j]) / 9;
                        for (int x = i - 2; x <= i; x++)
                        {
                            for (int y = j - 2; y <= j; y++)
                            {
                                bb += (float)Math.Pow(bmat[x, y] - bm[0], 2);
                                gg += (float)Math.Pow(gmat[x, y] - gm[0], 2);
                                rr += (float)Math.Pow(rmat[x, y] - rm[0], 2);
                            }
                        }
                        bx[0] = bb / 9;
                        gx[0] = gg / 9;
                        rx[0] = rr / 9;

                        bb = gg = rr = 0;
                        bm[1] = (bmat[i, j - 2] + bmat[i + 1, j - 2] + bmat[i + 2, j - 2] + bmat[i, j - 1] + bmat[i + 1, j - 1] + bmat[i + 2, j - 1] + bmat[i, j] + bmat[i + 1, j] + bmat[i + 2, j]) / 9;
                        gm[1] = (gmat[i, j - 2] + gmat[i + 1, j - 2] + gmat[i + 2, j - 2] + gmat[i, j - 1] + gmat[i + 1, j - 1] + gmat[i + 2, j - 1] + gmat[i, j] + gmat[i + 1, j] + gmat[i + 2, j]) / 9;
                        rm[1] = (rmat[i, j - 2] + rmat[i + 1, j - 2] + rmat[i + 2, j - 2] + rmat[i, j - 1] + rmat[i + 1, j - 1] + rmat[i + 2, j - 1] + rmat[i, j] + rmat[i + 1, j] + rmat[i + 2, j]) / 9;
                        for (int x = i; x <= i + 2; x++)
                        {
                            for (int y = j - 2; y <= j; y++)
                            {
                                bb += (float)Math.Pow(bmat[x, y] - bm[1], 2);
                                gg += (float)Math.Pow(gmat[x, y] - gm[1], 2);
                                rr += (float)Math.Pow(rmat[x, y] - rm[1], 2);
                            }
                        }
                        bx[1] = bb / 9;
                        gx[1] = gg / 9;
                        rx[1] = rr / 9;

                        bb = gg = rr = 0;
                        bm[2] = (bmat[i - 2, j] + bmat[i - 1, j] + bmat[i, j] + bmat[i - 2, j + 1] + bmat[i - 1, j + 1] + bmat[i, j + 1] + bmat[i - 2, j + 2] + bmat[i - 1, j + 2] + bmat[i, j + 2]) / 9;
                        gm[2] = (gmat[i - 2, j] + gmat[i - 1, j] + gmat[i, j] + gmat[i - 2, j + 1] + gmat[i - 1, j + 1] + gmat[i, j + 1] + gmat[i - 2, j + 2] + gmat[i - 1, j + 2] + gmat[i, j + 2]) / 9;
                        rm[2] = (rmat[i - 2, j] + rmat[i - 1, j] + rmat[i, j] + rmat[i - 2, j + 1] + rmat[i - 1, j + 1] + rmat[i, j + 1] + rmat[i - 2, j + 2] + rmat[i - 1, j + 2] + rmat[i, j + 2]) / 9;
                        for (int x = i - 2; x <= i; x++)
                        {
                            for (int y = j; y <= j + 2; y++)
                            {
                                bb += (float)Math.Pow(bmat[x, y] - bm[2], 2);
                                gg += (float)Math.Pow(gmat[x, y] - gm[2], 2);
                                rr += (float)Math.Pow(rmat[x, y] - rm[2], 2);
                            }
                        }
                        bx[2] = bb / 9;
                        gx[2] = gg / 9;
                        rx[2] = rr / 9;

                        bb = gg = rr = 0;
                        bm[3] = (bmat[i, j] + bmat[i + 1, j] + bmat[i + 2, j] + bmat[i, j + 1] + bmat[i + 1, j + 1] + bmat[i + 2, j + 1] + bmat[i, j + 2] + bmat[i + 1, j + 2] + bmat[i + 2, j + 2]) / 9;
                        gm[3] = (gmat[i, j] + gmat[i + 1, j] + gmat[i + 2, j] + gmat[i, j + 1] + gmat[i + 1, j + 1] + gmat[i + 2, j + 1] + gmat[i, j + 2] + gmat[i + 1, j + 2] + gmat[i + 2, j + 2]) / 9;
                        rm[3] = (rmat[i, j] + rmat[i + 1, j] + rmat[i + 2, j] + rmat[i, j + 1] + rmat[i + 1, j + 1] + rmat[i + 2, j + 1] + rmat[i, j + 2] + rmat[i + 1, j + 2] + rmat[i + 2, j + 2]) / 9;
                        for (int x = i; x <= i + 2; x++)
                        {
                            for (int y = j; y <= j + 2; y++)
                            {
                                bb += (float)Math.Pow(bmat[x, y] - bm[3], 2);
                                gg += (float)Math.Pow(gmat[x, y] - gm[3], 2);
                                rr += (float)Math.Pow(rmat[x, y] - rm[3], 2);
                            }
                        }
                        bx[3] = bb / 9;
                        gx[3] = gg / 9;
                        rx[3] = rr / 9;

                        sb = bx[0];
                        sg = gx[0];
                        sr = rx[0];
                        s = (sb + sg + sr) / 3;
                        r = 1;
                        for (int h = 1; h <= 3; h++)
                        {
                            yy = (bx[h] + gx[h] + rx[h]) / 3;
                            if (yy < s)
                            {
                                s = yy;
                                r = h + 1;
                            }
                        }
                        switch (r)
                        {
                            case 1:
                                b2[0] = (byte)bm[0];
                                b2[1] = (byte)gm[0];
                                b2[2] = (byte)rm[0];
                                b2 += 3;
                                break;
                            case 2:
                                b2[0] = (byte)bm[1];
                                b2[1] = (byte)gm[1];
                                b2[2] = (byte)rm[1];
                                b2 += 3;
                                break;
                            case 3:
                                b2[0] = (byte)bm[2];
                                b2[1] = (byte)gm[2];
                                b2[2] = (byte)rm[2];
                                b2 += 3;
                                break;
                            case 4:
                                b2[0] = (byte)bm[3];
                                b2[1] = (byte)gm[3];
                                b2[2] = (byte)rm[3];
                                b2 += 3;
                                break;
                            default:
                                break;
                        }
                    }

                    //ignore padding at end of each row which now includes the 2 pixel border on right
                    b2 += padding;
                }

I have made a couple of changes; I have returned the image clone you had before and added a couple of lines to correctly position the filtered pixels. This way you start with a clone of the original image then overwrite the pixels with the filtered ones, leaving the 2 pixels around the edge unfiltered. Was this why you were cloning the image originally?

Try the revisions and let me know how it goes.

No problems. I have read his thread but i haven't done much work with imaging. Fixing your filter is the most in depth i've ever gone with bitmaps to date :p I'll take another look and see if i can help him out :)

Sure Ryshad. Thanks a ton once again.

you had a similar post for Nucleus detection, were you posting for your friend or are you both working on similar projects?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.