프로젝트

일반

사용자정보

개정판 8f7f8073

ID8f7f807346b648d438257e50f6f0942a0a3a9279
상위 c3a5e283
하위 ce5a1268

김태성이(가) 4년 이상 전에 추가함

ImageCompare 수정

Change-Id: I56dc7931d809dda4227afea10baf5536c70174b8

차이점 보기:

ImageComparer/ComparerTestWPF/ComparerTestWPF.csproj
131 131
      <Install>false</Install>
132 132
    </BootstrapperPackage>
133 133
  </ItemGroup>
134
  <ItemGroup>
135
    <ProjectReference Include="..\Markus.ImageComparer\Markus.Image.csproj">
136
      <Project>{b3b05ced-f4eb-4f9d-b458-12fcbe48d546}</Project>
137
      <Name>Markus.Image</Name>
138
    </ProjectReference>
139
  </ItemGroup>
140 134
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
141 135
</Project>
ImageComparer/Markus.ImageComparer/EMGUCV_Extension.cs
1
using Emgu.CV;
2
using System;
3
using System.Collections.Generic;
4
using System.Linq;
5
using System.Text;
6
using System.Threading.Tasks;
7

  
8
namespace Markus.Image
9
{
10
    public class EmguCVImage
11
    {
12
        public static void test()
13
        {
14

  
15
        }
16
    }
17
}
ImageComparer/Markus.ImageComparer/ImageCompare.cs
1
using System;
2
using System.Collections.Generic;
3
using System.Drawing;
4
using System.Drawing.Imaging;
5
using System.Linq;
6
using System.Text;
7
using System.Threading.Tasks;
8

  
9
namespace Markus.Image
10
{
11
    public class ImageCompare : ImageCompareBase
12
    {
13
        /// <summary>
14
        /// 이미지를 비교 후 원본 이미지에 Rect를 그린다.
15
        /// </summary>
16
        /// <param name="Originalbitmap">원본 이미지</param>
17
        /// <param name="TargatBitmap">비교대상 이미지</param>
18
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
19
        /// <returns></returns>
20
        public Bitmap CompareDrawRects(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize)
21
        {
22
            var rects =  CompareReturnRects(Originalbitmap, TargatBitmap, ResultRectSize);
23

  
24
            if (rects.Count != 0)
25
            {
26
                using (Graphics g = Graphics.FromImage(Originalbitmap))
27
                {
28
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height)).ToList();
29

  
30
                    g.DrawRectangles(new Pen(Brushes.Red, 5f), rect.ToArray());
31
                    g.Save();
32

  
33
                    g.Dispose();
34
                }
35
            }
36

  
37
            return Originalbitmap;
38
        }
39

  
40
        public System.Windows.Media.Imaging.BitmapSource CompareDrawRects(System.Windows.Media.Imaging.BitmapSource Originalbitmap, System.Windows.Media.Imaging.BitmapSource TargatBitmap, Size ResultRectSize)
41
        {
42
            var _Originalbitmap = CreateBitmapFromSource(Originalbitmap);
43
            var _TargatBitmap = CreateBitmapFromSource(TargatBitmap);
44

  
45
            var rects = CompareReturnRects(_Originalbitmap, _TargatBitmap, ResultRectSize);
46
         
47
            if (rects.Count != 0)
48
            {
49
                using (Graphics g = Graphics.FromImage(_Originalbitmap))
50
                {
51
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height));
52

  
53
                    g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray());
54
                    g.Save();
55

  
56
                    g.Dispose();
57
                }
58
            }
59

  
60
            return CreateBitmapSourceFromBitmap(_Originalbitmap);
61
        }
62

  
63
        public List<System.Windows.Rect> CompareReturnRects(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize)
64
        {
65
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
66

  
67
            Bitmap Originalbitmap = null;
68
            Bitmap TargatBitmap = null;
69

  
70
            try
71
            {
72
                Originalbitmap = LoadPicture(OriginalbitmapUri);
73
                TargatBitmap = LoadPicture(TargatBitmapUri);
74

  
75
                result = CompareReturnRects(Originalbitmap, TargatBitmap, ResultRectSize);
76
            }
77
            catch (Exception)
78
            {
79
                throw;
80
            }
81
            finally
82
            {
83
                Originalbitmap.Dispose();
84
                TargatBitmap.Dispose();
85
            }
86

  
87
            return result;
88
        }
89

  
90
        /// <summary>
91
        /// 이미지를 비교 후 해당 영역을 Rect로 반환한다.
92
        /// </summary>
93
        /// <param name="Originalbitmap">원본 이미지</param>
94
        /// <param name="TargatBitmap">비교대상 이미지</param>
95
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
96
        /// <returns></returns>
97
        public List<System.Windows.Rect> CompareReturnRects(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize)
98
        {
99
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
100

  
101
            try
102
            {
103
                List<System.Windows.Rect> rects = new List<System.Windows.Rect>();
104

  
105
                var data = MathchesImageData(Originalbitmap, TargatBitmap);
106

  
107
                result =  GetMatchPixels(data, ResultRectSize);
108

  
109
                //if (rects.Count() > 0)
110
                //{
111
                //    result = Merge(rects, ResultRectSize.Height);
112
                //}
113

  
114
                //result = JoinRectList(rects);
115
            }
116
            catch (Exception ex)
117
            {
118
                throw ex;
119
            }
120
            finally
121
            {
122

  
123
            }
124

  
125
            return result;
126
        }
127

  
128
        /// <summary>
129
        /// 이미지를 비교 후 원본 이미지에 Rect를 그린다.
130
        /// 메모리 문제 발생
131
        /// </summary>
132
        /// <param name="Originalbitmap">원본 이미지</param>
133
        /// <param name="TargatBitmap">비교대상 이미지</param>
134
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
135
        /// <returns></returns>
136
        public async Task<Bitmap> CompareDrawRectsAsync(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize)
137
        {
138
            System.Drawing.Bitmap cloneOriginal = Originalbitmap;
139

  
140
            var rects = await CompareReturnRectsAsync(cloneOriginal, TargatBitmap, ResultRectSize);
141

  
142
            if (rects.Count != 0)
143
            {
144
                using (Graphics g = Graphics.FromImage(cloneOriginal))
145
                {
146
               
147
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height));
148

  
149
                    g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray());
150
                    g.Save();
151

  
152
                    g.Dispose();
153
                }
154
            }
155

  
156
            return cloneOriginal;
157
        }
158

  
159
        /// <summary>
160
        /// 이미지를 비교 후 원본 이미지에 Rect를 그린다.
161
        /// 메모리 문제 발생
162
        /// </summary>
163
        /// <param name="Originalbitmap">원본 이미지</param>
164
        /// <param name="TargatBitmap">비교대상 이미지</param>
165
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
166
        /// <returns></returns>
167
        public async Task<System.Windows.Media.Imaging.BitmapSource> CompareDrawRectsAsync(System.Windows.Media.Imaging.BitmapSource Originalbitmap, System.Windows.Media.Imaging.BitmapSource TargatBitmap, Size ResultRectSize)
168
        {
169

  
170
            var _Originalbitmap = CreateBitmapFromSource(Originalbitmap);
171
            var _TargatBitmap = CreateBitmapFromSource(TargatBitmap);
172

  
173
            var rects = await CompareReturnRectsAsync(_Originalbitmap, _TargatBitmap, ResultRectSize);
174

  
175
            if (rects.Count != 0)
176
            {
177
                using (Graphics g = Graphics.FromImage(_Originalbitmap))
178
                {
179
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height));
180

  
181
                    g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray());
182
                    g.Save();
183

  
184
                    g.Dispose();
185
                }
186
            }
187

  
188
            return CreateBitmapSourceFromBitmap(_Originalbitmap);
189
        }
190

  
191
        public Bitmap CreateBitmapFromSource(System.Windows.Media.Imaging.BitmapSource bitmapsource)
192
        {
193
            //convert image format
194
            var src = new System.Windows.Media.Imaging.FormatConvertedBitmap();
195
            src.BeginInit();
196
            src.Source = bitmapsource;
197
            src.DestinationFormat = System.Windows.Media.PixelFormats.Bgr24;
198
            src.EndInit();
199

  
200
            //copy to bitmap
201
            Bitmap bitmap = new Bitmap(src.PixelWidth, src.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
202
            var data = bitmap.LockBits(new Rectangle(Point.Empty, bitmap.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
203
            src.CopyPixels(System.Windows.Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
204
            bitmap.UnlockBits(data);
205

  
206
            return bitmap;
207
        }
208

  
209
        /// <summary>
210
        /// 메모리 문제 발생
211
        /// </summary>
212
        /// <param name="bitmap"></param>
213
        /// <returns></returns>
214
        public System.Windows.Media.Imaging.WriteableBitmap CreateWriteableBitmapFromBitmap(Bitmap bitmap)
215
        {
216
            System.Windows.Media.Imaging.WriteableBitmap result = null;
217

  
218
            if (bitmap == null)
219
                throw new ArgumentNullException("bitmap");
220

  
221
            try
222
            {
223
                int bytesPerPixel = 4;
224

  
225
                result = new System.Windows.Media.Imaging.WriteableBitmap(bitmap.Width, bitmap.Height,
226
                                                                   bitmap.HorizontalResolution ,bitmap.VerticalResolution,
227
                                                                   bitmap.PixelFormat.Convert(), null);
228

  
229
                Rectangle colorBitmapRectangle = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
230
                System.Windows.Int32Rect colorBitmapInt32Rect = new System.Windows.Int32Rect(0, 0, bitmap.Width, bitmap.Height);
231

  
232
                BitmapData data = bitmap.LockBits(colorBitmapRectangle, ImageLockMode.WriteOnly, bitmap.PixelFormat);
233

  
234
                result.WritePixels(colorBitmapInt32Rect, data.Scan0, data.Width * data.Height * bytesPerPixel, data.Stride);
235

  
236
                bitmap.UnlockBits(data);
237
            }
238
            catch (Exception ex)
239
            {
240
                //throw ex;
241
            }
242
            finally
243
            {
244
                bitmap.Dispose();
245
                bitmap = null;
246
                //GC.Collect(2);
247
            }
248

  
249
            return result;
250
        }
251
    
252
        /// <summary>
253
        /// 메모리 문제 발생
254
        /// </summary>
255
        /// <param name="bitmap"></param>
256
        /// <returns></returns>
257
        public System.Windows.Media.Imaging.BitmapSource CreateBitmapSourceFromBitmap(Bitmap bitmap)
258
        {
259
            System.Windows.Media.Imaging.BitmapSource result = null;
260
            
261
            if (bitmap == null)
262
                throw new ArgumentNullException("bitmap");
263

  
264
            try
265
            {
266
                using (var hbitmap = new SafeHBitmapHandle(bitmap.GetHbitmap(), true))
267
                {
268

  
269
                    result = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
270
                        hbitmap.DangerousGetHandle(),
271
                        IntPtr.Zero,
272
                        System.Windows.Int32Rect.Empty,
273
                        System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
274

  
275
                   
276
                }
277
            }
278
            catch (Exception ex)
279
            {
280
                //throw ex;
281
            }
282
            finally
283
            {
284
                bitmap.Dispose();
285
                bitmap = null;
286
                //GC.Collect(2);
287
            }
288

  
289
            return result;
290
        }
291

  
292
        public async Task<List<System.Windows.Rect>> CompareReturnRectsAsync(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize)
293
        {
294
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
295

  
296
            Bitmap Originalbitmap = null;
297
            Bitmap TargatBitmap = null;
298

  
299
            try
300
            {
301

  
302
                Originalbitmap = LoadPicture(OriginalbitmapUri);
303
                TargatBitmap = LoadPicture(TargatBitmapUri);
304

  
305
                result = await CompareReturnRectsAsync(Originalbitmap, TargatBitmap, ResultRectSize);
306
            }
307
            catch (Exception)
308
            {
309
                throw;
310
            }
311
            finally
312
            {
313
                Originalbitmap.Dispose();
314
                TargatBitmap.Dispose();
315
            }
316

  
317
            return result;
318
        }
319

  
320
        public async Task<System.Windows.Media.Imaging.BitmapSource> CompareDrawRectsAsync(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize)
321
        {
322
            System.Windows.Media.Imaging.BitmapSource result = null;
323

  
324
            Bitmap Originalbitmap = null;
325
            Bitmap TargatBitmap = null;
326

  
327
            try
328
            {
329

  
330
                Originalbitmap = LoadPicture(OriginalbitmapUri);
331
                TargatBitmap = LoadPicture(TargatBitmapUri);
332

  
333
                var bitmap = await CompareDrawRectsAsync(Originalbitmap, TargatBitmap, ResultRectSize);
334

  
335
                result = CreateBitmapSourceFromBitmap(bitmap);
336
            }
337
            catch (Exception)
338
            {
339
                throw;
340
            }
341
            finally
342
            {
343
                Originalbitmap.Dispose();
344
                TargatBitmap.Dispose();
345
            }
346

  
347
            return result;
348
        }
349

  
350
        /// <summary>
351
        /// 이미지를 비교 후 해당 영역을 Rect로 반환한다.
352
        /// </summary>
353
        /// <param name="Originalbitmap">원본 이미지</param>
354
        /// <param name="TargatBitmap">비교대상 이미지</param>
355
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
356
        /// <returns></returns>
357
        public async Task<List<System.Windows.Rect>> CompareReturnRectsAsync(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize)
358
        {
359
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
360

  
361
            try
362
            {
363
                var data = MathchesImageData(Originalbitmap, TargatBitmap);
364

  
365
                result = await GetMatchPixelsAsnc(data, ResultRectSize);
366

  
367
                //result = JoinRectList(result);
368
                //if (result.Count() > 0)
369
                //{
370
                //    result = Merge(result, ResultRectSize.Height);
371
                //}
372

  
373
                data = null;
374
            }
375
            catch (Exception ex)
376
            {
377
                throw ex;
378
            }
379
            finally
380
            {
381
            }
382

  
383
            return result;
384
        }
385

  
386
       
387
        protected override void Dispose(bool disposing)
388
        {
389
            base.Dispose(disposing);
390
        }
391
    }
392
}
ImageComparer/Markus.ImageComparer/ImageCompareBase.cs
1
using OpenCvSharp;
2
using System;
3
using System.Collections.Generic;
4
using System.Drawing;
5
using System.Drawing.Imaging;
6
using System.IO;
7
using System.Linq;
8
using System.Net;
9
using System.Runtime.InteropServices;
10
using System.Text;
11
using System.Threading.Tasks;
12
using Point = System.Drawing.Point;
13
using Size = System.Drawing.Size;
14

  
15
namespace Markus.Image
16
{
17
    public class ImageCompareBase : IDisposable
18
    {
19
        Mat OriginalImageData = null;
20
        Mat TargatImageData = null;
21

  
22
        double contoursLongCount = 0;
23
        double ComparisonCount = 0;
24
        public CompareProgress Progress = new CompareProgress();
25

  
26
        private void SetStatus(string message,double percentage,CompareStatus status)
27
        {
28
            System.Diagnostics.Debug.WriteLine(percentage);
29

  
30
            Progress.Message = message;
31
            Progress.Percentage = percentage;
32
            Progress.Status = status;
33
        }
34

  
35
        /// <summary>
36
        /// Originalbitmap에서 TargatBitmap과 비교하여 틀린 부분의 데이터를 Emgu.CV.TDepth형식으로 반환한다.
37
        /// </summary>
38
        /// <param name="Originalbitmap">원본 이미지</param>
39
        /// <param name="TargatBitmap">비교대상 이미지</param>
40
        /// <returns>Emgu.CV.TDepth형식의 byte[,,]</returns>
41
        protected Mat MathchesImageData(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap)
42
        {
43
            Mat result = new Mat();
44

  
45
            try
46
            {
47
                SetStatus("Image Load", 0, CompareStatus.Loading);
48

  
49
                Originalbitmap = ChangeBitmapFormatAndSize(Originalbitmap, Originalbitmap.Size, PixelFormat.Format24bppRgb);
50
                TargatBitmap = ChangeBitmapFormatAndSize(TargatBitmap, Originalbitmap.Size, PixelFormat.Format24bppRgb);
51

  
52
                // 원본이미지의 크키와 Format24bppRgb로 타켓 이미지를 변경
53
                // 크기가 틀린 경우 비교시 바이트배열 오류 발생
54
                OriginalImageData = OpenCvSharp.Extensions.BitmapConverter.ToMat(Originalbitmap);
55
                TargatImageData = OpenCvSharp.Extensions.BitmapConverter.ToMat(TargatBitmap);
56

  
57
                if (OriginalImageData.Size() != TargatImageData.Size())
58
                {
59
                    Cv2.Resize(TargatImageData, TargatImageData, OriginalImageData.Size());
60
                }
61
                
62
                Cv2.CvtColor(OriginalImageData, OriginalImageData, ColorConversionCodes.BGR2GRAY);
63
                Cv2.CvtColor(TargatImageData, TargatImageData, ColorConversionCodes.BGR2GRAY);
64

  
65
                Mat outputData = new Mat(TargatImageData.Size(), MatType.CV_8UC1);
66

  
67
                Cv2.Absdiff(OriginalImageData, TargatImageData, outputData);
68

  
69
                // 틀린부분을 반환
70
                Cv2.BitwiseNot(outputData, result);
71
            }
72
            catch (Exception ex)
73
            {
74
                throw ex;
75
            }
76
            finally
77
            {
78
            }
79
            
80
            return result;
81
        }
82

  
83
        protected System.Drawing.Bitmap ChangeBitmapFormatAndSize(System.Drawing.Bitmap bitmap, Size newSize, PixelFormat pixelFormat)
84
        {
85
            Bitmap result = bitmap;
86

  
87
            if (pixelFormat != bitmap.PixelFormat)
88
            {
89
                Point originPoint = new Point(0, 0);
90
                Rectangle rect = new Rectangle(originPoint, bitmap.Size);
91
                result = bitmap.Clone(rect, pixelFormat);
92
            }
93

  
94
            if (bitmap.Size != newSize)
95
            {
96
                result = new Bitmap(newSize.Width, newSize.Height);
97

  
98
                using (Graphics g = Graphics.FromImage(result))
99
                {
100
                    g.DrawImage(bitmap, 0, 0, newSize.Width, newSize.Height);
101
                    g.Dispose();
102
                }
103
            }
104

  
105
            return result;
106
        }
107

  
108
        /// <summary>
109
        /// Image<TColor, TDepth>의 틀린 부분을 Rect로 반환
110
        /// </summary>
111
        /// <param name="data"></param>
112
        /// <param name="block"></param>
113
        /// <returns></returns>
114
        protected List<System.Windows.Rect> GetMatchPixels(Mat data, Size block)
115
        {
116
            SetStatus("Detection", 0, CompareStatus.Detection);
117

  
118
            int width = data.Cols;
119
            int height = data.Rows;
120

  
121
            List<System.Windows.Rect> results = new List<System.Windows.Rect>();
122

  
123
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
124
            stopwatch.Start();
125

  
126
            Mat outputMat = new Mat(data.Size(), MatType.CV_8UC1);
127

  
128
            HierarchyIndex[] hierarchy;
129
            OpenCvSharp.Point[][] contours;
130

  
131
            OpenCvSharp.Point testpoint = new OpenCvSharp.Point();
132
           
133
            Cv2.Threshold(data, data, 0, 30,ThresholdTypes.BinaryInv);
134

  
135
            Cv2.FindContours(data, out contours, out hierarchy,RetrievalModes.List,ContourApproximationModes.ApproxNone, testpoint);
136

  
137
            SetStatus("Comparison", 0, CompareStatus.Comparison);
138
            contoursLongCount = contours.Sum(x => x.Count());
139

  
140
            var rects = contours.AsParallel()
141
                                .Select(points => GetRectList(points, block))
142
                                .SelectMany(x => x);
143

  
144
            results.AddRange(rects);
145
             
146
            return results;
147
        }
148

  
149
        private List<System.Windows.Rect> GetRectList(OpenCvSharp.Point[] points,Size block)
150
        {
151
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
152

  
153
            for (int i = 0; i < points.Count(); i++)
154
            {
155
                var rect = new System.Windows.Rect
156
                {
157
                    X = points[i].X - block.Width / 2,
158
                    Y = points[i].Y - block.Height / 2,
159
                    Width = block.Width,
160
                    Height = block.Height
161
                };
162

  
163
                if (result.Count(r => r.IntersectsWith(rect)) == 0)
164
                {
165
                    result.Add(rect);
166
                }
167

  
168
                ComparisonCount++;
169

  
170
                SetStatus("Comparison", ComparisonCount/contoursLongCount*100, CompareStatus.Comparison);
171
            }
172

  
173
            return result;
174
        }
175

  
176
        /// <summary>
177
        /// Image<TColor, TDepth>의 틀린 부분을 Rect로 반환
178
        /// </summary>
179
        /// <param name="data"></param>
180
        /// <param name="block"></param>
181
        /// <returns></returns>
182
        protected async Task<List<System.Windows.Rect>> GetMatchPixelsAsnc(Mat data, Size block)
183
        {
184
            return await Task.Factory.StartNew<List<System.Windows.Rect>>(() =>
185
            {
186
                return GetMatchPixels(data, block);
187
            });
188
        }
189

  
190
        protected Bitmap LoadPicture(string url)
191
        {
192
            HttpWebRequest wreq;
193
            HttpWebResponse wresp;
194
            Stream mystream;
195
            Bitmap bmp;
196

  
197
            bmp = null;
198
            mystream = null;
199
            wresp = null;
200
            try
201
            {
202
                wreq = (HttpWebRequest)WebRequest.Create(url);
203
                wreq.AllowWriteStreamBuffering = true;
204

  
205
                wresp = (HttpWebResponse)wreq.GetResponse();
206

  
207
                if ((mystream = wresp.GetResponseStream()) != null)
208
                    bmp = new Bitmap(mystream);
209
            }
210
            finally
211
            {
212
                if (mystream != null)
213
                {
214
                    mystream.Close();
215
                    mystream.Dispose();
216
                }
217

  
218
                if (wresp != null)
219
                {
220
                    wresp.Close();
221
                    wresp.Dispose();
222
                }
223
            }
224
            return (bmp);
225
        }
226

  
227
        #region  IDisposable Support 
228

  
229
        private bool disposedValue = false;
230

  
231
        // 중복 호출을 검색하려면 
232
        protected virtual void Dispose(bool disposing)
233
        {
234
            if (!disposedValue)
235
            {
236
                if (disposing)
237
                {
238
                    // TODO: 관리되는 상태(관리되는 개체)를 삭제합니다. 
239
                }
240
                // TODO: 관리되지 않는 리소스(관리되지 않는 개체)를 해제하고 아래의 종료자를 재정의합니다. 
241
                // TODO: 큰 필드를 null로 설정합니다. 
242
                disposedValue = true;
243
            }
244
        }
245

  
246
        // TODO: 위의 Dispose(bool disposing)에 관리되지 않는 리소스를 해제하는 코드가 포함되어 있는 경우에만 종료자를 재정의합니다.
247
        // 
248
        //~DisposeClass()
249
       // {
250
            // // 이 코드를 변경하지 마세요. 위의 Dispose(bool disposing)에 정리 코드를 입력하세요. 
251
            // Dispose(false); // 
252
       // } 
253

  
254
        // 삭제 가능한 패턴을 올바르게 구현하기 위해 추가된 코드입니다. 
255
        public void Dispose()
256
        {
257
            // 이 코드를 변경하지 마세요. 위의 Dispose(bool disposing)에 정리 코드를 입력하세요. 
258
            Dispose(true);
259

  
260

  
261
            if (OriginalImageData != null)
262
            {
263
                OriginalImageData.Dispose();
264
            }
265

  
266
            if (TargatImageData != null)
267
            {
268
                TargatImageData.Dispose();
269
            }
270

  
271
            // TODO: 위의 종료자가 재정의된 경우 다음 코드 줄의 주석 처리를 제거합니다. 
272
            //  GC.SuppressFinalize(this);
273
            GC.Collect();
274
            GC.SuppressFinalize(this);
275
            GC.Collect();
276
        } 
277
        #endregion
278
    }
279
}
ImageComparer/Markus.ImageComparer/ImageComparer - 복사본.cs
1
using Emgu.CV;
2
using Emgu.CV.Structure;
3
using System;
4
using System.Collections.Generic;
5
using System.Drawing;
6
using System.Drawing.Imaging;
7
using System.Linq;
8
using System.Text;
9
using System.Threading.Tasks;
10

  
11
namespace Markus.Image
12
{
13
    public class ImageComparer : ImageComparerBase
14
    {
15
        /// <summary>
16
        /// 이미지를 비교 후 원본 이미지에 Rect를 그린다.
17
        /// </summary>
18
        /// <param name="Originalbitmap">원본 이미지</param>
19
        /// <param name="TargatBitmap">비교대상 이미지</param>
20
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
21
        /// <returns></returns>
22
        public Bitmap CompareDrawRects(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize)
23
        {
24
            var rects =  CompareReturnRects(Originalbitmap, TargatBitmap, ResultRectSize);
25

  
26
            if (rects.Count != 0)
27
            {
28
                using (Graphics g = Graphics.FromImage(Originalbitmap))
29
                {
30
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height));
31

  
32
                    g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray());
33
                    g.Save();
34

  
35
                    g.Dispose();
36
                }
37
            }
38

  
39
            return Originalbitmap;
40
        }
41

  
42
        public System.Windows.Media.Imaging.BitmapSource CompareDrawRects(System.Windows.Media.Imaging.BitmapSource Originalbitmap, System.Windows.Media.Imaging.BitmapSource TargatBitmap, Size ResultRectSize)
43
        {
44
            var _Originalbitmap = CreateBitmapFromSource(Originalbitmap);
45
            var _TargatBitmap = CreateBitmapFromSource(TargatBitmap);
46

  
47
            var rects = CompareReturnRects(_Originalbitmap, _TargatBitmap, ResultRectSize);
48
         
49
            if (rects.Count != 0)
50
            {
51
                using (Graphics g = Graphics.FromImage(_Originalbitmap))
52
                {
53
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height));
54

  
55
                    g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray());
56
                    g.Save();
57

  
58
                    g.Dispose();
59
                }
60
            }
61

  
62
            return CreateBitmapSourceFromBitmap(_Originalbitmap);
63
        }
64

  
65
        public List<System.Windows.Rect> CompareReturnRects(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize)
66
        {
67
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
68

  
69
            Bitmap Originalbitmap = null;
70
            Bitmap TargatBitmap = null;
71

  
72
            try
73
            {
74

  
75
                Originalbitmap = LoadPicture(OriginalbitmapUri);
76
                TargatBitmap = LoadPicture(TargatBitmapUri);
77

  
78
                result = CompareReturnRects(Originalbitmap, TargatBitmap, ResultRectSize);
79
            }
80
            catch (Exception)
81
            {
82
                throw;
83
            }
84
            finally
85
            {
86
                Originalbitmap.Dispose();
87
                TargatBitmap.Dispose();
88
            }
89

  
90
            return result;
91
        }
92

  
93
        /// <summary>
94
        /// 이미지를 비교 후 해당 영역을 Rect로 반환한다.
95
        /// </summary>
96
        /// <param name="Originalbitmap">원본 이미지</param>
97
        /// <param name="TargatBitmap">비교대상 이미지</param>
98
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
99
        /// <returns></returns>
100
        public List<System.Windows.Rect> CompareReturnRects(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize)
101
        {
102
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
103

  
104
            try
105
            {
106
                Point[][] data = MathchesImageData(Originalbitmap, TargatBitmap);
107

  
108
                result =  GetMatchPixels(data, ResultRectSize);
109
            }
110
            catch (Exception ex)
111
            {
112
                throw ex;
113
            }
114
            finally
115
            {
116

  
117
            }
118

  
119
            return result;
120
        }
121

  
122

  
123
        /// <summary>
124
        /// 이미지를 비교 후 원본 이미지에 Rect를 그린다.
125
        /// 메모리 문제 발생
126
        /// </summary>
127
        /// <param name="Originalbitmap">원본 이미지</param>
128
        /// <param name="TargatBitmap">비교대상 이미지</param>
129
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
130
        /// <returns></returns>
131
        public async Task<Bitmap> CompareDrawRectsAsync(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize)
132
        {
133
            System.Drawing.Bitmap cloneOriginal = Originalbitmap;
134

  
135
            var rects = await CompareReturnRectsAsync(cloneOriginal, TargatBitmap, ResultRectSize);
136

  
137
            if (rects.Count != 0)
138
            {
139
                using (Graphics g = Graphics.FromImage(cloneOriginal))
140
                {
141
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height));
142

  
143
                    g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray());
144
                    g.Save();
145

  
146
                    g.Dispose();
147
                }
148
            }
149

  
150
            return cloneOriginal;
151
        }
152

  
153
        public async Task<Bitmap> CompareDrawRectsAsync(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize)
154
        {
155
            Bitmap Originalbitmap = null;
156
            Bitmap TargatBitmap = null;
157

  
158
            Originalbitmap = LoadPicture(OriginalbitmapUri);
159
            TargatBitmap = LoadPicture(TargatBitmapUri);
160

  
161
            System.Drawing.Bitmap cloneOriginal = Originalbitmap;
162

  
163
            var rects = await CompareReturnRectsAsync(cloneOriginal, TargatBitmap, ResultRectSize);
164

  
165
            if (rects.Count != 0)
166
            {
167
                using (Graphics g = Graphics.FromImage(cloneOriginal))
168
                {
169
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height));
170

  
171
                    g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray());
172
                    g.Save();
173

  
174
                    g.Dispose();
175
                }
176
            }
177

  
178
            return cloneOriginal;
179
        }
180

  
181

  
182
        /// <summary>
183
        /// 이미지를 비교 후 원본 이미지에 Rect를 그린다.
184
        /// 메모리 문제 발생
185
        /// </summary>
186
        /// <param name="Originalbitmap">원본 이미지</param>
187
        /// <param name="TargatBitmap">비교대상 이미지</param>
188
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
189
        /// <returns></returns>
190
        public async Task<System.Windows.Media.Imaging.BitmapSource> CompareDrawRectsAsync(System.Windows.Media.Imaging.BitmapSource Originalbitmap, System.Windows.Media.Imaging.BitmapSource TargatBitmap, Size ResultRectSize)
191
        {
192

  
193
            var _Originalbitmap = CreateBitmapFromSource(Originalbitmap);
194
            var _TargatBitmap = CreateBitmapFromSource(TargatBitmap);
195

  
196
            var rects = await CompareReturnRectsAsync(_Originalbitmap, _TargatBitmap, ResultRectSize);
197

  
198
            if (rects.Count != 0)
199
            {
200
                using (Graphics g = Graphics.FromImage(_Originalbitmap))
201
                {
202
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height));
203

  
204
                    g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray());
205
                    g.Save();
206

  
207
                    g.Dispose();
208
                }
209
            }
210

  
211
            return CreateBitmapSourceFromBitmap(_Originalbitmap);
212
        }
213

  
214
        public Bitmap CreateBitmapFromSource(System.Windows.Media.Imaging.BitmapSource bitmapsource)
215
        {
216
            //convert image format
217
            var src = new System.Windows.Media.Imaging.FormatConvertedBitmap();
218
            src.BeginInit();
219
            src.Source = bitmapsource;
220
            src.DestinationFormat = System.Windows.Media.PixelFormats.Bgr24;
221
            src.EndInit();
222

  
223
            //copy to bitmap
224
            Bitmap bitmap = new Bitmap(src.PixelWidth, src.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
225
            var data = bitmap.LockBits(new Rectangle(Point.Empty, bitmap.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
226
            src.CopyPixels(System.Windows.Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
227
            bitmap.UnlockBits(data);
228

  
229
            return bitmap;
230
        }
231

  
232
        /// <summary>
233
        /// 메모리 문제 발생
234
        /// </summary>
235
        /// <param name="bitmap"></param>
236
        /// <returns></returns>
237
        public System.Windows.Media.Imaging.WriteableBitmap CreateWriteableBitmapFromBitmap(Bitmap bitmap)
238
        {
239
            System.Windows.Media.Imaging.WriteableBitmap result = null;
240

  
241
            if (bitmap == null)
242
                throw new ArgumentNullException("bitmap");
243

  
244
            try
245
            {
246
                int bytesPerPixel = 4;
247

  
248
                result = new System.Windows.Media.Imaging.WriteableBitmap(bitmap.Width, bitmap.Height,
249
                                                                   bitmap.HorizontalResolution ,bitmap.VerticalResolution,
250
                                                                   bitmap.PixelFormat.Convert(), null);
251

  
252
                Rectangle colorBitmapRectangle = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
253
                System.Windows.Int32Rect colorBitmapInt32Rect = new System.Windows.Int32Rect(0, 0, bitmap.Width, bitmap.Height);
254

  
255
                BitmapData data = bitmap.LockBits(colorBitmapRectangle, ImageLockMode.WriteOnly, bitmap.PixelFormat);
256

  
257
                result.WritePixels(colorBitmapInt32Rect, data.Scan0, data.Width * data.Height * bytesPerPixel, data.Stride);
258

  
259
                bitmap.UnlockBits(data);
260
            }
261
            catch (Exception ex)
262
            {
263
                //throw ex;
264
            }
265
            finally
266
            {
267
                bitmap.Dispose();
268
                bitmap = null;
269
                //GC.Collect(2);
270
            }
271

  
272
            return result;
273
        }
274
    
275
        /// <summary>
276
        /// 메모리 문제 발생
277
        /// </summary>
278
        /// <param name="bitmap"></param>
279
        /// <returns></returns>
280
        public System.Windows.Media.Imaging.BitmapSource CreateBitmapSourceFromBitmap(Bitmap bitmap)
281
        {
282
            System.Windows.Media.Imaging.BitmapSource result = null;
283
            
284
            if (bitmap == null)
285
                throw new ArgumentNullException("bitmap");
286

  
287
            try
288
            {
289
                using (var hbitmap = new SafeHBitmapHandle(bitmap.GetHbitmap(), true))
290
                {
291

  
292
                    result = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
293
                        hbitmap.DangerousGetHandle(),
294
                        IntPtr.Zero,
295
                        System.Windows.Int32Rect.Empty,
296
                        System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
297

  
298
                   
299
                }
300
            }
301
            catch (Exception ex)
302
            {
303
                //throw ex;
304
            }
305
            finally
306
            {
307
                bitmap.Dispose();
308
                bitmap = null;
309
                //GC.Collect(2);
310
            }
311

  
312
            return result;
313
        }
314

  
315
        public async Task<List<System.Windows.Rect>> CompareReturnRectsAsync(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize)
316
        {
317
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
318

  
319
            Bitmap Originalbitmap = null;
320
            Bitmap TargatBitmap = null;
321

  
322
            try
323
            {
324

  
325
                Originalbitmap = LoadPicture(OriginalbitmapUri);
326
                TargatBitmap = LoadPicture(TargatBitmapUri);
327

  
328
                result = await CompareReturnRectsAsync(Originalbitmap, TargatBitmap, ResultRectSize);
329
            }
330
            catch (Exception)
331
            {
332
                throw;
333
            }
334
            finally
335
            {
336
                Originalbitmap.Dispose();
337
                TargatBitmap.Dispose();
338
            }
339

  
340
            return result;
341
        }
342

  
343
        /// <summary>
344
        /// 이미지를 비교 후 해당 영역을 Rect로 반환한다.
345
        /// </summary>
346
        /// <param name="Originalbitmap">원본 이미지</param>
347
        /// <param name="TargatBitmap">비교대상 이미지</param>
348
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
349
        /// <returns></returns>
350
        public async Task<List<System.Windows.Rect>> CompareReturnRectsAsync(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize)
351
        {
352
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
353

  
354
            try
355
            {
356
                byte[,,] data = MathchesImageData(Originalbitmap, TargatBitmap);
357

  
358
                result = await GetMatchPixelsAsnc(data, ResultRectSize);
359
         
360
                data = null;
361
            }
362
            catch (Exception ex)
363
            {
364
                throw ex;
365
            }
366
            finally
367
            {
368
            }
369

  
370
            return result;
371
        }
372

  
373
       
374
        protected override void Dispose(bool disposing)
375
        {
376
            base.Dispose(disposing);
377
        }
378
    }
379
}
ImageComparer/Markus.ImageComparer/ImageComparerBase - 복사본.cs
1
using Emgu.CV;
2
using Emgu.CV.CvEnum;
3
using Emgu.CV.Structure;
4
using System;
5
using System.Collections.Generic;
6
using System.Drawing;
7
using System.Drawing.Imaging;
8
using System.IO;
9
using System.Linq;
10
using System.Net;
11
using System.Text;
12
using System.Threading.Tasks;
13

  
14
namespace Markus.Image
15
{
16
    public class ImageComparerBase : IDisposable
17
    {
18
        Image<Gray, Byte> OriginalImageData = null;
19
        Image<Gray, Byte> TargatImageData = null;
20

  
21
        int Threshold = 60; //stores threshold for thread access
22

  
23
        /// <summary>
24
        /// 이미지 비교에 사용되는 점수
25
        /// </summary>
26
        double gMatchScore = 0.09;
27

  
28
        /// <summary>
29
        /// 이미지의 크기와 포멧을 변경한다.
30
        /// </summary>
31
        /// <param name="bitmap"></param>
32
        /// <param name="newSize"></param>
33
        /// <param name="pixelFormat"></param>
34
        /// <returns></returns>
35
        protected System.Drawing.Bitmap ChangeBitmapFormatAndSize(System.Drawing.Bitmap bitmap, Size newSize, PixelFormat pixelFormat)
36
        {
37
            Bitmap result = bitmap;
38

  
39
            if (pixelFormat != bitmap.PixelFormat)
40
            {
41
                Point originPoint = new Point(0, 0);
42
                Rectangle rect = new Rectangle(originPoint, bitmap.Size);
43
                result = bitmap.Clone(rect, pixelFormat);
44
            }
45

  
46
            if (bitmap.Size != newSize)
47
            {
48
                result = new Bitmap(newSize.Width, newSize.Height);
49

  
50
                using (Graphics g = Graphics.FromImage(result))
51
                {
52
                    g.DrawImage(bitmap, 0, 0, newSize.Width, newSize.Height);
53
                    g.Dispose();
54
                }
55
            }
56

  
57
            return result;
58
        }
59

  
60
        /// <summary>
61
        /// Originalbitmap에서 TargatBitmap과 비교하여 틀린 부분의 데이터를 Emgu.CV.TDepth형식으로 반환한다.
62
        /// </summary>
63
        /// <param name="Originalbitmap">원본 이미지</param>
64
        /// <param name="TargatBitmap">비교대상 이미지</param>
65
        /// <returns>Emgu.CV.TDepth형식의 byte[,,]</returns>
66
        protected byte[,,] MathchesImageData_old(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap)
67
        {
68
            byte[,,] result = null;
69

  
70
            try
71
            {
72
                // 원본이미지의 크키와 Format24bppRgb로 타켓 이미지를 변경
73
                // 크기가 틀린 경우 비교시 바이트배열 오류 발생
74
                // 이미지 포멧은 24bit이하로 emgu CV가 작동
75
                Originalbitmap = ChangeBitmapFormatAndSize(Originalbitmap, Originalbitmap.Size, PixelFormat.Format24bppRgb);
76
                TargatBitmap = ChangeBitmapFormatAndSize(TargatBitmap, Originalbitmap.Size, PixelFormat.Format24bppRgb);
77
                
78
                OriginalImageData = new Image<Gray, Byte>(Originalbitmap);
79
                TargatImageData = new Image<Gray, Byte>(TargatBitmap);
80

  
81
                //OriginalImageData = OriginalImageData.SmoothBilateral(10,50,50);
82
                //TargatImageData = TargatImageData.SmoothBilateral(10, 50, 50);
83

  
84
                #region Apply dilation and erosion to remove some noise 효과없음
85
                //OriginalImageData = OriginalImageData.Dilate(1);
86
                //TargatImageData = TargatImageData.Dilate(1);
87
                //OriginalImageData = OriginalImageData.Erode(1);
88
                //TargatImageData = TargatImageData.Erode(1);
89

  
90
                //threshold(OriginalImageData);
91
                //threshold(TargatImageData);
92
                #endregion
93

  
94
                //Computes absolute different between this image and the other image
95
                // 원본이미지와 타겟이미지를 처리
96
                var tmp = OriginalImageData.AbsDiff(TargatImageData).ThresholdBinary(new Gray(50), new Gray(255));
97
                var matches = tmp.Not();
98

  
99
                // 틀린부분을 반환
100
                result = matches.Data;
101

  
102
            
103

  
104

  
105
                matches.Dispose();
106
                tmp.Dispose();
107
            }
108
            catch (Exception ex)
109
            {
110
                throw ex;
111
            }
112
            
113
            return result;
114
        }
115

  
116
        protected Point[][] MathchesImageData(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap)
117
        {
118
            Point[][] result = null;
119

  
120
            try
121
            {
122
                // 원본이미지의 크키와 Format24bppRgb로 타켓 이미지를 변경
123
                // 크기가 틀린 경우 비교시 바이트배열 오류 발생
124
                // 이미지 포멧은 24bit이하로 emgu CV가 작동
125
                Originalbitmap = ChangeBitmapFormatAndSize(Originalbitmap, Originalbitmap.Size, PixelFormat.Format24bppRgb);
126
                TargatBitmap = ChangeBitmapFormatAndSize(TargatBitmap, Originalbitmap.Size, PixelFormat.Format24bppRgb);
127

  
128
                OriginalImageData = new Image<Gray, Byte>(Originalbitmap);
129
                TargatImageData = new Image<Gray, Byte>(TargatBitmap);
130

  
131
                //OriginalImageData = OriginalImageData.SmoothBilateral(10,50,50);
132
                //TargatImageData = TargatImageData.SmoothBilateral(10, 50, 50);
133

  
134
                #region Apply dilation and erosion to remove some noise 효과없음
135
                //OriginalImageData = OriginalImageData.Dilate(1);
136
                //TargatImageData = TargatImageData.Dilate(1);
137
                //OriginalImageData = OriginalImageData.Erode(1);
138
                //TargatImageData = TargatImageData.Erode(1);
139

  
140
                //threshold(OriginalImageData);
141
                //threshold(TargatImageData);
142
                #endregion
143

  
144
                //Computes absolute different between this image and the other image
145
                // 원본이미지와 타겟이미지를 처리
146
                var tmp = OriginalImageData.AbsDiff(TargatImageData).ThresholdBinary(new Gray(50), new Gray(255));
147

  
148
                Emgu.CV.Util.VectorOfVectorOfPoint contours = new Emgu.CV.Util.VectorOfVectorOfPoint();
149
                Mat m = new Mat();
150

  
151
                CvInvoke.FindContours(tmp, contours, m, Emgu.CV.CvEnum.RetrType.External, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple);
152

  
153
                result = contours.ToArrayOfArray();
154
                tmp.Dispose();
155
            }
156
            catch (Exception ex)
157
            {
158
                throw ex;
159
            }
160

  
161
            return result;
162
        }
163

  
164
        private void threshold(Emgu.CV.Image<Gray, byte> image)
165
        {
166
            Emgu.CV.Image<Gray, byte> outImg = new Image<Gray, byte>(image.Size);
167

  
168
            //CvInvoke.Threshold(image.SmoothGaussian(5), outImg,0, 255, ThresholdType.Mask);
169
            CvInvoke.AdaptiveThreshold(image.SmoothMedian(1), outImg, 255,AdaptiveThresholdType.GaussianC,ThresholdType.Binary,31,2);
170
            //CvInvoke.Threshold(image.SmoothGaussian(9), outImg, 100, 255, ThresholdType.Binary | ThresholdType.Otsu);
171

  
172
            image = outImg;
173
        }
174

  
175
        /// <summary>
176
        /// MathchesImageData의 틀린 부분을 Rect로 반환
177
        /// </summary>
178
        /// <param name="data"></param>
179
        /// <param name="currentX"></param>
180
        /// <param name="currentY"></param>
181
        /// <param name="ImageWidth"></param>
182
        /// <param name="ImageHeight"></param>
183
        /// <param name="block"></param>
184
        /// <returns></returns>
185
        protected System.Windows.Rect? DataMatchScore(byte[,,] data, int currentX, int currentY, int ImageWidth, int ImageHeight, Size block)
186
        {
187
            System.Windows.Rect? result = null;
188

  
189
            int x = currentX;
190
            int y = currentY;
191
            int width = ImageWidth;
192
            int height = ImageHeight;
193

  
194
            for (int i = 0; i < block.Width; i++)
195
            {
196
                int wi = x + i;
197
                if (wi >= width) break;
198

  
199
                for (int j = 0; j < block.Height; j++)
200
                {
201
                    int hj = y + j;
202
                    if (hj >= height) break;
203

  
204
                    double matchScore = data[wi, hj, 0];
205

  
206
                    if (matchScore < gMatchScore)
207
                    {
208
                        result = new System.Windows.Rect(y, x, block.Width, block.Height);
209
                        return result;
210
                    }
211
                }
212
            }
213

  
214
            return result;
215
        }
216

  
217
        /// <summary>
218
        /// Image<TColor, TDepth>의 틀린 부분을 Rect로 반환
219
        /// </summary>
220
        /// <param name="data"></param>
221
        /// <param name="block"></param>
222
        /// <returns></returns>
223
        protected List<System.Windows.Rect> GetMatchPixels(byte[,,] data, Size block)
224
        {
225
            int width = data.GetLength(0);
226
            int height = data.GetLength(1);
227

  
228
            List<System.Windows.Rect> results = new List<System.Windows.Rect>();
229

  
230
            var heightRange = from h in Enumerable.Range(1, height)
231
                              where h % block.Height == 0
232
                              select h;
233

  
234
            var widthRange = from w in Enumerable.Range(1, width)
235
                             where w % block.Width == 0
236
                             select w;
237

  
238
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
239
            stopwatch.Start();
240

  
241
            Parallel.ForEach(heightRange, (y) =>
242
            {
243
                Parallel.ForEach(widthRange, (x) =>
244
                {
245
                    var rect = DataMatchScore(data, x, y, width, height, block);
246

  
247
                    if (rect != null)
248
                    {
249
                        results.Add(rect.Value);
250
                    }
251
                });
252
            });
253

  
254
            System.Diagnostics.Debug.WriteLine("1 - " + new TimeSpan(stopwatch.ElapsedTicks));
255
            return results;
256
        }
257

  
258
        protected List<System.Windows.Rect> GetMatchPixels(byte[,,] data, Size block)
259
        {
260
            int width = data.GetLength(0);
261
            int height = data.GetLength(1);
262

  
263
            List<System.Windows.Rect> results = new List<System.Windows.Rect>();
264

  
265
            var heightRange = from h in Enumerable.Range(1, height)
266
                              where h % block.Height == 0
267
                              select h;
268

  
269
            var widthRange = from w in Enumerable.Range(1, width)
270
                             where w % block.Width == 0
271
                             select w;
272

  
273
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
274
            stopwatch.Start();
275

  
276
            Parallel.ForEach(heightRange, (y) =>
277
            {
278
                Parallel.ForEach(widthRange, (x) =>
279
                {
280
                    var rect = DataMatchScore(data, x, y, width, height, block);
281

  
282
                    if (rect != null)
283
                    {
284
                        results.Add(rect.Value);
285
                    }
286
                });
287
            });
288

  
289
            System.Diagnostics.Debug.WriteLine("1 - " + new TimeSpan(stopwatch.ElapsedTicks));
290
            return results;
291
        }
292

  
293
        /// <summary>
294
        /// Image<TColor, TDepth>의 틀린 부분을 Rect로 반환
295
        /// </summary>
296
        /// <param name="data"></param>
297
        /// <param name="block"></param>
298
        /// <returns></returns>
299
        protected async Task<List<System.Windows.Rect>> GetMatchPixelsAsnc(byte[,,] data, Size block)
300
        {
301
            return await Task.Factory.StartNew<List<System.Windows.Rect>>(() =>
302
            {
303
                return GetMatchPixels(data, block);
304
            });
305
        }
306

  
307
        protected Bitmap LoadPicture(string url)
308
        {
309
            HttpWebRequest wreq;
310
            HttpWebResponse wresp;
311
            Stream mystream;
312
            Bitmap bmp;
313

  
314
            bmp = null;
315
            mystream = null;
316
            wresp = null;
317
            try
318
            {
319
                wreq = (HttpWebRequest)WebRequest.Create(url);
320
                wreq.AllowWriteStreamBuffering = true;
321

  
322
                wresp = (HttpWebResponse)wreq.GetResponse();
323

  
324
                if ((mystream = wresp.GetResponseStream()) != null)
325
                    bmp = new Bitmap(mystream);
326
            }
327
            finally
328
            {
329
                if (mystream != null)
330
                {
331
                    mystream.Close();
332
                    mystream.Dispose();
333
                }
334

  
335
                if (wresp != null)
336
                {
337
                    wresp.Close();
338
                    wresp.Dispose();
339
                }
340
            }
341
            return (bmp);
342
        }
343

  
344
        #region  IDisposable Support 
345

  
346
        private bool disposedValue = false;
347

  
348
        // 중복 호출을 검색하려면 
349
        protected virtual void Dispose(bool disposing)
350
        {
351
            if (!disposedValue)
352
            {
353
                if (disposing)
354
                {
355
                    // TODO: 관리되는 상태(관리되는 개체)를 삭제합니다. 
356
                }
357
                // TODO: 관리되지 않는 리소스(관리되지 않는 개체)를 해제하고 아래의 종료자를 재정의합니다. 
358
                // TODO: 큰 필드를 null로 설정합니다. 
359
                disposedValue = true;
360
            }
361
        }
362

  
363
        // TODO: 위의 Dispose(bool disposing)에 관리되지 않는 리소스를 해제하는 코드가 포함되어 있는 경우에만 종료자를 재정의합니다.
364
        // 
365
        //~DisposeClass()
366
       // {
367
            // // 이 코드를 변경하지 마세요. 위의 Dispose(bool disposing)에 정리 코드를 입력하세요. 
368
            // Dispose(false); // 
369
       // } 
370

  
371
        // 삭제 가능한 패턴을 올바르게 구현하기 위해 추가된 코드입니다. 
372
        public void Dispose()
373
        {
374
            // 이 코드를 변경하지 마세요. 위의 Dispose(bool disposing)에 정리 코드를 입력하세요. 
375
            Dispose(true);
376

  
377

  
378
            if (OriginalImageData != null)
379
            {
... 이 차이점은 표시할 수 있는 최대 줄수를 초과해서 이 차이점은 잘렸습니다.

내보내기 Unified diff

클립보드 이미지 추가 (최대 크기: 500 MB)