示例#1
0
        public Image_Panel(Bitmap image, string imageName)
        {
            InitializeComponent();

            this.chHisto.Width = this.Width - panelImage.Width;

            imageForReset = (Bitmap)image.Clone();

            originalImage  = image;
            this.imageName = imageName;

            this.Text = imageName;

            secondaryImage = (Bitmap)image.Clone();

            this.pctbImage.Image = image;
            this.pctbImage.Show();

            hist = new ImageHistogram((Bitmap)pctbImage.Image, this);

            hist.CreateChart(chHisto);
            this.pctbHistogram.Show();

            basicImageOpertions = new BasicImageOpertions((Bitmap)pctbImage.Image);

            basicImageOpertions.ImageFinished += OnImageFinished;
        }
        public void Negative()
        {
            try
            {
                this.bitmapData = BasicImageOpertions.BitmapToBitmapData(bmp);

                unsafe                                              // C# doesn't support pointer arithmetic
                {
                    byte *PtrFirstPixel = (byte *)bitmapData.Scan0; // Point to first pixel

                    for (int y = 0; y < heightInPixels; y++)
                    {
                        byte *currentLine = PtrFirstPixel + (y * bitmapData.Stride);

                        for (int x = 0; x < widthInBytes; x += bytesPerPixel)
                        {
                            currentLine[x]     = (byte)(255 - currentLine[x]);
                            currentLine[x + 1] = (byte)(255 - currentLine[x + 1]);
                            currentLine[x + 2] = (byte)(255 - currentLine[x + 2]);
                        }
                    }
                    bmp.UnlockBits(bitmapData);
                }
                OnImageFinished(bmp);
            }
            catch
            {
                System.Windows.Forms.MessageBox.Show("Please select image first", "Error");
            }
        }
        public void ToGreyScale()
        {
            try
            {
                this.bitmapData = BasicImageOpertions.BitmapToBitmapData(bmp);

                unsafe                                              // C# doesn't support pointer arithmetic
                {
                    byte *PtrFirstPixel = (byte *)bitmapData.Scan0; // Point to first pixel

                    for (int y = 0; y < heightInPixels; y++)
                    {
                        byte *currentLine = PtrFirstPixel + (y * bitmapData.Stride);

                        for (int x = 0; x < widthInBytes; x += bytesPerPixel)
                        {
                            int avg = (currentLine[x] + currentLine[x + 1] + currentLine[x + 2]) / 3;

                            currentLine[x]     = (byte)avg;
                            currentLine[x + 1] = (byte)avg;
                            currentLine[x + 2] = (byte)avg;
                            //GreyScale
                        }
                    }
                    bmp.UnlockBits(bitmapData);
                }
                OnImageFinished(bmp);
            }
            catch
            {
            }
        }
        public UOPPanel(Bitmap image, Image_Panel caller)
        {
            InitializeComponent();

            this.caller = caller;

            originalImage = image;

            BasicImageOpertions = new BasicImageOpertions(originalImage);

            BasicImageOpertions.ToGreyScale();

            secondaryImage = (Bitmap)originalImage.Clone();

            this.pctbImage.Image = secondaryImage;

            hist = new ImageHistogram((Bitmap)pctbImage.Image);

            hist.CreateChart(this.chHisto);

            this.pctbUOP.Image = new Bitmap(256, 256);

            grafika = Graphics.FromImage(pctbUOP.Image);

            LUT   = new int[256];
            linia = new Krzywa();
            RysujLinie();
        }
示例#5
0
        private void FindMin()
        {
            try
            {
                BitmapData bitmapData = BasicImageOpertions.BitmapToBitmapData(bitmap);

                int bytesPerPixel  = System.Drawing.Bitmap.GetPixelFormatSize(bitmap.PixelFormat) / 8;
                int heightInPixels = bitmapData.Height;
                int widthInBytes   = bitmapData.Width * bytesPerPixel;


                unsafe                                              // C# doesn't support pointer arithmetic
                {
                    byte *PtrFirstPixel = (byte *)bitmapData.Scan0; // Point to first pixel

                    for (int y = 0; y < heightInPixels; y++)
                    {
                        byte *currentLine = PtrFirstPixel + (y * bitmapData.Stride);

                        for (int x = 0; x < widthInBytes; x += bytesPerPixel)
                        {
                            if (currentLine[x] < min)
                            {
                                min = currentLine[x];
                            }
                        }
                    }
                    bitmap.UnlockBits(bitmapData);
                }
            }
            catch
            {
                System.Windows.Forms.MessageBox.Show("Please select image first", "Error");
            }
        }
        public void Reduction(int numOfLevels)
        {
            try
            {
                this.bitmapData = BasicImageOpertions.BitmapToBitmapData(bmp);

                unsafe                                              // C# doesn't support pointer arithmetic
                {
                    byte *PtrFirstPixel = (byte *)bitmapData.Scan0; // Point to first pixel

                    for (int y = 0; y < heightInPixels; y++)
                    {
                        byte *currentLine = PtrFirstPixel + (y * bitmapData.Stride);

                        for (int x = 0; x < widthInBytes; x += bytesPerPixel)
                        {
                            int tmp = (currentLine[x] + currentLine[x + 1] + currentLine[x + 2]) / 3;

                            tmp = ((int)(tmp / (256 / numOfLevels))) * (255 / (numOfLevels - 1));

                            currentLine[x]     = (byte)tmp;
                            currentLine[x + 1] = (byte)tmp;
                            currentLine[x + 2] = (byte)tmp;
                        }
                    }
                    bmp.UnlockBits(bitmapData);
                }
                OnImageFinished(bmp);
            }
            catch
            {
                System.Windows.Forms.MessageBox.Show("Please select image first", "Error");
            }
        }
        public void CreateHistogram()
        {
            toneHistogram.Clear();

            for (int i = 0; i < 256; ++i)
            {
                toneHistogram.Add(i, 0);

                Red[i]   = 0;
                Green[i] = 0;
                Blue[i]  = 0;
            }

            try
            {
                bitmapData = BasicImageOpertions.BitmapToBitmapData(bitmap);

                int bytesPerPixel  = System.Drawing.Bitmap.GetPixelFormatSize(bitmap.PixelFormat) / 8;
                int heightInPixels = bitmapData.Height;
                int widthInBytes   = bitmapData.Width * bytesPerPixel;


                unsafe                                              // C# doesn't support pointer arithmetic
                {
                    byte *PtrFirstPixel = (byte *)bitmapData.Scan0; // Point to first pixel

                    for (int y = 0; y < heightInPixels; y++)
                    {
                        byte *currentLine = PtrFirstPixel + (y * bitmapData.Stride);

                        for (int x = 0; x < widthInBytes; x += bytesPerPixel)
                        {
                            Color col = Color.FromArgb(255, currentLine[x + 2], currentLine[x + 1], currentLine[x]);

                            Blue[currentLine[x]]++;
                            Green[currentLine[x + 1]]++;
                            Red[currentLine[x + 2]]++;


                            if (colorHistogram.ContainsKey(col))
                            {
                                colorHistogram[col] = colorHistogram[col] + 1;
                            }
                            else
                            {
                                colorHistogram.Add(col, 1);
                            }
                        }
                    }
                    bitmap.UnlockBits(bitmapData);
                }
            }
            catch
            {
                System.Windows.Forms.MessageBox.Show("Please select image first", "Error");
            }
            SetMinAndMax();
        }
        private void btnOK_Click(object sender, EventArgs e)
        {
            if (cmbFirstImage.SelectedItem != null && cmbSecondImage.SelectedItem != null)
            {
                Bitmap bmp1 = bitmaps[(string)cmbFirstImage.SelectedItem];
                Bitmap bmp2 = new Bitmap((Bitmap)bitmaps[(string)cmbSecondImage.SelectedItem], bmp1.Width, bmp1.Height);//(Bitmap)bitmaps[(string)cmbSecondImage.SelectedItem].Clone();
                //resultBmp = (Bitmap)bmp1.Clone();


                operationOnImage = new BasicImageOpertions(bmp2);
                operationOnImage.ToGreyScale();

                operationOnImage = new BasicImageOpertions(bmp1);

                if (rdbAdd.Checked)
                {
                    operationOnImage.ADD(bmp2);
                }
                else if (rdbSub.Checked)
                {
                    operationOnImage.SUB(bmp2);
                }
                else if (rdbDiff.Checked)
                {
                    operationOnImage.DIFF(bmp2);
                }
                else if (rdbOR.Checked)
                {
                    operationOnImage.OR(bmp2);
                }
                else if (rdbAND.Checked)
                {
                    operationOnImage.AND(bmp2);
                }
                else if (rdbXOR.Checked)
                {
                    operationOnImage.XOR(bmp2);
                }
                //else if (radioButtonAnd.Checked) And(bmp1, bmp2);
                //else if (radioButtonOr.Checked) Or(bmp1, bmp2);
                //else if (radioButtonXor.Checked) Xor(bmp1, bmp2);
            }
            foreach (Image_Panel form in forms)
            {
                form.Refresh();
                form.RemakeHistogram();
            }

            this.Close();
        }
        public void StretchHistogram()
        {
            CreateHistogram();

            int newR;
            int newG;
            int newB;

            int diffR = maxR - minR;
            int diffG = maxG - minG;
            int diffB = maxB - minB;

            try
            {
                bitmapData = BasicImageOpertions.BitmapToBitmapData(bitmap);

                int bytesPerPixel  = System.Drawing.Bitmap.GetPixelFormatSize(bitmap.PixelFormat) / 8;
                int heightInPixels = bitmapData.Height;
                int widthInBytes   = bitmapData.Width * bytesPerPixel;

                unsafe                                              // C# doesn't support pointer arithmetic
                {
                    byte *PtrFirstPixel = (byte *)bitmapData.Scan0; // Point to first pixel

                    for (int y = 0; y < heightInPixels; y++)
                    {
                        byte *currentLine = PtrFirstPixel + (y * bitmapData.Stride);

                        for (int x = 0; x < widthInBytes; x += bytesPerPixel)
                        {
                            newR = (int)((currentLine[x + 2] - minR) * 255 / diffR);
                            newG = (int)((currentLine[x + 1] - minG) * 255 / diffG);
                            newB = (int)((currentLine[x] - minB) * 255 / diffB);

                            currentLine[x + 2] = (byte)newR;
                            currentLine[x + 1] = (byte)newG;
                            currentLine[x]     = (byte)newB;
                        }
                    }
                    bitmap.UnlockBits(bitmapData);
                }
            }
            catch
            {
                System.Windows.Forms.MessageBox.Show("Please select image first", "Error");
            }
            caller.SetImageAndHist(bitmap);
        }
        public BasicImageOpertions(Bitmap bitmap)
        {
            if (bitmap == null)
            {
                return;
            }

            this.bmp        = bitmap;
            SecondaryBitmap = (Bitmap)bmp.Clone();

            this.bitmapData = BasicImageOpertions.BitmapToBitmapData(bmp);

            this.bytesPerPixel  = System.Drawing.Bitmap.GetPixelFormatSize(bmp.PixelFormat) / 8;
            this.heightInPixels = bitmapData.Height;
            this.widthInBytes   = bitmapData.Width * bytesPerPixel;

            bmp.UnlockBits(bitmapData);
        }
        public void Brightness(int value)
        {
            this.ToGreyScale();

            try
            {
                this.bitmapData = BasicImageOpertions.BitmapToBitmapData(bmp);

                unsafe                                              // C# doesn't support pointer arithmetic
                {
                    byte *PtrFirstPixel = (byte *)bitmapData.Scan0; // Point to first pixel

                    for (int y = 0; y < heightInPixels; y++)
                    {
                        byte *currentLine = PtrFirstPixel + (y * bitmapData.Stride);

                        for (int x = 0; x < widthInBytes; x += bytesPerPixel)
                        {
                            double val = currentLine[x] + value * (256 / 256.0);

                            if (val < 0)
                            {
                                val = 0;
                            }
                            else if (val > 255)
                            {
                                val = 255;
                            }

                            currentLine[x]     = (byte)val;
                            currentLine[x + 1] = (byte)val;
                            currentLine[x + 2] = (byte)val;
                        }
                    }
                    bmp.UnlockBits(bitmapData);
                }
                OnImageFinished(bmp);
            }
            catch
            {
                System.Windows.Forms.MessageBox.Show("Please select image first", "Error");
            }
        }
示例#12
0
        public void SetImageAndHist(Bitmap image)
        {
            originalImage = image;

            secondaryImage = (Bitmap)image.Clone();

            this.pctbImage.Image = null;

            this.pctbImage.Image = image;
            this.pctbImage.Show();

            hist = new ImageHistogram((Bitmap)pctbImage.Image, this);

            hist.CreateChart(chHisto);
            this.pctbHistogram.Show();

            basicImageOpertions = new BasicImageOpertions((Bitmap)pctbImage.Image);

            basicImageOpertions.ImageFinished += OnImageFinished;

            this.Refresh();
        }
        public void Stretching(int value1, int value2)
        {
            this.ToGreyScale();

            try
            {
                this.bitmapData = BasicImageOpertions.BitmapToBitmapData(bmp);

                unsafe                                              // C# doesn't support pointer arithmetic
                {
                    byte *PtrFirstPixel = (byte *)bitmapData.Scan0; // Point to first pixel

                    for (int y = 0; y < heightInPixels; y++)
                    {
                        byte *currentLine = PtrFirstPixel + (y * bitmapData.Stride);

                        for (int x = 0; x < widthInBytes; x += bytesPerPixel)
                        {
                            if (currentLine[x] > value1 && currentLine[x] <= value2)
                            {
                                Console.Write("Dupaaaa");

                                currentLine[x]     = (byte)((currentLine[x] - value1) * ((255) / (value2 - value1)));
                                currentLine[x + 1] = (byte)((currentLine[x + 1] - value1) * ((255) / (value2 - value1)));
                                currentLine[x + 2] = (byte)((currentLine[x + 2] - value1) * ((255) / (value2 - value1)));
                            }
                        }
                    }
                    bmp.UnlockBits(bitmapData);
                }
                OnImageFinished(bmp);
            }
            catch
            {
                System.Windows.Forms.MessageBox.Show("Please select image first", "Error");
            }
        }
        public void XOR(Bitmap imgToAdd)
        {
            this.ToGreyScale();

            try
            {
                this.bitmapData = BasicImageOpertions.BitmapToBitmapData(bmp);
                BitmapData bitmapDataSecImage = BasicImageOpertions.BitmapToBitmapData(imgToAdd);

                unsafe                                               // C# doesn't support pointer arithmetic
                {
                    byte *PtrFirstPixel1 = (byte *)bitmapData.Scan0; // Point to first pixel
                    byte *PtrFirstPixel2 = (byte *)bitmapDataSecImage.Scan0;

                    for (int y = 0; y < heightInPixels; y++)
                    {
                        byte *currentLineFirst = PtrFirstPixel1 + (y * bitmapData.Stride);
                        byte *currentLineSec   = PtrFirstPixel2 + (y * bitmapData.Stride);

                        for (int x = 0; x < widthInBytes; x += bytesPerPixel)
                        {
                            currentLineFirst[x]     = (byte)(currentLineFirst[x] ^ currentLineSec[x]);
                            currentLineFirst[x + 1] = (byte)(currentLineFirst[x + 1] ^ currentLineSec[x + 1]);
                            currentLineFirst[x + 2] = (byte)(currentLineFirst[x + 2] ^ currentLineSec[x + 2]);
                        }
                    }
                    bmp.UnlockBits(bitmapData);
                    imgToAdd.UnlockBits(bitmapDataSecImage);
                }
                OnImageFinished(bmp);
            }
            catch
            {
                System.Windows.Forms.MessageBox.Show("Please select image first", "Error");
            }
        }
        public BeforeAfterPanel(Bitmap bitmap, Operacje operacja, Image_Panel caller)
        {
            InitializeComponent();

            this.Origbitmap = bitmap;
            newBitmap       = (Bitmap)bitmap.Clone();

            basicImage = new BasicImageOpertions(this.newBitmap);
            basicImage.ImageFinished += OnImageFinished;

            this.pctbInput.Image = Origbitmap;
            this.operacja        = operacja;

            this.caller = caller;

            switch (operacja)
            {
            case Operacje.Progowanie:
                tbArgument.Minimum = 0;
                tbArgument.Maximum = 255;
                tbArgument.Value   = 127;
                this.Text          = "Progowanie";
                basicImage.Threshold(tbArgument.Value);
                break;

            case Operacje.ProgowanieZZachowaniem:
                tbArgument.Minimum = 0;
                tbArgument.Maximum = 255;
                tbArgument.Value   = 127;
                this.Text          = "Progowanie";
                basicImage.ThresholdWithRetention(tbArgument.Value);
                break;

            case Operacje.Rozciaganie:
                this.tbSecondArgument.Enabled = true;
                this.tbSecondArgument.Visible = true;
                this.lbValue2.Visible         = true;

                tbArgument.Minimum = 0;
                tbArgument.Maximum = 255;
                tbArgument.Value   = 127;

                tbSecondArgument.Minimum = 0;
                tbSecondArgument.Maximum = 255;
                tbSecondArgument.Value   = 127;

                this.Text = "Rozciaganie";
                basicImage.Stretching(tbArgument.Value, tbSecondArgument.Value);
                break;

            case Operacje.Jasnosc:
                tbArgument.Minimum = -255;
                tbArgument.Maximum = 255;
                tbArgument.Value   = 0;
                this.Text          = "Jasność";
                basicImage.Brightness(tbArgument.Value);
                break;

            case Operacje.Redukcja:
                tbArgument.Minimum = 2;
                tbArgument.Maximum = 255;
                tbArgument.Value   = 127;
                this.Text          = "Redukcja";
                basicImage.Reduction(tbArgument.Value);
                break;
            }

            this.lbValue.Text  = tbArgument.Value.ToString();
            this.lbValue2.Text = tbSecondArgument.Value.ToString();
        }
        public void EqulizeHist(int method)
        {
            CreateHistogram();

            Bitmap tmp = (Bitmap)bitmap.Clone();

            int Rr = 0;
            int Rg = 0;
            int Rb = 0;

            int HintR = 0;
            int HintG = 0;
            int HintB = 0;

            int HavgR = (int)Red.Average();
            int HavgG = (int)Green.Average();
            int HavgB = (int)Blue.Average();

            int[] leftR  = new int[toneHistogram.Count];
            int[] rightR = new int[toneHistogram.Count];
            int[] _newR  = new int[toneHistogram.Count];

            int[] leftG  = new int[toneHistogram.Count];
            int[] rightG = new int[toneHistogram.Count];
            int[] _newG  = new int[toneHistogram.Count];

            int[] leftB  = new int[toneHistogram.Count];
            int[] rightB = new int[toneHistogram.Count];
            int[] _newB  = new int[toneHistogram.Count];

            int z;

            for (z = 0; z < toneHistogram.Count - 1; ++z)
            {
                leftR[z] = Rr;
                HintR   += Red[z];

                leftG[z] = Rg;
                HintG   += Green[z];

                leftB[z] = Rb;
                HintB   += Blue[z];

                while (HintR > HavgR)
                {
                    HintR -= HavgR;
                    Rr++;
                }
                if (Rr > toneHistogram.Count - 1)
                {
                    Rr = toneHistogram.Count - 1;
                }

                while (HintG > HavgG)
                {
                    HintG -= HavgG;
                    Rg++;
                }
                if (Rg > toneHistogram.Count - 1)
                {
                    Rg = toneHistogram.Count - 1;
                }

                while (HintB > HavgB)
                {
                    HintB -= HavgB;
                    Rb++;
                }
                if (Rb > toneHistogram.Count - 1)
                {
                    Rb = toneHistogram.Count - 1;
                }

                rightR[z] = Rr;
                rightG[z] = Rg;
                rightB[z] = Rb;

                switch (method)
                {
                case 1:
                    _newR[z] = (leftR[z] + rightR[z]) / 2;
                    _newG[z] = (leftG[z] + rightG[z]) / 2;
                    _newB[z] = (leftB[z] + rightB[z]) / 2;
                    break;

                case 2:
                    _newR[z] = rightR[z] - leftR[z];
                    _newG[z] = rightG[z] - leftG[z];
                    _newB[z] = rightB[z] - leftB[z];
                    break;

                case 3:
                    _newR[z] = (leftR[z] + rightR[z]) / 2;
                    _newG[z] = (leftG[z] + rightG[z]) / 2;
                    _newB[z] = (leftB[z] + rightB[z]) / 2;
                    break;

                case 4:
                    _newR[z] = (leftR[z] + rightR[z]) / 2;
                    _newG[z] = (leftG[z] + rightG[z]) / 2;
                    _newB[z] = (leftB[z] + rightB[z]) / 2;
                    break;
                }
            }

            Random random = new Random();

            try
            {
                bitmapData = BasicImageOpertions.BitmapToBitmapData(tmp);

                int bytesPerPixel  = System.Drawing.Bitmap.GetPixelFormatSize(tmp.PixelFormat) / 8;
                int heightInPixels = bitmapData.Height;
                int widthInBytes   = bitmapData.Width * bytesPerPixel;


                unsafe                                              // C# doesn't support pointer arithmetic
                {
                    byte *PtrFirstPixel = (byte *)bitmapData.Scan0; // Point to first pixel

                    for (int y = 0; y < heightInPixels; y++)
                    {
                        byte *currentLine   = PtrFirstPixel + (y * bitmapData.Stride);
                        byte *HelperPointer = PtrFirstPixel + (y * bitmapData.Stride);

                        for (int x = 0; x < widthInBytes; x += bytesPerPixel)
                        {
                            byte colorR = 0;
                            byte colorG = 0;
                            byte colorB = 0;

                            byte valR = currentLine[x + 2];
                            byte valG = currentLine[x + 1];
                            byte valB = currentLine[x];

                            if (leftR[valR] == rightR[valR])
                            {
                                colorR = (byte)leftR[valR];
                            }
                            if (leftG[valG] == rightG[valG])
                            {
                                colorG = (byte)leftG[valG];
                            }
                            if (leftB[valB] == rightB[valB])
                            {
                                colorB = (byte)leftB[valB];
                            }
                            else
                            {
                                switch (method)
                                {
                                case 1:     //Average
                                    colorR = (byte)_newR[valR];
                                    colorG = (byte)_newG[valG];
                                    colorB = (byte)_newB[valB];
                                    break;

                                case 2:     //Random
                                    int valueR = random.Next(0, _newR[valR]);
                                    colorR = (byte)(leftR[valR] + valueR);

                                    int valueG = random.Next(0, _newG[valG]);
                                    colorG = (byte)(leftG[valG] + valueG);

                                    int valueB = random.Next(0, _newB[valB]);
                                    colorB = (byte)(leftR[valB] + valueB);

                                    break;

                                case 3:    //Neighbour
                                    double averageR = 0;
                                    double averageG = 0;
                                    double averageB = 0;

                                    int count = 0;
                                    foreach (Point offset in new Point[] { new Point(1, 0), new Point(-1, 0), new Point(0, 1), new Point(0, -1), new Point(1, 1), new Point(-1, -1), new Point(-1, 1), new Point(1, -1) })
                                    {
                                        if (x / bytesPerPixel + offset.X >= 0 && x / bytesPerPixel + offset.X < bitmap.Width && y + offset.Y >= 0 && y + offset.Y < bitmap.Height)
                                        {
                                            Color col = bitmap.GetPixel(x / bytesPerPixel + offset.X, y + offset.Y);

                                            averageR = col.R;
                                            averageG = col.G;
                                            averageB = col.B;

                                            ++count;
                                        }
                                    }
                                    averageR /= count;
                                    averageG /= count;
                                    averageB /= count;

                                    if (averageR > rightR[valR])
                                    {
                                        colorR = (byte)rightR[valR];
                                    }
                                    else if (averageR < leftR[valR])
                                    {
                                        colorR = (byte)leftR[valR];
                                    }
                                    else
                                    {
                                        colorR = (byte)((int)averageR);
                                    }

                                    if (averageG > rightG[valG])
                                    {
                                        colorG = (byte)rightG[valG];
                                    }
                                    else if (averageG < leftG[valG])
                                    {
                                        colorG = (byte)leftG[valG];
                                    }
                                    else
                                    {
                                        colorG = (byte)((int)averageG);
                                    }

                                    if (averageB > rightR[valB])
                                    {
                                        colorB = (byte)rightB[valB];
                                    }
                                    else if (averageB < leftB[valB])
                                    {
                                        colorB = (byte)leftB[valB];
                                    }
                                    else
                                    {
                                        colorB = (byte)((int)averageB);
                                    }


                                    break;

                                case 4:     //Own
                                    averageR = 0;
                                    averageG = 0;
                                    averageB = 0;

                                    count = 0;
                                    foreach (Point offset in new Point[] { new Point(1, 0), new Point(-1, 0), new Point(0, 1), new Point(0, -1), new Point(1, 1), new Point(-1, -1), new Point(-1, 1), new Point(1, -1) })
                                    {
                                        if (x / bytesPerPixel + offset.X >= 0 && x / bytesPerPixel + offset.X < bitmap.Width && y + offset.Y >= 0 && y + offset.Y < bitmap.Height)
                                        {
                                            Color col = bitmap.GetPixel(x / bytesPerPixel + offset.X, y + offset.Y);

                                            averageR = col.R;
                                            averageG = col.G;
                                            averageB = col.B;

                                            ++count;

                                            ++count;
                                        }
                                    }
                                    averageR /= count;
                                    averageG /= count;
                                    averageB /= count;

                                    if (averageR > rightR[valR])
                                    {
                                        colorR = (byte)rightR[valR];
                                    }
                                    else if (averageR < leftR[valR])
                                    {
                                        colorR = (byte)leftR[valR];
                                    }
                                    else
                                    {
                                        colorR = (byte)((int)averageR);
                                    }

                                    if (averageG > rightG[valG])
                                    {
                                        colorG = (byte)rightG[valG];
                                    }
                                    else if (averageG < leftG[valG])
                                    {
                                        colorG = (byte)leftG[valG];
                                    }
                                    else
                                    {
                                        colorG = (byte)((int)averageG);
                                    }

                                    if (averageB > rightB[valB])
                                    {
                                        colorB = (byte)rightB[valB];
                                    }
                                    else if (averageB < leftB[valB])
                                    {
                                        colorB = (byte)leftB[valB];
                                    }
                                    else
                                    {
                                        colorB = (byte)((int)averageB);
                                    }

                                    break;

                                default:
                                    break;
                                }
                            }

                            currentLine[x + 2] = colorR;
                            currentLine[x + 1] = colorG;
                            currentLine[x]     = colorB;
                        }
                    }

                    tmp.UnlockBits(bitmapData);
                }
            }
            catch
            {
                System.Windows.Forms.MessageBox.Show("Please select image first", "Error");
            }
            caller.SetImageAndHist(tmp);
        }
        public Bitmap LogicalFilter(int angle)
        {
            int size  = 3;
            int index = size - size / 2 - 1;

            try
            {
                this.bitmapData          = BasicImageOpertions.BitmapToBitmapData(bmp);
                this.secondaryBitmapData = BasicImageOpertions.BitmapToBitmapData(SecondaryBitmap);

                unsafe                                                                // C# doesn't support pointer arithmetic
                {
                    byte *PtrFirstPixelFirst     = (byte *)bitmapData.Scan0;          // Point to first pixel of first image
                    byte *PtrFirstPixelSecondary = (byte *)secondaryBitmapData.Scan0; // Point to first pixel of helper image

                    for (int y = index; y < heightInPixels - index; y++)
                    {
                        byte *currentLineOld = PtrFirstPixelFirst + (y * bitmapData.Stride);
                        byte *currentLineNew = PtrFirstPixelSecondary + (y * secondaryBitmapData.Stride);

                        for (int x = index * bytesPerPixel; x < widthInBytes - index * bytesPerPixel; x += bytesPerPixel)
                        {
                            byte *colCenter = (byte *)(PtrFirstPixelFirst + (y * bitmapData.Stride) + x);

                            int newColor = *colCenter;

                            switch (angle)
                            {
                            case 0:
                                byte *colLeft  = (byte *)(PtrFirstPixelFirst + ((y + 0) * bitmapData.Stride) + x + 1 * bytesPerPixel);
                                byte *colRight = (byte *)(PtrFirstPixelFirst + ((y + 0) * bitmapData.Stride) + x + (-1) * bytesPerPixel);

                                if (*colLeft == *colRight)
                                {
                                    newColor = *colRight;
                                }

                                break;

                            case 45:
                                byte *colDownLeft = (byte *)(PtrFirstPixelFirst + ((y + 1) * bitmapData.Stride) + x + (-1) * bytesPerPixel);
                                byte *colTopRight = (byte *)(PtrFirstPixelFirst + ((y + -1) * bitmapData.Stride) + x + 1 * bytesPerPixel);

                                if (*colDownLeft == *colTopRight)
                                {
                                    newColor = *colDownLeft;
                                }

                                break;


                            case 90:
                                byte *colTop  = (byte *)(PtrFirstPixelFirst + ((y + -1) * bitmapData.Stride) + x + 0 * bytesPerPixel);
                                byte *colDown = (byte *)(PtrFirstPixelFirst + ((y + 1) * bitmapData.Stride) + x + 0 * bytesPerPixel);

                                if (*colTop == *colDown)
                                {
                                    newColor = *colTop;
                                }

                                break;

                            case 135:
                                byte *colTopLeft   = (byte *)(PtrFirstPixelFirst + ((y + -1) * bitmapData.Stride) + x + (-1) * bytesPerPixel);
                                byte *colDownRight = (byte *)(PtrFirstPixelFirst + ((y + 1) * bitmapData.Stride) + x + 1 * bytesPerPixel);

                                if (*colTopLeft == *colDownRight)
                                {
                                    newColor = *colTopLeft;
                                }

                                break;
                            }

                            int finalColor = newColor;

                            currentLineNew[x]     = (byte)finalColor;
                            currentLineNew[x + 1] = (byte)finalColor;
                            currentLineNew[x + 2] = (byte)finalColor;
                        }
                    }
                }
                bmp.UnlockBits(bitmapData);
                SecondaryBitmap.UnlockBits(secondaryBitmapData);
            }
            catch
            {
                System.Windows.Forms.MessageBox.Show("Please select image first", "Error");
            }
            return(SecondaryBitmap);
        }
        public Bitmap MedianFilter(int m, int n, int outlierMethod)
        {
            int indexM = m - m / 2 - 1;
            int indexN = n - n / 2 - 1;

            Point[,] temp = new Point[m, n];

            for (int i = -indexM; i <= indexM; i++)
            {
                for (int j = -indexN; j <= indexN; j++)
                {
                    temp[i + indexM, j + indexN] = new Point(i, j);
                }
            }

            byte[] pixels = new byte[m * n];

            if (outlierMethod == 0)
            {
                indexM = 0;
                indexN = 0;
            }

            try
            {
                this.bitmapData          = BasicImageOpertions.BitmapToBitmapData(bmp);
                this.secondaryBitmapData = BasicImageOpertions.BitmapToBitmapData(SecondaryBitmap);

                unsafe                                                                // C# doesn't support pointer arithmetic
                {
                    byte *PtrFirstPixelFirst     = (byte *)bitmapData.Scan0;          // Point to first pixel of first image
                    byte *PtrFirstPixelSecondary = (byte *)secondaryBitmapData.Scan0; // Point to first pixel of helper image

                    for (int y = indexN; y < heightInPixels - indexN; y++)
                    {
                        byte *currentLineOld = PtrFirstPixelFirst + (y * bitmapData.Stride);
                        byte *currentLineNew = PtrFirstPixelSecondary + (y * secondaryBitmapData.Stride);

                        for (int x = indexM * bytesPerPixel; x < widthInBytes - indexM * bytesPerPixel; x += bytesPerPixel)
                        {
                            int p = 0;

                            for (int k = 0; k < m; k++)
                            {
                                for (int l = 0; l < n; l++)
                                {
                                    if (x + temp[k, l].X * bytesPerPixel >= 0 && x + temp[k, l].X * bytesPerPixel < widthInBytes && y + temp[k, l].Y >= 0 && y + temp[k, l].Y < heightInPixels)
                                    {
                                        byte *col = (byte *)(PtrFirstPixelFirst + ((y + temp[k, l].Y) * bitmapData.Stride) + x + temp[k, l].X * bytesPerPixel);
                                        pixels[p] = *col;
                                        ++p;
                                    }
                                }
                            }

                            Array.Sort(pixels);

                            byte finalColor = KernelOpperations.GetMedian(pixels);

                            currentLineNew[x]     = (byte)finalColor;
                            currentLineNew[x + 1] = (byte)finalColor;
                            currentLineNew[x + 2] = (byte)finalColor;
                        }
                    }
                }
                bmp.UnlockBits(bitmapData);
                SecondaryBitmap.UnlockBits(secondaryBitmapData);
            }
            catch
            {
                System.Windows.Forms.MessageBox.Show("Please select image first", "Error");
            }
            return(SecondaryBitmap);
        }
        public Bitmap Erosion(int scaling_type, int outlierMethod, int neighbours)
        {
            int size  = 3;
            int index = size - size / 2 - 1;

            Point[,] temp = new Point[size, size];

            for (int i = -index; i <= index; i++)
            {
                for (int j = -index; j <= index; j++)
                {
                    temp[i + index, j + index] = new Point(i, j);
                }
            }


            if (outlierMethod == 0)
            {
                index = 0;
            }

            try
            {
                this.bitmapData          = BasicImageOpertions.BitmapToBitmapData(bmp);
                this.secondaryBitmapData = BasicImageOpertions.BitmapToBitmapData(SecondaryBitmap);

                unsafe                                                                // C# doesn't support pointer arithmetic
                {
                    byte *PtrFirstPixelFirst     = (byte *)bitmapData.Scan0;          // Point to first pixel of first image
                    byte *PtrFirstPixelSecondary = (byte *)secondaryBitmapData.Scan0; // Point to first pixel of helper image

                    for (int y = index; y < heightInPixels - index; y++)
                    {
                        byte *currentLineOld = PtrFirstPixelFirst + (y * bitmapData.Stride);
                        byte *currentLineNew = PtrFirstPixelSecondary + (y * secondaryBitmapData.Stride);

                        for (int x = index * bytesPerPixel; x < widthInBytes - index * bytesPerPixel; x += bytesPerPixel)
                        {
                            byte *colCenter = (byte *)(PtrFirstPixelFirst + (y * bitmapData.Stride) + x);

                            int newColor = *colCenter;

                            for (int k = 0; k < size; k++)
                            {
                                for (int l = 0; l < size; l++)
                                {
                                    if (x + temp[k, l].X * bytesPerPixel >= 0 && x + temp[k, l].X * bytesPerPixel < widthInBytes && y + temp[k, l].Y >= 0 && y + temp[k, l].Y < heightInPixels)
                                    {
                                        if (neighbours == 4 && Math.Abs(temp[k, l].X) != Math.Abs(temp[k, l].Y))
                                        {
                                            byte *col = (byte *)(PtrFirstPixelFirst + ((y + temp[k, l].Y) * bitmapData.Stride) + x + temp[k, l].X * bytesPerPixel);

                                            if (newColor > *col)
                                            {
                                                newColor = *col;
                                            }
                                        }
                                        else
                                        {
                                            byte *col = (byte *)(PtrFirstPixelFirst + ((y + temp[k, l].Y) * bitmapData.Stride) + x + temp[k, l].X * bytesPerPixel);

                                            if (newColor > *col)
                                            {
                                                newColor = *col;
                                            }
                                        }
                                    }
                                }
                            }

                            int finalColor = newColor;

                            finalColor = scale.Scale(newColor, scaling_type);

                            currentLineNew[x]     = (byte)finalColor;
                            currentLineNew[x + 1] = (byte)finalColor;
                            currentLineNew[x + 2] = (byte)finalColor;
                        }
                    }
                }
                bmp.UnlockBits(bitmapData);
                SecondaryBitmap.UnlockBits(secondaryBitmapData);
            }
            catch
            {
                System.Windows.Forms.MessageBox.Show("Please select image first", "Error");
            }
            return(SecondaryBitmap);
        }
        public Bitmap LinearFilter(int[,] mask, int scaling_type, int outlierMethod)
        {
            int size    = (int)Math.Sqrt(mask.Length);
            int index   = size - size / 2 - 1;
            int divisor = 0;

            for (int i = 0; i < size; ++i)
            {
                for (int j = 0; j < size; ++j)
                {
                    divisor += mask[i, j];
                }
            }

            if (divisor == 0)
            {
                divisor = 1;
            }

            Point[,] temp = new Point[size, size];

            for (int i = -index; i <= index; i++)
            {
                for (int j = -index; j <= index; j++)
                {
                    temp[i + index, j + index] = new Point(i, j);
                }
            }

            if (outlierMethod == 0)
            {
                index = 0;
            }

            try
            {
                this.bitmapData          = BasicImageOpertions.BitmapToBitmapData(bmp);
                this.secondaryBitmapData = BasicImageOpertions.BitmapToBitmapData(SecondaryBitmap);

                unsafe                                                                // C# doesn't support pointer arithmetic
                {
                    byte *PtrFirstPixelFirst     = (byte *)bitmapData.Scan0;          // Point to first pixel of first image
                    byte *PtrFirstPixelSecondary = (byte *)secondaryBitmapData.Scan0; // Point to first pixel of helper image

                    for (int y = index; y < heightInPixels - index; y++)
                    {
                        byte *currentLineOld = PtrFirstPixelFirst + (y * bitmapData.Stride);
                        byte *currentLineNew = PtrFirstPixelSecondary + (y * secondaryBitmapData.Stride);

                        for (int x = index * bytesPerPixel; x < widthInBytes - index * bytesPerPixel; x += bytesPerPixel)
                        {
                            int newColor = 0;

                            for (int k = 0; k < size; k++)
                            {
                                for (int l = 0; l < size; l++)
                                {
                                    if (x + temp[k, l].X * bytesPerPixel >= 0 && x + temp[k, l].X * bytesPerPixel < widthInBytes && y + temp[k, l].Y >= 0 && y + temp[k, l].Y < heightInPixels)
                                    {
                                        byte *col = (byte *)(PtrFirstPixelFirst + ((y + temp[k, l].Y) * bitmapData.Stride) + x + temp[k, l].X * bytesPerPixel);

                                        newColor += (int)(mask[k, l] * (int)*col);
                                    }
                                }
                            }

                            newColor /= divisor;
                            int finalColor = newColor;

                            finalColor = scale.Scale(newColor, scaling_type);

                            currentLineNew[x]     = (byte)finalColor;
                            currentLineNew[x + 1] = (byte)finalColor;
                            currentLineNew[x + 2] = (byte)finalColor;
                        }
                    }
                }
                bmp.UnlockBits(bitmapData);
                SecondaryBitmap.UnlockBits(secondaryBitmapData);
            }
            catch
            {
                System.Windows.Forms.MessageBox.Show("Please select image first", "Error");
            }
            return(SecondaryBitmap);
        }