No 52. 두 장의 픽셀 대비 bool

winfrom 버전 사진 비교
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace CaptureImages
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
        private void button2_Click(object sender, EventArgs e)
        {
            List<Point> po = getPoint(@"e:\cpImage\IMG_0001.jpg");
            //for (int i = 0; i < po.Count; i++)
            //{
            //    label1.Text += po[i].X+","+po[i].Y;
            //}
            label1.Text = po[0].X + "," + po[0].Y;
        }
        private void button1_Click(object sender, EventArgs e)
        {
            //Bitmap bt1 = ImageScal(@"e:\    .jpg", 150, 340, 1213, 526);
            //Bitmap bt2 = ImageScal(@"e:\    .jpg", 150, 340, 1221, 531);

            //Bitmap bt1 = ImageScal(@"e:\    .jpg", 50, 50, 1390, 940);

            Bitmap bt1 = ImageScal(@"e:\cpImage\IMG.jpg", 80, 80, 1428, 693);
            Bitmap bt2 = ImageScal(@"e:\cpImage\IMG_0001.jpg", 80, 80, 1500, 692);

            //Bitmap bt1 = ImageScal(@"e:\cpImage\IMG.jpg", 80, 80, 1290, 1263);
            //Bitmap bt2 = ImageScal(@"e:\cpImage\IMG_0001.jpg", 80, 80, 1362, 1262);

            //Bitmap bt1 = ImageScal(@"e:\    .jpg", 50, 50, 1394, 1832);
            //Bitmap bt2 = ImageScal(@"e:\    .jpg", 50, 50, 1397, 945);

            //Bitmap bt1 = ImageScal(@"e:\    .jpg", 50, 50, 1394, 1832);
            //Bitmap bt2 = ImageScal(@"e:\    .jpg", 50, 50, 1390, 945);
            List<Rectangle> rec = Compare(bt1, bt2, new Size(5, 5));

            if (rec.Count > 60)
            {
                label1.Text = "        ";
            }
            else
            {
                label1.Text = "   ";
            }

            pictureBox1.Image = bt1;
            pictureBox2.Image = bt2;
            // bool i = ImgComp(bt1, bt2);

        }

        //               

        private Bitmap ImageScal(string imagePath, int width, int height, int offsetX, int offsetY)
        {
            //      
            Bitmap originalImage = new Bitmap(imagePath);

            //      
            Bitmap newImage = new Bitmap(width, height);

            //      
            Graphics grp = Graphics.FromImage(newImage);

            //             
            grp.Clear(Color.Transparent);

            //  
            grp.DrawImage(originalImage, new Rectangle(0, 0, width, height),
              new Rectangle(offsetX, offsetY, width, height),
              GraphicsUnit.Pixel);
            originalImage.Dispose();
            grp.Dispose();

            #region         
            //if (newImage != null)
            //{

            //    Rectangle rect = new Rectangle(0, 0, width,height);
            //    System.Drawing.Imaging.BitmapData bmpData = newImage.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, newImage.PixelFormat);
            //    IntPtr ptr = bmpData.Scan0;
            //    int bytes = width * height * 3;
            //    byte[] rgbValues = new byte[bytes];
            //    System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
            //    double colorTemp = 0;
            //    for (int i = 0; i < rgbValues.Length; i += 3)
            //    {
            //        colorTemp = rgbValues[i + 2] * 0.299 + rgbValues[i + 1] * 0.587 + rgbValues[i] * 0.114;
            //        //rgbValues[i] = rgbValues[i + 1] = rgbValues[i + 2] = colorTemp>200?(byte)(255):(byte)0;
            //        rgbValues[i] = rgbValues[i + 1] = rgbValues[i + 2] =(byte)colorTemp;

            //    }
            //    System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
            //    newImage.UnlockBits(bmpData);
            //}
            #endregion

            //          
            return Imgbinaryzation(newImage);
        }
        /// <summary>
        ///      
        /// </summary>
        private Bitmap Imgbinaryzation(Bitmap newImage)
        {
            if (newImage != null)
            {
                int threshold = ousu(newImage);
                Color color = new Color();//      
                Color newColor = new Color();

                for (int i = 0; i < newImage.Width; i++)
                {
                    for (int j = 0; j <newImage.Height; j++)
                    {
                        color = newImage.GetPixel(i, j); //            
                        if (color.R > threshold) newColor = Color.White;
                        else newColor = Color.Black;
                        newImage.SetPixel(i, j, newColor);
                    }
                }
            }
            return newImage;
        }


        //      (             )
        private int ousu(Bitmap img)
        {
            int thresholdValue = 1;
            int[] ihist = new int[256];

            int i, j, k;
            int n, n1, n2, gmin, gmax;
            double m1, m2, sum, csum, fmax, sb;

            for (i = 0; i < 256; i++)
                ihist[i] = 0;

            gmin = 255; gmax = 0;

            for (i = 1; i < img.Width - 1; i++)
            {
                for (j = 1; j < img.Height - 1; j++)
                {
                    Color c = img.GetPixel(i, j);
                    int cn = ((c.G * 59 + c.R * 30 + c.B * 11) / 100);
                    ihist[cn]++;
                    //
                    if (cn > gmax) gmax = cn;
                    if (cn < gmin) gmin = cn;
                }
            }

            sum = csum = 0.0;
            n = 0;
            for (k = 0; k <= 255; k++)
            {
                sum += (double)k * (double)ihist[k];
                n += ihist[k];
            }

            if (n == 0)
            {
                return (60);
            }

            fmax = -1.0;
            n1 = 0;
            for (k = 0; k < 255; k++)
            {
                n1 += ihist[k];
                if (n1 == 0) { continue; }
                n2 = n - n1;
                if (n2 == 0) { break; }
                csum += (double)k * ihist[k];
                m1 = csum / n1;
                m2 = (sum - csum) / n2;
                sb = (double)n1 * (double)n2 * (m1 - m2) * (m1 - m2);
                /* bbg: note: can be optimized. */
                if (sb > fmax)
                {
                    fmax = sb;
                    thresholdValue = k;
                }
            }

            return thresholdValue;
        }


        #region          

        /// <summary>
        ///           
        /// </summary>
        /// <param name="actualImage">    </param>
        /// <param name="expectedImage">    </param>
        /// <returns>    ,           </returns>
        private bool ImgComp(Bitmap actualImage, Bitmap expectedImage)
        {


            //            
            int[] actualHisogram = GetHisogram(actualImage);
            int[] expectHisogram = GetHisogram(expectedImage);

            //             
            float result = GetFinalResult(actualHisogram, expectHisogram);

            //      1           
            return (result > 0.999);

            //                            ,            index          
        }

        private int[] GetHisogram(Bitmap bmpImg)
        {
            BitmapData data = bmpImg.LockBits(new System.Drawing.Rectangle(0, 0, bmpImg.Width, bmpImg.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            int[] histogram = new int[256];

            unsafe
            {
                byte* ptr = (byte*)data.Scan0;
                int remain = data.Stride - data.Width * 3;
                for (int i = 0; i < histogram.Length; i++)
                    histogram[i] = 0;
                for (int i = 0; i < data.Height; i++)
                {
                    for (int j = 0; j < data.Width; j++)
                    {
                        int mean = ptr[0] + ptr[1] + ptr[2];
                        mean /= 3;
                        histogram[mean]++;
                        ptr += 3;
                    }
                    ptr += remain;
                }
            }
            bmpImg.UnlockBits(data);
            return histogram;


        }
        /// <summary>
        ///            
        /// </summary>
        /// <param name="actualHisogram">        </param>
        /// <param name="expectedHisogram">        </param>
        /// <returns>         </returns>
        private float GetFinalResult(int[] actualHisogram, int[] expectedHisogram)
        {
            if (actualHisogram.Length != expectedHisogram.Length)
            {
                return 0;
            }
            float result = 0;
            int j = actualHisogram.Length;
            for (int i = 0; i < j; i++)
            {
                result += 1 - GetAbs(actualHisogram[i], expectedHisogram[i]);
            }
            return result / j;
        }
        /// <summary>
        ///                       
        /// </summary>
        /// <param name="firstNum">   </param>
        /// <param name="secondNum">  </param>
        /// <returns>    </returns>
        private float GetAbs(int firstNum, int secondNum)
        {
            int abs = Math.Abs(firstNum - secondNum);
            int maxNum = Math.Max(firstNum, secondNum);
            return (float)abs / ((maxNum == 0) ? 1 : maxNum);
        }


        #endregion

        #region             

        //  /// <summary>
        /////     
        ///// </summary>
        [StructLayout(LayoutKind.Explicit)]
        private struct ICColor
        {
            [FieldOffset(0)]
            public byte B;
            [FieldOffset(1)]
            public byte G;
            [FieldOffset(2)]
            public byte R;
        }

      

        //      
        //</summary>
        //<param name="bmp1"></param>
        //<param name="bmp2"></param>
        //<param name="block"></param>
        //<returns></returns>
        public static List<Rectangle> Compare(Bitmap bmp1, Bitmap bmp2, Size block)
        {
            List<Rectangle> rects = new List<Rectangle>();
            PixelFormat pf = PixelFormat.Format24bppRgb;

            BitmapData bd1 = bmp1.LockBits(new Rectangle(0, 0, bmp1.Width, bmp1.Height), ImageLockMode.ReadOnly, pf);
            BitmapData bd2 = bmp2.LockBits(new Rectangle(0, 0, bmp2.Width, bmp2.Height), ImageLockMode.ReadOnly, pf);

            try
            {
                unsafe
                {
                    int w = 0, h = 0;

                    while (h < bd1.Height && h < bd2.Height)
                    {
                        byte* p1 = (byte*)bd1.Scan0 + h * bd1.Stride;
                        byte* p2 = (byte*)bd2.Scan0 + h * bd2.Stride;

                        w = 0;
                        while (w < bd1.Width && w < bd2.Width)
                        {
                            //        
                            for (int i = 0; i < block.Width; i++)
                            {
                                int wi = w + i;
                                if (wi >= bd1.Width || wi >= bd2.Width) break;

                                for (int j = 0; j < block.Height; j++)
                                {
                                    int hj = h + j;
                                    if (hj >= bd1.Height || hj >= bd2.Height) break;

                                    ICColor* pc1 = (ICColor*)(p1 + wi * 3 + bd1.Stride * j);
                                    ICColor* pc2 = (ICColor*)(p2 + wi * 3 + bd2.Stride * j);

                                    if (pc1->R != pc2->R || pc1->G != pc2->G || pc1->B != pc2->B)
                                    {
                                        //                .      .

                                        int bw = Math.Min(block.Width, bd1.Width - w);
                                        int bh = Math.Min(block.Height, bd1.Height - h);
                                        rects.Add(new Rectangle(w, h, bw, bh));

                                        goto E;
                                    }
                                }
                            }
                        E:
                            w += block.Width;
                        }

                        h += block.Height;
                    }
                }
            }
            finally
            {
                bmp1.UnlockBits(bd1);
                bmp2.UnlockBits(bd2);
            }

            return rects;
        }
        #endregion
        /// <summary>
        ///           ,     
        /// </summary>
        /// <returns></returns>
        private List<Point> getPoint(string imgPath)
        {
            List<Point> lispo = new List<Point>();
           
            int count = 0;
            Color co = new Color();
            Bitmap bt1 = new Bitmap(imgPath);
            for (int i = 230; i < bt1.Height; i++)
            {
               count=0;
                for (int j = 220; j < bt1.Width; j++)
                {
                    co = bt1.GetPixel(j,i);
                    if (co.R < 250 || co.G < 250 || co.B < 250)
                    {
                        count++;
                        if (count > 5)
                        {
                            return lispo;                        
                        }
                        Point po = new Point(j,i);
                        lispo.Add(po);
                    }                
                }
            }
            return lispo;          
        }
    }
}



 
asp.net 버전 사진 비교
/// <summary>
        ///         
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnShowPoint_Click(object sender, EventArgs e)
        {
            List<Point> po = getPoint(@"e:\cpImage\01.jpg");
            label1.Text = po[0].X + "," + po[0].Y;
        }
        /// <summary>
        ///           ,     
        /// </summary>
        /// <returns></returns>
        private List<Point> getPoint(string imgPath)
        {
            List<Point> lispo = new List<Point>();

            int count = 0;
            Color co = new Color();
            Bitmap bt1 = new Bitmap(imgPath);
            for (int i = 230; i < bt1.Height; i++)
            {
                count = 0;
                for (int j = 0; j < bt1.Width; j++)
                {
                    co = bt1.GetPixel(j, i);
                    if (co.R < 0 || co.G < 250 || co.B < 250)
                    {
                        count++;
                        if (count > 5)
                        {
                            return lispo;
                        }
                        Point po = new Point(j, i);
                        lispo.Add(po);
                    }
                }
            }
            return lispo;
        }

        /// <summary>
        ///       
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnShowImg_Click(object sender, EventArgs e)
        {
            DataTable dt = enterGrade.GetPaperPositions();
            if (dt!=null && dt.Rows.Count>0)
            {
                //             
                List<Point> po = getPoint(@"e:\cpImage\IMG_0001.jpg");
                //               
                string[] Code = dt.Rows[0]["CodePos"].ToString().Split(',');
                //x       
                int codeX = Convert.ToInt32(po[0].X) - Convert.ToInt32(Code[0]);
                //y       
                int codeY = Convert.ToInt32(po[0].Y) - Convert.ToInt32(Code[1]);

                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    //   td      
                    int Interval = Convert.ToInt32(dt.Rows[i]["CP_Interval"].ToString());
                    //    
                    string PositionGuid = dt.Rows[i]["PositionGuid"].ToString();
                    //      
                    int cutLen = Convert.ToInt32(dt.Rows[0]["CPTDwh"].ToString());
                    //           
                    string[] goodPos = dt.Rows[i]["CP_GoodPos"].ToString().Split(',');
                    //   x   
                    int sqlGoodX = Convert.ToInt32(goodPos[0]);
                    //   y   
                    int sqlGoodY = Convert.ToInt32(goodPos[1]);
                    int goodX = sqlGoodX + codeX;
                    int goodY = sqlGoodY + codeY;

                    for (int j = 1; j <= 4; j++)
                    {
                        Bitmap bt1 = ImageScal(@"e:\cpImage\IMG.jpg", cutLen, cutLen, sqlGoodX, sqlGoodY);
                        Bitmap bt2 = ImageScal(@"e:\cpImage\IMG_0001.jpg", cutLen, cutLen, goodX, goodY);
                        List<Rectangle> rec = Compare(bt1, bt2, new Size(5, 5));

                        if (rec.Count > 56)
                        {
                            //      
                            enterGrade.ModifyGetScore(PositionGuid,j+"");
                            j = 5;
                        }
                        else
                        {
                            sqlGoodX += 138;
                            //sqlGoodY += 190;
                            goodX += 138;
                            //goodY += 190;
                        }
                    }
                }
            }
        }
        //               
        private Bitmap ImageScal(string imagePath, int width, int height, int offsetX, int offsetY)
        {
            //      
            Bitmap originalImage = new Bitmap(imagePath);

            //      
            Bitmap newImage =new Bitmap(width, height);

            //      
            Graphics grp = Graphics.FromImage(newImage);

            //             
            grp.Clear(Color.Transparent);

            //  
            grp.DrawImage(originalImage, new Rectangle(0, 0, width, height),
              new Rectangle(offsetX, offsetY, width, height),
              GraphicsUnit.Pixel);
            originalImage.Dispose();
            grp.Dispose();
            //          
            return Imgbinaryzation(newImage);
        }
        /// <summary>
        ///      
        /// </summary>
        private Bitmap Imgbinaryzation(Bitmap newImage)
        {
            if (newImage != null)
            {
                int threshold = ousu(newImage);
                Color color = new Color();//      
                Color newColor = new Color();

                for (int i = 0; i < newImage.Width; i++)
                {
                    for (int j = 0; j < newImage.Height; j++)
                    {
                        color = newImage.GetPixel(i, j); //            
                        if (color.R > threshold) newColor = Color.White;
                        else newColor = Color.Black;
                        newImage.SetPixel(i, j, newColor);
                    }
                }
            }
            return newImage;
        }


        //      (             )
        private int ousu(Bitmap img)
        {
            int thresholdValue = 1;
            int[] ihist = new int[256];

            int i, j, k;
            int n, n1, n2, gmin, gmax;
            double m1, m2, sum, csum, fmax, sb;

            for (i = 0; i < 256; i++)
                ihist[i] = 0;

            gmin = 255; gmax = 0;

            for (i = 1; i < img.Width - 1; i++)
            {
                for (j = 1; j < img.Height - 1; j++)
                {
                    Color c = img.GetPixel(i, j);
                    int cn = ((c.G * 59 + c.R * 30 + c.B * 11) / 100);
                    ihist[cn]++;
                    //
                    if (cn > gmax) gmax = cn;
                    if (cn < gmin) gmin = cn;
                }
            }

            sum = csum = 0.0;
            n = 0;
            for (k = 0; k <= 255; k++)
            {
                sum += (double)k * (double)ihist[k];
                n += ihist[k];
            }

            if (n == 0)
            {
                return (60);
            }

            fmax = -1.0;
            n1 = 0;
            for (k = 0; k < 255; k++)
            {
                n1 += ihist[k];
                if (n1 == 0) { continue; }
                n2 = n - n1;
                if (n2 == 0) { break; }
                csum += (double)k * ihist[k];
                m1 = csum / n1;
                m2 = (sum - csum) / n2;
                sb = (double)n1 * (double)n2 * (m1 - m2) * (m1 - m2);
                /* bbg: note: can be optimized. */
                if (sb > fmax)
                {
                    fmax = sb;
                    thresholdValue = k;
                }
            }

            return thresholdValue;
        }
        
        #region          
        /// <summary>
        ///           
        /// </summary>
        /// <param name="actualImage">    </param>
        /// <param name="expectedImage">    </param>
        /// <returns>    ,           </returns>
        private bool ImgComp(Bitmap actualImage, Bitmap expectedImage)
        {
            //            
            int[] actualHisogram = GetHisogram(actualImage);
            int[] expectHisogram = GetHisogram(expectedImage);

            //             
            float result = GetFinalResult(actualHisogram, expectHisogram);

            //      1           
            return (result > 0.999);
            //                            ,            index          
        }

        private int[] GetHisogram(Bitmap bmpImg)
        {
            BitmapData data = bmpImg.LockBits(new System.Drawing.Rectangle(0, 0, bmpImg.Width, bmpImg.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            int[] histogram = new int[256];

            unsafe
            {
                byte* ptr = (byte*)data.Scan0;
                int remain = data.Stride - data.Width * 3;
                for (int i = 0; i < histogram.Length; i++)
                    histogram[i] = 0;
                for (int i = 0; i < data.Height; i++)
                {
                    for (int j = 0; j < data.Width; j++)
                    {
                        int mean = ptr[0] + ptr[1] + ptr[2];
                        mean /= 3;
                        histogram[mean]++;
                        ptr += 3;
                    }
                    ptr += remain;
                }
            }
            bmpImg.UnlockBits(data);
            return histogram;            
        }
        /// <summary>
        ///            
        /// </summary>
        /// <param name="actualHisogram">        </param>
        /// <param name="expectedHisogram">        </param>
        /// <returns>         </returns>
        private float GetFinalResult(int[] actualHisogram, int[] expectedHisogram)
        {
            if (actualHisogram.Length != expectedHisogram.Length)
            {
                return 0;
            }
            float result = 0;
            int j = actualHisogram.Length;
            for (int i = 0; i < j; i++)
            {
                result += 1 - GetAbs(actualHisogram[i], expectedHisogram[i]);
            }
            return result / j;
        }
        /// <summary>
        ///                       
        /// </summary>
        /// <param name="firstNum">   </param>
        /// <param name="secondNum">  </param>
        /// <returns>    </returns>
        private float GetAbs(int firstNum, int secondNum)
        {
            int abs = Math.Abs(firstNum - secondNum);
            int maxNum = Math.Max(firstNum, secondNum);
            return (float)abs / ((maxNum == 0) ? 1 : maxNum);
        }


        #endregion

        #region             

        //  /// <summary>
        /////     
        ///// </summary>
        [StructLayout(LayoutKind.Explicit)]
        private struct ICColor
        {
            [FieldOffset(0)]
            public byte B;
            [FieldOffset(1)]
            public byte G;
            [FieldOffset(2)]
            public byte R;
        }
        
        /// <summary>
        /// //      
        /// </summary>
        /// <param name="bmp1"></param>
        /// <param name="bmp2"></param>
        /// <param name="block"></param>
        /// <returns></returns>
        public static List<Rectangle> Compare(Bitmap bmp1, Bitmap bmp2, Size block)
        {
            List<Rectangle> rects = new List<Rectangle>();
            PixelFormat pf = PixelFormat.Format24bppRgb;

            BitmapData bd1 = bmp1.LockBits(new Rectangle(0, 0, bmp1.Width, bmp1.Height), ImageLockMode.ReadOnly, pf);
            BitmapData bd2 = bmp2.LockBits(new Rectangle(0, 0, bmp2.Width, bmp2.Height), ImageLockMode.ReadOnly, pf);

            try
            {
                unsafe
                {
                    int w = 0, h = 0;

                    while (h < bd1.Height && h < bd2.Height)
                    {
                        byte* p1 = (byte*)bd1.Scan0 + h * bd1.Stride;
                        byte* p2 = (byte*)bd2.Scan0 + h * bd2.Stride;

                        w = 0;
                        while (w < bd1.Width && w < bd2.Width)
                        {
                            //        
                            for (int i = 0; i < block.Width; i++)
                            {
                                int wi = w + i;
                                if (wi >= bd1.Width || wi >= bd2.Width) break;

                                for (int j = 0; j < block.Height; j++)
                                {
                                    int hj = h + j;
                                    if (hj >= bd1.Height || hj >= bd2.Height) break;

                                    ICColor* pc1 = (ICColor*)(p1 + wi * 3 + bd1.Stride * j);
                                    ICColor* pc2 = (ICColor*)(p2 + wi * 3 + bd2.Stride * j);

                                    if (pc1->R != pc2->R || pc1->G != pc2->G || pc1->B != pc2->B)
                                    {
                                        //                .      .
                                        int bw = Math.Min(block.Width, bd1.Width - w);
                                        int bh = Math.Min(block.Height, bd1.Height - h);
                                        rects.Add(new Rectangle(w, h, bw, bh));

                                        goto E;
                                    }
                                }
                            }
                        E:
                            w += block.Width;
                        }

                        h += block.Height;
                    }
                }
            }
            finally
            {
                bmp1.UnlockBits(bd1);
                bmp2.UnlockBits(bd2);
            }
            return rects;
        }

좋은 웹페이지 즐겨찾기