Monday, 20 November 2017

ImageGrassy: An Image Processing and Utility Tool

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Win32;
using System.Windows.Media.Imaging;
using System.IO;
namespace ImageApplications
{
    public struct PixelColor
    {
        public byte Blue;
        public byte Green;
        public byte Red;
        public byte Alpha;
        public PixelColor(int r, int g, int b, int a)
        {
            this.Red = (byte)r;
            this.Green = (byte)g;
            this.Blue = (byte)b;
            this.Alpha = (byte)a;
        }
    }
   
    public class Bitmap
    {
        public BitmapSource Image;
        private BitmapImage iSrc;
        private byte []array;
        private Int32Rect rect;
        public int Height, Width;
       public int NumCol, NumRow;
       
        public Bitmap(string fileName)
        {
            iSrc = new BitmapImage(new Uri(fileName));
            Image = iSrc;
            array = new byte[iSrc.PixelWidth * iSrc.PixelHeight * 4];
            rect = new Int32Rect(0, 0, iSrc.PixelWidth, iSrc.PixelHeight);
            iSrc.CopyPixels(rect, array, iSrc.PixelWidth * 4, 0);
            NumRow = iSrc.PixelHeight;
            NumCol = iSrc.PixelWidth;
            Height = NumRow;
            Width = NumCol;
           
               
        }
        public Bitmap(BitmapImage bmpSrc)
        {
            iSrc = bmpSrc;
            Image = iSrc;
            array = new byte[iSrc.PixelWidth * iSrc.PixelHeight * 4];
            rect = new Int32Rect(0, 0, iSrc.PixelWidth, iSrc.PixelHeight);
            iSrc.CopyPixels(rect, array, iSrc.PixelWidth * 4, 0);
            NumRow = iSrc.PixelHeight;
            NumCol = iSrc.PixelWidth;
            Height = NumRow;
            Width = NumCol;


        }
        private  BitmapImage CropImage(ImageSource source, int width, int height, int startx,int starty)
        {
            var rect = new Rect(startx, starty, startx+width , height +startx);
            var group = new DrawingGroup();
            RenderOptions.SetBitmapScalingMode(group, BitmapScalingMode.HighQuality);
            group.Children.Add(new ImageDrawing(source, rect));
            var drawingVisual = new DrawingVisual();
            using (var drawingContext = drawingVisual.RenderOpen())
                drawingContext.DrawDrawing(group);
            var resizedImage = new RenderTargetBitmap(
                width, height,         // Resized dimensions
                96, 96,                // Default DPI values
                PixelFormats.Default); // Default pixel format
            resizedImage.Render(drawingVisual);
            BitmapSource bf= BitmapFrame.Create(resizedImage);
            BitmapImage bi = BitmapImageFromBitmapSource(bf);
            return bi;
        }
        public void CropTheImage(int startx, int starty, int width, int height)
        {
            Image = CropImage(Image, width, height, startx, starty);
        }
        public  void Resize(int rRows,int rCols)
        {
           
            TransformedBitmap tb = new System.Windows.Media.Imaging.TransformedBitmap(
                  Image, new ScaleTransform((double)rRows/iSrc.Height, (double)rCols/iSrc.Width));
            Image = tb;
            iSrc = BitmapImageFromBitmapSource(Image);
            array = new byte[iSrc.PixelWidth * iSrc.PixelHeight * 4];
            rect = new Int32Rect(0, 0, iSrc.PixelWidth, iSrc.PixelHeight);
            iSrc.CopyPixels(rect, array, iSrc.PixelWidth * 4, 0);
            NumRow = iSrc.PixelHeight;
            NumCol = iSrc.PixelWidth;
            Height = NumRow;
            Width = NumCol;
        }
        public Bitmap(int Height,int Width)
        {
            WriteableBitmap wb = new System.Windows.Media.Imaging.WriteableBitmap(
                   Width, Height, 96, 96, PixelFormats.Bgra32, null);
            Image = wb;
           
            iSrc = BitmapImageFromBitmapSource(Image);
            //BitmapImage bmp=new System.Windows.Media.Imaging.BitmapImage(
            //iSrc = bmpSrc;
            //iSrc.H
           
            array = new byte[iSrc.PixelWidth * iSrc.PixelHeight * 4];
            rect = new Int32Rect(0, 0, iSrc.PixelWidth, iSrc.PixelHeight);
            iSrc.CopyPixels(rect, array, iSrc.PixelWidth * 4, 0);
            NumRow = iSrc.PixelHeight;
            NumCol = iSrc.PixelWidth;
            Height = NumRow;
            Width = NumCol;


        }
        #region Image Processing Stuff
        public void Finalize()
        {
           
            Image=WriteableBitmap.Create(iSrc.PixelWidth, iSrc.PixelHeight,
                       96, 96, PixelFormats.Bgra32, null, array, iSrc.PixelWidth * 4);
        }
        private PixelColor GetPixelValue(int x, int y, byte[] rawpixel, int width, int hight)
        {
            PixelColor pointpixel;
            int offset = y * width * 4 + x * 4;
            pointpixel.Blue = rawpixel[offset + 0];
            pointpixel.Green = rawpixel[offset + 1];
            pointpixel.Red = rawpixel[offset + 2];
            pointpixel.Alpha = rawpixel[offset + 3];
            return pointpixel;
        }
        public PixelColor GetPixel(int x,int y)
        {
            return(GetPixelValue( x,  y, array, Width, Height));
        }
        public void SetPixel(int x,int y, PixelColor color)
        {
            array=PutPixel(array, Width, Height, color,  x,  y);
        }
       private byte[] PutPixel(byte[] rawimagepixel, int width, int hight, PixelColor pixels, int x, int y)
        {
            int offset = y * width * 4 + x * 4;
            rawimagepixel[offset + 0] = pixels.Blue;
            rawimagepixel[offset + 1] = pixels.Green;
            rawimagepixel[offset + 2] = pixels.Red;
            rawimagepixel[offset + 3] = pixels.Alpha;
            return rawimagepixel;
        }
       public static BitmapImage BitmapImageFromBitmapSource(BitmapSource src)
       {
           BitmapSource bitmapSource = src;
           JpegBitmapEncoder encoder = new JpegBitmapEncoder();
           MemoryStream memoryStream = new MemoryStream();
           BitmapImage bImg = new BitmapImage();
           encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
           encoder.Save(memoryStream);
           bImg.BeginInit();
           bImg.StreamSource = new MemoryStream(memoryStream.ToArray());
           bImg.EndInit();
           memoryStream.Close();
           return bImg;
       }
       public  void Save(string filePath)
       {
           var image = Image;
           using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
           {
               BitmapEncoder encoder = new JpegBitmapEncoder();
               encoder.Frames.Add(BitmapFrame.Create(image));
               encoder.Save(fileStream);
           }
       }
        #endregion
    }


public static BitmapSource Gray2Binary(BitmapImage grayImage,double threshold)
{
    if (threshold > 1)
    {
        throw new ApplicationException("Threshold must be between 0 and 1");
    }
    if (threshold < 0)
    {
        threshold = System.Math.Abs(threshold);
    }
    threshold = 255 * threshold;
    Bitmap bmp = new Bitmap(grayImage);
    for (int i = 0; i < bmp.NumRow; i++)
    {
        for (int j = 0; j < bmp.NumCol; j++)
        {
            PixelColor c = bmp.GetPixel(j, i);
            //Color c = bmp.GetPixel(j, i);// Extract the color of a pixel
            int rd = c.Red;
            double d1 = 0;
            if (rd > threshold)
            {
                d1 = 255;
            }
            int c1 = (int)Math.Round(d1);
            PixelColor c2 = new PixelColor(c1, c1, c1, c.Alpha);
            bmp.SetPixel(j, i, c2);
        }
    }
    bmp.Finalize();
    return bmp.Image;
   
}

public static BitmapSource WaveletTransform(BitmapImage bmpSource, int function,int m_threshold)
{
    int[,] orgred;
    int[,] orgblue;
    int[,] orggreen;
    int[,] rowred;
    int[,] rowblue;
    int[,] rowgreen;
    int[,] colred;
    int[,] colblue;
    int[,] colgreen;
    int[,] scalered;
    int[,] scaleblue;
    int[,] scalegreen;
    int[,] recrowred;
    int[,] recrowblue;
    int[,] recrowgreen;
    int[,] recorgred;
    int[,] recorgblue;
    int[,] recorggreen;
    Bitmap bitmap = new Bitmap(bmpSource);
    // BitmapData bitmapdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width,
    //     bitmap.Height), ImageLockMode.ReadWrite, img.PixelFormat);
    orgred = new int[bitmap.Height + 1, bitmap.Width + 1];
    orgblue = new int[bitmap.Height + 1, bitmap.Width + 1];
    orggreen = new int[bitmap.Height + 1, bitmap.Width + 1];
    rowred = new int[bitmap.Height + 1, bitmap.Width + 1];
    rowblue = new int[bitmap.Height + 1, bitmap.Width + 1];
    rowgreen = new int[bitmap.Height + 1, bitmap.Width + 1];
    colred = new int[bitmap.Height + 1, bitmap.Width + 1];
    colblue = new int[bitmap.Height + 1, bitmap.Width + 1];
    colgreen = new int[bitmap.Height + 1, bitmap.Width + 1];
    scalered = new int[bitmap.Height + 1, bitmap.Width + 1];
    scaleblue = new int[bitmap.Height + 1, bitmap.Width + 1];
    scalegreen = new int[bitmap.Height + 1, bitmap.Width + 1];
    recrowred = new int[bitmap.Height + 1, bitmap.Width + 1];
    recrowblue = new int[bitmap.Height + 1, bitmap.Width + 1];
    recrowgreen = new int[bitmap.Height + 1, bitmap.Width + 1];
    recorgred = new int[bitmap.Height + 1, bitmap.Width + 1];
    recorgblue = new int[bitmap.Height + 1, bitmap.Width + 1];
    recorggreen = new int[bitmap.Height + 1, bitmap.Width + 1];
    //unsafe
    {
     
        for (int i = 0; i < bitmap.Height; i++)
        {
            for (int j = 0; j < bitmap.Width; j++)
            {
                orgred[i, j] = bitmap.GetPixel(j,i).Red;
                orggreen[i, j] = bitmap.GetPixel(j, i).Green;
                orgblue[i, j] = bitmap.GetPixel(j, i).Blue;
               
            }
         
        }
    }
    //Transform rows
    for (int r = 0; r < bitmap.Height; r++)
    {
        int k = 0;
        for (int p = 0; p < bitmap.Width; p = p + 2)
        {
            rowred[r, k] = (int)((double)(orgred[r, p] + orgred[r, p + 1]) / 2);
            rowred[r, k + (bitmap.Width / 2)] = (int)((double)(orgred[r, p] - orgred[r, p + 1]) / 2);
            rowgreen[r, k] = (int)((double)(orggreen[r, p] + orggreen[r, p + 1]) / 2);
            rowgreen[r, k + (bitmap.Width / 2)] = (int)((double)(orggreen[r, p] - orggreen[r, p + 1]) / 2);
            rowblue[r, k] = (int)((double)(orgblue[r, p] + orgblue[r, p + 1]) / 2);
            rowblue[r, k + (bitmap.Width / 2)] = (int)((double)(orgblue[r, p] - orgblue[r, p + 1]) / 2);
            k++;
        }
    }
    //Transform columns
    for (int c = 0; c < bitmap.Width; c++)
    {
        int k = 0;
        for (int p = 0; p < bitmap.Height; p = p + 2)
        {
            colred[k, c] = (int)((double)(rowred[p, c] + rowred[p + 1, c]) / 2);
            colred[k + bitmap.Height / 2, c] = (int)((double)(rowred[p, c] - rowred[p + 1, c]) / 2);
            colgreen[k, c] = (int)((double)(rowgreen[p, c] + rowgreen[p + 1, c]) / 2);
            colgreen[k + bitmap.Height / 2, c] = (int)((double)(rowgreen[p, c] - rowgreen[p + 1, c]) / 2);
            colblue[k, c] = (int)((double)(rowblue[p, c] + rowblue[p + 1, c]) / 2);
            colblue[k + bitmap.Height / 2, c] = (int)((double)(rowblue[p, c] - rowblue[p + 1, c]) / 2);
            k++;
        }
    }
    //Scale col
    for (int r = 0; r < bitmap.Height; r++)
    {
        for (int c = 0; c < bitmap.Width; c++)
        {
            if (r >= 0 && r < bitmap.Height / 2 && c >= 0 && c < bitmap.Width / 2)
            {
                scalered[r, c] = colred[r, c];
                scalegreen[r, c] = colgreen[r, c];
                scaleblue[r, c] = colblue[r, c];
            }
            else
            {
                scalered[r, c] = Math.Abs((colred[r, c] - 127));
                scalegreen[r, c] = Math.Abs((colgreen[r, c] - 127));
                scaleblue[r, c] = Math.Abs((colblue[r, c] - 127));
            }
        }
    }
    //Set LL = 0
    for (int r = 0; r < bitmap.Width / 2; r++)
    {
        for (int c = 0; c < bitmap.Height / 2; c++)
        {
            colred[r, c] = 0;
            colgreen[r, c] = 0;
            colblue[r, c] = 0;
        }
    }
    //Set LL = 0
    for (int r = 0; r < bitmap.Height; r++)
    {
        for (int c = 0; c < bitmap.Width; c++)
        {
            if (!(r >= 0 && r < bitmap.Height / 2 && c >= 0 && c < bitmap.Width / 2))
            {
                if (Math.Abs(colred[r, c]) <= m_threshold)
                {
                    colred[r, c] = 0;
                }
                else
                {
                    //colred[r, c] = 255;
                }
                if (Math.Abs(colgreen[r, c]) <= m_threshold)
                {
                    colgreen[r, c] = 0;
                }
                else
                {
                    //colgreen[r, c] = 255;
                }
                if (Math.Abs(colblue[r, c]) <= m_threshold)
                {
                    colblue[r, c] = 0;
                }
                else
                {
                    //colblue[r, c] = 255;
                }
            }
        }
    }
    //Inverse Transform columns
    for (int c = 0; c < bitmap.Width; c++)
    {
        int k = 0;
        for (int p = 0; p < bitmap.Height; p = p + 2)
        {
            recrowred[p, c] = (int)((colred[k, c] + colred[k + bitmap.Height / 2, c]));
            recrowred[p + 1, c] = (int)((colred[k, c] - colred[k + bitmap.Height / 2, c]));
            recrowgreen[p, c] = (int)((colgreen[k, c] + colgreen[k + bitmap.Height / 2, c]));
            recrowgreen[p + 1, c] = (int)((colgreen[k, c] - colgreen[k + bitmap.Height / 2, c]));
            recrowblue[p, c] = (int)((colblue[k, c] + colblue[k + bitmap.Height / 2, c]));
            recrowblue[p + 1, c] = (int)((colblue[k, c] - colblue[k + bitmap.Height / 2, c]));
            k++;
        }
    }

    //Invers Transform rows
    for (int r = 0; r < bitmap.Height; r++)
    {
        int k = 0;
        for (int p = 0; p < bitmap.Width; p = p + 2)
        {
            recorgred[r, p] = (int)((recrowred[r, k] + recrowred[r, k + (bitmap.Width / 2)]));
            recorgred[r, p + 1] = (int)((recrowred[r, k] - recrowred[r, k + (bitmap.Width / 2)]));
            recorggreen[r, p] = (int)((recrowgreen[r, k] + recrowgreen[r, k + (bitmap.Width / 2)]));
            recorggreen[r, p + 1] = (int)((recrowgreen[r, k] - recrowgreen[r, k + (bitmap.Width / 2)]));
            recorgblue[r, p] = (int)((recrowblue[r, k] + recrowblue[r, k + (bitmap.Width / 2)]));
            recorgblue[r, p + 1] = (int)((recrowblue[r, k] - recrowblue[r, k + (bitmap.Width / 2)]));
            k++;
        }
    }
    Bitmap imgPtr = new Bitmap(bmpSource);
   
  //  unsafe
    {
   
      //  byte[] imgPtr = new byte[bitmap.Height*bitmap.Width*4];
        int k = 0;
        for (int i = 0; i < bitmap.Height; i++)
        {
            for (int j = 0; j < bitmap.Width; j++)
            {
                if (function == 0)
                {
                    PixelColor pc=new PixelColor();
                    pc.Red =(byte) Math.Abs(recorgred[i, j] - 0);
                    pc.Green = (byte)Math.Abs(recorggreen[i, j] - 0);
                    pc.Blue = (byte)Math.Abs(recorgblue[i, j] - 0);
                    imgPtr.SetPixel(j, i, pc);
                }
                else
                {
                    PixelColor pc = new PixelColor();
                    pc.Red = (byte)scalered[i, j];
                    pc.Green = (byte)scalegreen[i, j];
                    pc.Blue= (byte)scaleblue[i, j];
                    imgPtr.SetPixel(j, i, pc);
                }
               
            }
           
        }
    }
    imgPtr.Finalize();
    return imgPtr.Image;
    //bitmap.UnlockBits(bitmapdata);
}

public static BitmapSource MedianFilter(BitmapImage srcBmp, int []Kernel)
{
   
    List<int> rd = new List<int>();
    List<int> gr = new List<int>();
    List<int> bl = new List<int>();
    List<int> alp = new List<int>();
           
    int xdir = Kernel[0];
    int ydir = Kernel[1];
    Bitmap bmp = new Bitmap(srcBmp);
    Bitmap median = new Bitmap(srcBmp);
    PixelColor c;
   
    for (int i = 0; i < bmp.NumRow; i++)
    {
        for (int j = 0; j < bmp.NumCol; j++)
        {
            rd = new List<int>();
             gr = new List<int>();
            bl = new List<int>();
            alp = new List<int>();
            int ind = 0;
            PixelColor pc=new PixelColor();
            for (int i1 = i-ydir; i1 <= i+ydir; i1++)
            {
                for (int j1 = j-xdir; j1 <= j+xdir; j1++)
                {
           //     
                    if((j1<bmp.NumCol) && (i1<bmp.NumRow) &&
                          (j1>=0)&&(i1>=0)&&(i1!=i)&&(j1!=j))
                    {
                            pc = median.GetPixel(j1, i1);
                            rd.Add(pc.Red);
                            gr.Add(pc.Green);
                            bl.Add(pc.Blue);
                            alp.Add(pc.Alpha);
                            ind++;
                   
                    }
             //       catch (Exception ex)
                    {
                    }
                }
            }
            if (rd.Count > 0)
            {
                int red = (int)GetMedian(rd.ToArray());
                int green = (int)GetMedian(gr.ToArray());
                int blue = (int)GetMedian(bl.ToArray());
                int alpha = (int)GetMedian(alp.ToArray());
                PixelColor pc2 = new PixelColor(red, green, blue, alpha);
                median.SetPixel(j, i, pc2);
               
            }
           
           
        }
    }
    median.Finalize();
    return median.Image;
}

public static BitmapSource ConvFilter(BitmapImage b, int [,]Kernel)
{
    Bitmap bmp = new Bitmap(b);
    Bitmap rslt = new Bitmap(b);
    int nRows = Kernel.GetUpperBound(0);
    int nCols = Kernel.GetUpperBound(1);
   
    double sumR = 0, sumG = 0, sumB = 0,sumAlpha=0;
    int weight = 0;
    int r = 0, c = 0;
    int tot = 0;
    string s = ""; 
    for (int i = nRows/2; i < bmp.NumRow-nRows/2; i++)
    {
        for (int j = nCols/2; j < bmp.NumCol-nCols/2; j++)
        {
            sumR = sumG = sumB = sumAlpha=0;
            r = 0;
            c = 0;
            PixelColor pc = bmp.GetPixel(j, i);
            for (int i1 = -nRows/2; i1 <=nRows/2 ; i1++)
            {
                for (int j1 = -nCols/2; j1 <=nCols/2; j1++)
                {
                    pc = bmp.GetPixel(j1+j, i1+i);
                    double red = (double)pc.Red;
                    sumR = sumR+red * (double)Kernel[r, c];
                    double green = (double)pc.Green;
                    double blue = pc.Blue;
                    sumG = sumG + green * (double)Kernel[r, c];
                    sumB = sumB + blue* (double)Kernel[r, c];
                    tot++;
                    c++;
                }
                r++;
                c = 0;
            }
            if (weight == 0)
            {
                weight = 1;
            }
            sumG = 0;
            sumB = 0;
            //sumR = sumR / (double)tot;
            if (sumR > 255)
            {
                sumR = 255;
            }
            if (sumR < 0)
            {
                sumR = 0;
            }
            if (sumG > 255)
            {
                sumG = 255;
            }
            if (sumG < 0)
            {
                sumG = 0;
            }
            if (sumB < 0)
            {
                sumB = 0;
            }
            if (sumB > 255)
            {
                sumB = 255;
            }
     
            pc.Red = (byte)(int)sumR;
            pc.Green = (byte)sumG;
            pc.Blue = (byte)sumB;
            rslt.SetPixel(j, i, pc);
        }
    }
 
    rslt.Finalize();
    return rslt.Image;
}

public static BitmapSource MeanShiftSegmentation(BitmapImage src, double ThresholdDistance,int radious)
{
    Bitmap rgb = new Bitmap(src);
    Bitmap hsv = new Bitmap(Bitmap.BitmapImageFromBitmapSource(ConvertImageFromRGB2HSV(src)));
   
    for (int i = 0; i < rgb.NumRow; i++)
    {
        for (int j = 0; j < rgb.NumCol; j++)
        {
            double tot=0;
            double valsH = 0;
            double valsS = 0;
            double valsB = 0;
            double valsR = 0;
            double valsG = 0;
            double valsBl = 0;
   
            for (int i1 = -radious; i1 < radious; i1++)
            {
                for (int j1 = -radious; j1 < radious; j1++)
                {
                    if (((i1 + i) >= 0) && ((i1 + i) < rgb.NumRow) &&
                             ((j1 + j) >= 0) && ((j1 + j) < rgb.NumCol))
                    {
                        PixelColor pcHSV = hsv.GetPixel(j1 + j, i1 + i);
                        valsH+=(double)(pcHSV.Red);
                        valsS += (double)(pcHSV.Green);
                        valsB+=(double)(pcHSV.Blue);
                        PixelColor pcRGB = rgb.GetPixel(j1 + j, i1 + i);
                        valsR += (double)(pcRGB.Red);
                        valsG += (double)(pcRGB.Green);
                        valsBl += (double)(pcRGB.Blue);
                        tot++;
                    }
                   
                }
            }
            double mH = valsH/tot;
            double mS =valsS/tot;
            double mV = valsB/tot;
            byte mR =(byte) (valsR/tot);
            byte mG = (byte)(valsG/tot);
            byte mB = (byte)(valsBl/tot);

            PixelColor pcv = hsv.GetPixel( j, i);
            PixelColor pcR = new PixelColor();
            double avgColor = (Math.Abs(pcv.Red - mH) +
              Math.Abs(pcv.Green - mS) + Math.Abs(pcv.Blue - mV)) / 3;
            if (avgColor < ThresholdDistance)
            {
                pcR = new PixelColor(mR, mG, mB, 255);
                rgb.SetPixel(j,  i, pcR);
            }
        }
    }
    rgb.Finalize();
    return rgb.Image;
}

public static BitmapSource MakeCollage(BitmapImage srcBmp,Bitmap[]allBmp,int BlockSizeRow,int BlockSizeCol)
{
    Bitmap Rslt = new Bitmap(srcBmp);// GRAY is the resultant matrix
    Bitmap src = new Bitmap(srcBmp);
    int NumRow = src.Height;
    int numCol = src.Width;
   
   
    Bitmap srcBlock = new Bitmap(BlockSizeRow, BlockSizeCol);
    for (int i = 0; i < NumRow - BlockSizeRow; i += BlockSizeRow)
    {
        for (int j = 0; j < numCol - BlockSizeCol; j += BlockSizeCol)
        {
            srcBlock = new Bitmap(BlockSizeRow, BlockSizeCol);
            ////1. Extract all the pixels in main image block
            for (int i1 = 0; i1 < (BlockSizeRow); i1++)
            {
                for (int j1 = 0; j1 < (BlockSizeCol); j1++)
                {
                    srcBlock.SetPixel(j1, i1, Rslt.GetPixel(j + j1, i + i1));
                    //      System.Threading.Thread.Sleep(15);
                }
            }
            srcBlock.Finalize();
            ////////// 2. Let us now compare this block with every image in database
            double dst = 999999999999999.0;
            int small = -1;
            for (int k = 0; k < allBmp.Length; k++)
            {
                double d = 0;
                for (int i1 = 0; i1 < BlockSizeRow; i1++)
                {
                    for (int j1 = 0; j1 < BlockSizeCol; j1++)
                    {
                        PixelColor c1 = srcBlock.GetPixel(j1, i1);
                        int rd1 = c1.Red;
                        int gr1 = c1.Green;
                        int bl = c1.Blue;

                        PixelColor c2 = allBmp[k].GetPixel(j1, i1);
                        int rd2 = c2.Red;
                        int gr2 = c2.Green;
                        int bl2 = c2.Blue;
                        d = d + Math.Abs(rd1 - rd2) + Math.Abs(gr1 - gr2) + Math.Abs(bl - bl2);
                    }
                }
                d = d / (double)(BlockSizeRow * BlockSizeCol);
                if (d < dst)
                {
                    dst = d;
                    small = k;
                }
            }
            for (int i1 = 0; i1 < BlockSizeRow; i1++)
            {
                for (int j1 = 0; j1 < BlockSizeCol; j1++)
                {
                    PixelColor c1 = allBmp[small].GetPixel(j1, i1);
                    try
                    {
                        Rslt.SetPixel(j1 + j, i1 + i, c1);
                    }
                    catch (Exception ex)
                    {
                    }

                }
            }
        }
        //timer1.Enabled = true;
    }
    Rslt.Finalize();
    return Rslt.Image;
}

public static Int32Rect TemplateMatch(BitmapImage mainImage, BitmapImage templateImage)
{
    Bitmap f=new Bitmap(mainImage);
    Bitmap t=new Bitmap(templateImage);
    int BlockSizeRow = t.NumRow;
    int BlockSizeCol = t.NumCol;
    int NumRow = f.NumRow;
    int numCol = f.NumCol;
   
    double dst = 0;
    int smallX = 0,smallY=0;
    double miuF = CalculateMean(f.GetImageAsList());
    double stdF = CalculateStdDev(f.GetImageAsList());
    double miuT = CalculateStdDev(t.GetImageAsList());
    double stdT = CalculateStdDev(t.GetImageAsList());
           
    for (int i = 0; i < NumRow - BlockSizeRow; i ++)
    {
        for (int j = 0; j < numCol - BlockSizeCol; j ++)
        {
            double sm = 0;
            for (int i1 = 0; i1 < (BlockSizeRow); i1++)
            {
                for (int j1 = 0; j1 < (BlockSizeCol); j1++)
                {
                    PixelColor fpc = f.GetPixel(j1 + j, i1 + i);
                    PixelColor tpc = t.GetPixel(j1, i1);
                    sm =sm+ ((double)fpc.Red - miuF) * ((double)tpc.Red - miuT) / (stdF * stdT);
                }
            }
            sm=sm/(double)(BlockSizeCol*BlockSizeRow);
            sm = Math.Abs(sm);
            if (sm > dst)
            {
                dst = sm;
           
                smallX = i;
                smallY = j;
            }
        }
    }
 
    return new Int32Rect(smallX, smallY, (int)templateImage.Width, (int)templateImage.Height);
}

No comments:

Post a Comment