I am implementing an image processing related code in C#. It works almost fine, but I find a problem that I am anable to solve. When I run the project, I get the output perfectly. But when I minimize the screen and expand it, the originial image appears distorted. I cannot understand how this is possible, considering that I do not make any changes to the original image. Anyone can help me out?

Depending on what you mean by "distorted" it sounds like you are having problems with the way the application fires Paint events.
Do you have code you can paste so that we can isolate the issue for you?

Yes I do.

int[] s1 = new int[9];
            int[] s2 = new int[9];
            int[] s3 = new int[9];
            float[] bm = new float[4];
            float[] gm = new float[4];
            float[] rm = new float[4];
            float bb=0,gg=0,rr=0,sb,sg,sr,s,yy;
            float[] bx = new float[4];
            float[] gx = new float[4];
            float[] rx = new float[4];
            float[,] bmat = new float[pictureBox1.Height, pictureBox1.Width];
            float[,] gmat = new float[pictureBox1.Height, pictureBox1.Width];
            float[,] rmat = new float[pictureBox1.Height, pictureBox1.Width];
            int r;
            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();
                byte* b3 = (byte*)(void*)bms.Scan0.ToPointer();
                b2 = b1;
                /*for (int i = 0; i < bmps.Height; i++)
                {
                    for (int j = 0; j < bmpd.Width; j++)
                    {
                        b2[i * bmd.Stride + j] = b1[i * bms.Stride + j];
                    }
                }*/
                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;
                    }
                }
                /*for (int i = 0; i < bmps.Height; i++)
                {
                    for (int j = 0; j < bmpd.Width; j++)
                    {
                        b2[i * bmd.Stride + j] = b1[i * bms.Stride + j];
                    }
                }*/
                b2 += (2 * bmd.Width * 3 + 2 * 3);
                
                for (int i = 2; i < pictureBox1.Height - 2; i++)
                {
                    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)//bx[h]<sb&&gx[h]<sg&&rx[h]<sr)
                            {
                                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;
                        }
                    }
                }
                bmps.UnlockBits(bms);
                bmpd.UnlockBits(bmd);
                pictureBox2.Image = bmpd;
                pictureBox2.Visible = true;
                bmpd.Save(@"C:\users\pashok\kuwaop.jpg");
                pictureBox2.Refresh();
                button3.Enabled = true;
            }
Bitmap bs = (Bitmap)pictureBox1.Image;
            Bitmap bd = new Bitmap(@"C:\users\pashok\kuwaop.jpg");
            Point p;
            List<Point> diffpts = new List<Point>();
            FileInfo f = new FileInfo(@"C:\users\pashok\diff.txt");
            StreamWriter w = f.CreateText();
            pictureBox2.Refresh();
            for (int i = 0; i < bs.Width; i++)
            {
                for (int j = 0; j < bs.Height; j++)
                { 
                    if(bs.GetPixel(i,j).R!=bd.GetPixel(i,j).R&&bs.GetPixel(i,j).G!=bd.GetPixel(i,j).G&&bs.GetPixel(i,j).B!=bd.GetPixel(i,j).B)
                    {
                        bd.SetPixel(i, j, Color.Red);
                    }
                }
            }
            label1.Text = "Stored varying points";
            label1.Visible = true;
            w.Close();

I have another button click event to select the image. The code for the same is :

OpenFileDialog o = new OpenFileDialog();
            o.InitialDirectory = "";
            o.RestoreDirectory = true;
            if (o.ShowDialog() == DialogResult.OK)
            {
                this.pictureBox1.Image = new Bitmap(o.FileName);
                this.pictureBox1.Height = this.pictureBox1.Image.Height;
                this.pictureBox1.Width = this.pictureBox1.Image.Width;
                pictureBox1.Visible = true;
                this.Invalidate();
                this.pictureBox2.Height = this.pictureBox1.Image.Height;
                this.pictureBox2.Width = this.pictureBox1.Image.Width;
                pictureBox2.Visible = false;
                this.Invalidate();
            }

hmm, can you clarify what you mean by the image being distorted? A screenshot would be ideal. Wanna make sure i fully understand whats happening before we start looking at solutions.

Sure. I am attaching the screen shots.. The orig.jpg file is how the screen appears before I minimize. The newimg.jpg is how the screen appears after I expand.

Attachments newimg.jpg 191.52 KB orig.jpg 159.93 KB

Hmm, its not what i thought.
I am still puzzling it out, but i threw in this extra line:

bmps.UnlockBits(bms);
                bmpd.UnlockBits(bmd);
                pictureBox1.Image = bmps;
                pictureBox2.Image = bmpd;

And the image distorts when you run the code. So its not that the image is distorted by minimising, it is being distorted during the process but the distortion is only shown when the image refreshes : / The same happens if you add pictureBox1.Refresh(); after you refesh pictureBox2.

So the question is, where abouts in your code is the distortion occuring.
I know this isnt an answer, and i'll keep trying, but at least it narrows down the problem.

Edited 7 Years Ago by Geekitygeek: n/a

Well, like you said, I atleast understood what the problem is. Thanks a lot

I've narrowed it down to the switch at the end of the code block that is causing the distortion...getting closer :)

What is the switch at the end supposed to do? And were you aware that r will never be 4? You loop through h=1 and h=2 so the max that r will be is h+1=3.

Im still trying to get to the root of the issue, but the problem seems to be that when you apply the values of bm, gm and rm to b2 it causes the distortion. So either the values in bm,gm and rm are not being set correctly, or you are applying them to b2 incorrectly.

Sorry i cant be more specific so far, i'm not 100% sure what it is your code is doing :p

I will first explain what the code does.

Starting from pixel 2,2 , I consider matrices of size 3*3 as shown in the attachment file. There are basically 4 regions. I calculate the variance for each of these regions and find the min of it. I also calculate the mean intensity value for these regions. Whichever variance value is minimum, I set the pixel value(say 2,2 for a start) as the mean intensity value. That is, out of regions 1 to 4, suppose if region 3 has least variance, I set pixel 2,2 value as the mean intensity of region 3. This is the purpose of the switch statement.

Attachments kuw.jpg 12.93 KB

Ok, i think i vaguely understand :) I'm afraid i have a doctors appointment shortly, but i'll try to take another look this afternoon.

Now that we know the problem is somewhere in your code, i would suggest you check a couple of things:
a) that the pixels are being read in correctly.
b) that your variance/mean intensity calculations are coming out correctly.
c) that the correct value is chosen and assigned by your switch.

Use breakpoints to step through the sections of code to ensure that the variables contain teh values you expect, for teh math stuff, calculate the variance etc by hand and see if the outcome of your loops matchs.

Comments
Very helpful indeed!

Sure Ryshad,

Thanks a ton for helpin out... i will get back to u later. with anther problem i have.

I have gone thru my coding again, but it seems to be correct. Any luck with ur trial?

I managed to find one issue, although it hasnt solved the problem yet : /
When you copy the pixels into your bmat/gmat/rmat arrays, you arent accounting for the padding; each row of pixels starts on a 4byte boundary so if your images width is not an exact multiple of the pixel width then the rows are padded. You can adjust for this by inserting the following line:

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;
                    }
                    b1 += bms.Stride - (pictureBox1.Width * 3); //add this

                }

The stride is the total width of a row including padding so if you subtract the pixel width of the image from the stride you are left with the padding :) Then jsut factoir that into your loop.
I picked up on this by using a pure red 38 x 38 image and i noticed that bmat contained blocks of 38 255's starting every 40 item (ie (2,2) to (3,1) all contained 255 when they should be 0 :p
I'll keep chipping away at it for youwhenever time permits.

Having played around with it some more i think the problem is not with your math, but with how you are writing the calculated pixels back to the bitmap.
You are starting your check at pixel (2,2) and ending at (width-2, height-2) which means there is a border of two pixels around the image which you dont process. They are included in the calculations, but not calculated themselves. The problem is that you arent acounting for these gaps when you start writing to the bitmap. bmd.Scan0.ToPointer() returns a pointer to the memory address of the very first pixel in the bitmap, when you start copying the pixels from the source you are copying pixel (2,2) into the first pixel of the destination image. And when you reach the end of a row you arent padding the destination bitmaps row to account for writing fewer pixels to it.

There were a couple of other minor errors i found as well. This is what i ended up with:

int[] s1 = new int[9];
            int[] s2 = new int[9];
            int[] s3 = new int[9];
            float[] bm = new float[4];
            float[] gm = new float[4];
            float[] rm = new float[4];
            float bb=0,gg=0,rr=0,sb,sg,sr,s,yy;
            float[] bx = new float[4];
            float[] gx = new float[4];
            float[] rx = new float[4];
            float[,] bmat = new float[pictureBox1.Height, pictureBox1.Width];
            float[,] gmat = new float[pictureBox1.Height, pictureBox1.Width];
            float[,] rmat = new float[pictureBox1.Height, pictureBox1.Width];
            int r;
            int padding = 0; //added variable to store padding value
            unsafe
            {
                Bitmap bmps = (Bitmap)pictureBox1.Image;
                Bitmap bmpd = new Bitmap(pictureBox1.Width, pictureBox1.Height);//cloning the image was what copied the image into the second picturebox. You ened to start with a fresh bitmap to write to.
                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();
                
                //b2 = b1; REMOVED THIS. This was the reason the first image got distorted instead of the second.
                //you were overwriting b2 with a pointer to the pixels in b1. Be careful with pointers, they store an address not a value.
                
                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
                //new image will be 4 pixels thinner than the source as you start at 2 and stop 2 short
                padding = bms.Stride - ((pictureBox1.Width - 4) * 3);

                for (int i = 2; i < pictureBox1.Height - 2; i++)
                {
                    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;
                        }
                    }

                    //add empty padding to the end of each row.
                    //this results in the black trim on the left and bottom edges of the image
                    //but it ensures the rows are kept in sync
                    for (int pad = 0; pad < padding; pad++)
                    {
                        b2[pad] = (byte)0;
                    }
                    b2 += padding;
                }
                bmps.UnlockBits(bms);
                bmpd.UnlockBits(bmd);
                pictureBox2.Image = bmpd;
                pictureBox2.Visible = true;
                bmpd.Save(@"C:\users\dan\kuwaop.jpg");
                pictureBox1.Refresh();
                pictureBox2.Refresh();
                button3.Enabled = true;
            }

I've commented the changes i had to make and briefly outlined the reasons. I can try and explain in more depth if you need me to. This does what you intended it to do i believe. But i think you will need to put some thouhgt into how you wish to calculate and apply the means for the pixels around the edge of the image :)

Hope this helps you out, and thank you so much for bringing a challenge...was great having something to really sink my teeth into!

Dear Ryshad,

I implemented the changes and the output is perfect. It is exactly what I want. Thanks a ton..

This question has already been answered. Start a new discussion instead.