프로젝트

일반

사용자정보

개정판 6b6bc870

ID6b6bc87043883385753788073b9c07e73b5e7717
상위 95e6fe93
하위 9f61d7b6

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

markus.ImageComparer - opencvSharp으로 변경

Change-Id: I61b98727b99f086f90b997ce6419b5a6c352bb97

차이점 보기:

ImageComparer/ComparerTestWPF/App.config
1 1
<?xml version="1.0" encoding="utf-8" ?>
2 2
<configuration>
3
    <startup> 
3
  <startup> 
4 4
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
5 5
    </startup>
6 6
</configuration>
ImageComparer/ComparerTestWPF/ComparerTestWPF.csproj
15 15
    <Deterministic>true</Deterministic>
16 16
  </PropertyGroup>
17 17
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
18
    <PlatformTarget>AnyCPU</PlatformTarget>
18
    <PlatformTarget>x64</PlatformTarget>
19 19
    <DebugSymbols>true</DebugSymbols>
20 20
    <DebugType>full</DebugType>
21 21
    <Optimize>false</Optimize>
ImageComparer/Markus.Image.sln
12 12
		Nuget\Markus.Image.nupkg = Nuget\Markus.Image.nupkg
13 13
	EndProjectSection
14 14
EndProject
15
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Markus.Image.EMGU", "Markus.ImageComparer.EMGU\Markus.Image.EMGU.csproj", "{96437AC2-24F9-48A7-AC24-221086017BB3}"
16
EndProject
15 17
Global
16 18
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
17 19
		Debug|Any CPU = Debug|Any CPU
......
26 28
		{154D99CA-A021-4FFD-A590-5CEBF6C99BB3}.Debug|Any CPU.Build.0 = Debug|Any CPU
27 29
		{154D99CA-A021-4FFD-A590-5CEBF6C99BB3}.Release|Any CPU.ActiveCfg = Release|Any CPU
28 30
		{154D99CA-A021-4FFD-A590-5CEBF6C99BB3}.Release|Any CPU.Build.0 = Release|Any CPU
31
		{96437AC2-24F9-48A7-AC24-221086017BB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
32
		{96437AC2-24F9-48A7-AC24-221086017BB3}.Debug|Any CPU.Build.0 = Debug|Any CPU
33
		{96437AC2-24F9-48A7-AC24-221086017BB3}.Release|Any CPU.ActiveCfg = Release|Any CPU
34
		{96437AC2-24F9-48A7-AC24-221086017BB3}.Release|Any CPU.Build.0 = Release|Any CPU
29 35
	EndGlobalSection
30 36
	GlobalSection(SolutionProperties) = preSolution
31 37
		HideSolutionNode = FALSE
ImageComparer/Markus.ImageComparer.EMGU/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.EMGU/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.EMGU/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)).ToList();
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
        // JoinRects: will return a rectangle composed of r1 and r2.
43
        private System.Windows.Rect JoinRects(System.Windows.Rect r1, System.Windows.Rect r2)
44
        {
45
            return new System.Windows.Rect(Math.Min(r1.X, r2.X),
46
                            Math.Min(r1.Y, r2.Y),
47
                            Math.Max(r1.Y + r1.Width, r2.Y + r2.Width),
48
                            Math.Max(r1.X + r1.Height, r2.X + r2.Height));
49
        }
50

  
51
        private System.Windows.Rect RectSizeUp(System.Windows.Rect rect,int UpSize)
52
        {
53
            return new System.Windows.Rect(rect.X - UpSize, rect.Y - UpSize, rect.Width + UpSize, rect.Height + UpSize);
54
        }
55

  
56
        public System.Windows.Media.Imaging.BitmapSource CompareDrawRects(System.Windows.Media.Imaging.BitmapSource Originalbitmap, System.Windows.Media.Imaging.BitmapSource TargatBitmap, Size ResultRectSize)
57
        {
58
            var _Originalbitmap = CreateBitmapFromSource(Originalbitmap);
59
            var _TargatBitmap = CreateBitmapFromSource(TargatBitmap);
60

  
61
            var rects = CompareReturnRects(_Originalbitmap, _TargatBitmap, ResultRectSize);
62
         
63
            if (rects.Count != 0)
64
            {
65
                using (Graphics g = Graphics.FromImage(_Originalbitmap))
66
                {
67
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height));
68

  
69
                    g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray());
70
                    g.Save();
71

  
72
                    g.Dispose();
73
                }
74
            }
75

  
76
            return CreateBitmapSourceFromBitmap(_Originalbitmap);
77
        }
78

  
79
        public List<System.Windows.Rect> CompareReturnRects(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize)
80
        {
81
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
82

  
83
            Bitmap Originalbitmap = null;
84
            Bitmap TargatBitmap = null;
85

  
86
            try
87
            {
88

  
89
                Originalbitmap = LoadPicture(OriginalbitmapUri);
90
                TargatBitmap = LoadPicture(TargatBitmapUri);
91

  
92
                result = CompareReturnRects(Originalbitmap, TargatBitmap, ResultRectSize);
93
            }
94
            catch (Exception)
95
            {
96
                throw;
97
            }
98
            finally
99
            {
100
                Originalbitmap.Dispose();
101
                TargatBitmap.Dispose();
102
            }
103

  
104
            return result;
105
        }
106

  
107
        /// <summary>
108
        /// 이미지를 비교 후 해당 영역을 Rect로 반환한다.
109
        /// </summary>
110
        /// <param name="Originalbitmap">원본 이미지</param>
111
        /// <param name="TargatBitmap">비교대상 이미지</param>
112
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
113
        /// <returns></returns>
114
        public List<System.Windows.Rect> CompareReturnRects(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize)
115
        {
116
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
117

  
118
            try
119
            {
120
                List<System.Windows.Rect> rects = new List<System.Windows.Rect>();
121

  
122
                byte[,,] data = MathchesImageData(Originalbitmap, TargatBitmap);
123

  
124
                result =  GetMatchPixels(data, ResultRectSize);
125

  
126
                //if (rects.Count() > 0)
127
                //{
128
                //    result = Merge(rects, ResultRectSize.Height);
129
                //}
130

  
131
                //result = JoinRectList(rects);
132
            }
133
            catch (Exception ex)
134
            {
135
                throw ex;
136
            }
137
            finally
138
            {
139

  
140
            }
141

  
142
            return result;
143
        }
144

  
145
        private List<System.Windows.Rect> JoinRectList(List<System.Windows.Rect> rects)
146
        {
147
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
148

  
149
            if (rects.Count() > 0)
150
            {
151
                System.Windows.Rect rect = rects[0];
152
                System.Windows.Rect joinRect = rects[0];
153

  
154
                while (rects.Count() > 0)
155
                {
156
                    var joinItems = rects.Where(x => RectSizeUp(joinRect, 1).Contains(x)).ToList();
157

  
158
                    if (joinItems.Count() == 0)
159
                    {
160
                        result.Add(joinRect);
161
                    }
162
                    else
163
                    {
164
                        for (int i = 0; i < joinItems.Count(); i++)
165
                        {
166
                            rect = JoinRects(rect, joinItems[i]);
167
                            rects.Remove(joinItems[i]);
168
                        }
169

  
170
                        if (rects.Count() > 0)
171
                        {
172
                            rects.RemoveAt(0);
173
                        }
174

  
175
                        result.Add(joinRect);
176
                    }
177
                }
178
            }
179

  
180
            return result;
181
        }
182

  
183
        private List<System.Windows.Rect> Merge(List<System.Windows.Rect> r,int rectHeight)
184
        {
185
            // Computing the bound
186
            System.Windows.Rect bound = new System.Windows.Rect(r[0].X, r[0].Y, r[0].Width, r[0].Height);
187
            for (int i = 1; i < r.Count(); ++i)
188
            {
189
                bound.X = Math.Min(bound.X, r[i].X);
190
                bound.Y = Math.Min(bound.Y, r[i].Y);
191
                bound.Width = Math.Max(bound.Right, r[i].Right) - bound.X;
192
                bound.Height = Math.Max(bound.Bottom, r[i].Bottom) - bound.Y;
193
            }
194

  
195
            // Create number of rectangle will be created by vertical strip expansion
196
            System.Windows.Rect[] m = new System.Windows.Rect[(int)bound.Height / (int)rectHeight];
197
            for (int i = 0; i < m.Length; ++i)
198
            {
199
                m[i] = new System.Windows.Rect(bound.X, bound.Y + i * rectHeight, bound.Y, rectHeight);
200
            }
201

  
202
            for (int i = 0; i < r.Count(); ++i)
203
            {
204
                int index = ((int)r[i].Y - (int)bound.Y) / rectHeight;
205

  
206
                if (m[index].Width <= 0)
207
                {
208
                    m[index].Width = r[i].Width;
209
                    m[index].X = r[i].X;
210
                }
211
                else
212
                {
213
                    int right = (int)m[index].Right;
214
                    m[index].X = Math.Min(m[index].X, r[i].X);
215
                    m[index].Width = Math.Max(right, r[i].Right) - m[index].X;
216
                }
217
            }
218

  
219
            // Merge horozontally
220
            for (int i = m.Length - 1; i > 0; --i)
221
            {
222
                // can only merge when two rect has the same X and Width
223
                if ((m[i].X == m[i - 1].X) && (m[i].Width == m[i - 1].Width))
224
                {
225
                    m[i - 1].Height += m[i].Height; // expanse the rectangle
226
                    m[i].Width = 0;                // remove one rectangle
227
                }
228
            }
229

  
230
            // Remove all the empty rectangle
231
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
232
            for (int i = m.Length - 1; i >= 0; --i)
233
            {
234
                if (m[i].Width > 0)
235
                    result.Add(m[i]);
236
            }
237

  
238
            return result;
239
        }
240
        /// <summary>
241
        /// 이미지를 비교 후 원본 이미지에 Rect를 그린다.
242
        /// 메모리 문제 발생
243
        /// </summary>
244
        /// <param name="Originalbitmap">원본 이미지</param>
245
        /// <param name="TargatBitmap">비교대상 이미지</param>
246
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
247
        /// <returns></returns>
248
        public async Task<Bitmap> CompareDrawRectsAsync(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize)
249
        {
250
            System.Drawing.Bitmap cloneOriginal = Originalbitmap;
251

  
252
            var rects = await CompareReturnRectsAsync(cloneOriginal, TargatBitmap, ResultRectSize);
253

  
254
            if (rects.Count != 0)
255
            {
256
                using (Graphics g = Graphics.FromImage(cloneOriginal))
257
                {
258
               
259
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height));
260

  
261
                    g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray());
262
                    g.Save();
263

  
264
                    g.Dispose();
265
                }
266
            }
267

  
268
            return cloneOriginal;
269
        }
270

  
271
        /// <summary>
272
        /// 이미지를 비교 후 원본 이미지에 Rect를 그린다.
273
        /// 메모리 문제 발생
274
        /// </summary>
275
        /// <param name="Originalbitmap">원본 이미지</param>
276
        /// <param name="TargatBitmap">비교대상 이미지</param>
277
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
278
        /// <returns></returns>
279
        public async Task<System.Windows.Media.Imaging.BitmapSource> CompareDrawRectsAsync(System.Windows.Media.Imaging.BitmapSource Originalbitmap, System.Windows.Media.Imaging.BitmapSource TargatBitmap, Size ResultRectSize)
280
        {
281

  
282
            var _Originalbitmap = CreateBitmapFromSource(Originalbitmap);
283
            var _TargatBitmap = CreateBitmapFromSource(TargatBitmap);
284

  
285
            var rects = await CompareReturnRectsAsync(_Originalbitmap, _TargatBitmap, ResultRectSize);
286

  
287
            if (rects.Count != 0)
288
            {
289
                using (Graphics g = Graphics.FromImage(_Originalbitmap))
290
                {
291
                    var rect = rects.Select(x => new System.Drawing.Rectangle((int)x.X, (int)x.Y, (int)x.Width, (int)x.Height));
292

  
293
                    g.DrawRectangles(new Pen(Brushes.Blue, 3f), rect.ToArray());
294
                    g.Save();
295

  
296
                    g.Dispose();
297
                }
298
            }
299

  
300
            return CreateBitmapSourceFromBitmap(_Originalbitmap);
301
        }
302

  
303
        public Bitmap CreateBitmapFromSource(System.Windows.Media.Imaging.BitmapSource bitmapsource)
304
        {
305
            //convert image format
306
            var src = new System.Windows.Media.Imaging.FormatConvertedBitmap();
307
            src.BeginInit();
308
            src.Source = bitmapsource;
309
            src.DestinationFormat = System.Windows.Media.PixelFormats.Bgr24;
310
            src.EndInit();
311

  
312
            //copy to bitmap
313
            Bitmap bitmap = new Bitmap(src.PixelWidth, src.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
314
            var data = bitmap.LockBits(new Rectangle(Point.Empty, bitmap.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
315
            src.CopyPixels(System.Windows.Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
316
            bitmap.UnlockBits(data);
317

  
318
            return bitmap;
319
        }
320

  
321
        /// <summary>
322
        /// 메모리 문제 발생
323
        /// </summary>
324
        /// <param name="bitmap"></param>
325
        /// <returns></returns>
326
        public System.Windows.Media.Imaging.WriteableBitmap CreateWriteableBitmapFromBitmap(Bitmap bitmap)
327
        {
328
            System.Windows.Media.Imaging.WriteableBitmap result = null;
329

  
330
            if (bitmap == null)
331
                throw new ArgumentNullException("bitmap");
332

  
333
            try
334
            {
335
                int bytesPerPixel = 4;
336

  
337
                result = new System.Windows.Media.Imaging.WriteableBitmap(bitmap.Width, bitmap.Height,
338
                                                                   bitmap.HorizontalResolution ,bitmap.VerticalResolution,
339
                                                                   bitmap.PixelFormat.Convert(), null);
340

  
341
                Rectangle colorBitmapRectangle = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
342
                System.Windows.Int32Rect colorBitmapInt32Rect = new System.Windows.Int32Rect(0, 0, bitmap.Width, bitmap.Height);
343

  
344
                BitmapData data = bitmap.LockBits(colorBitmapRectangle, ImageLockMode.WriteOnly, bitmap.PixelFormat);
345

  
346
                result.WritePixels(colorBitmapInt32Rect, data.Scan0, data.Width * data.Height * bytesPerPixel, data.Stride);
347

  
348
                bitmap.UnlockBits(data);
349
            }
350
            catch (Exception ex)
351
            {
352
                //throw ex;
353
            }
354
            finally
355
            {
356
                bitmap.Dispose();
357
                bitmap = null;
358
                //GC.Collect(2);
359
            }
360

  
361
            return result;
362
        }
363
    
364
        /// <summary>
365
        /// 메모리 문제 발생
366
        /// </summary>
367
        /// <param name="bitmap"></param>
368
        /// <returns></returns>
369
        public System.Windows.Media.Imaging.BitmapSource CreateBitmapSourceFromBitmap(Bitmap bitmap)
370
        {
371
            System.Windows.Media.Imaging.BitmapSource result = null;
372
            
373
            if (bitmap == null)
374
                throw new ArgumentNullException("bitmap");
375

  
376
            try
377
            {
378
                using (var hbitmap = new SafeHBitmapHandle(bitmap.GetHbitmap(), true))
379
                {
380

  
381
                    result = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
382
                        hbitmap.DangerousGetHandle(),
383
                        IntPtr.Zero,
384
                        System.Windows.Int32Rect.Empty,
385
                        System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
386

  
387
                   
388
                }
389
            }
390
            catch (Exception ex)
391
            {
392
                //throw ex;
393
            }
394
            finally
395
            {
396
                bitmap.Dispose();
397
                bitmap = null;
398
                //GC.Collect(2);
399
            }
400

  
401
            return result;
402
        }
403

  
404
        public async Task<List<System.Windows.Rect>> CompareReturnRectsAsync(string OriginalbitmapUri, string TargatBitmapUri, Size ResultRectSize)
405
        {
406
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
407

  
408
            Bitmap Originalbitmap = null;
409
            Bitmap TargatBitmap = null;
410

  
411
            try
412
            {
413

  
414
                Originalbitmap = LoadPicture(OriginalbitmapUri);
415
                TargatBitmap = LoadPicture(TargatBitmapUri);
416

  
417
                result = await CompareReturnRectsAsync(Originalbitmap, TargatBitmap, ResultRectSize);
418
            }
419
            catch (Exception)
420
            {
421
                throw;
422
            }
423
            finally
424
            {
425
                Originalbitmap.Dispose();
426
                TargatBitmap.Dispose();
427
            }
428

  
429
            return result;
430
        }
431

  
432
        /// <summary>
433
        /// 이미지를 비교 후 해당 영역을 Rect로 반환한다.
434
        /// </summary>
435
        /// <param name="Originalbitmap">원본 이미지</param>
436
        /// <param name="TargatBitmap">비교대상 이미지</param>
437
        /// <param name="ResultRectSize">반환되는 Rect의 사이즈</param>
438
        /// <returns></returns>
439
        public async Task<List<System.Windows.Rect>> CompareReturnRectsAsync(System.Drawing.Bitmap Originalbitmap, System.Drawing.Bitmap TargatBitmap, Size ResultRectSize)
440
        {
441
            List<System.Windows.Rect> result = new List<System.Windows.Rect>();
442

  
443
            try
444
            {
445
                byte[,,] data = MathchesImageData(Originalbitmap, TargatBitmap);
446

  
447
                result = await GetMatchPixelsAsnc(data, ResultRectSize);
448

  
449
                //result = JoinRectList(result);
450
                //if (result.Count() > 0)
451
                //{
452
                //    result = Merge(result, ResultRectSize.Height);
453
                //}
454

  
455
                data = null;
456
            }
457
            catch (Exception ex)
458
            {
459
                throw ex;
460
            }
461
            finally
462
            {
463
            }
464

  
465
            return result;
466
        }
467

  
468
       
469
        protected override void Dispose(bool disposing)
470
        {
471
            base.Dispose(disposing);
472
        }
473
    }
474
}
ImageComparer/Markus.ImageComparer.EMGU/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
            {
380
                OriginalImageData.Dispose();
381
            }
382

  
383
            if (TargatImageData != null)
384
            {
385
                TargatImageData.Dispose();
386
            }
387

  
388
            // TODO: 위의 종료자가 재정의된 경우 다음 코드 줄의 주석 처리를 제거합니다. 
389
            //  GC.SuppressFinalize(this);
390
            GC.Collect();
391
            GC.SuppressFinalize(this);
392
            GC.Collect();
393
        } 
394
        #endregion
395
    }
396
}
ImageComparer/Markus.ImageComparer.EMGU/ImageComparerBase.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.IO;
8
using System.Linq;
9
using System.Net;
10
using System.Text;
11
using System.Threading.Tasks;
12

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

  
20
        /// <summary>
21
        /// 이미지 비교에 사용되는 점수
22
        /// </summary>
23
        double gMatchScore = 0.9;
24

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

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

  
43
            if (bitmap.Size != newSize)
44
            {
45
                result = new Bitmap(newSize.Width, newSize.Height);
46

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

  
54
            return result;
55
        }
56

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

  
67
            try
68
            {
69
                // 원본이미지의 크키와 Format24bppRgb로 타켓 이미지를 변경
70
                // 크기가 틀린 경우 비교시 바이트배열 오류 발생
71
                // 이미지 포멧은 24bit이하로 emgu CV가 작동
72
                Originalbitmap = ChangeBitmapFormatAndSize(Originalbitmap, Originalbitmap.Size, PixelFormat.Format24bppRgb);
73
                TargatBitmap = ChangeBitmapFormatAndSize(TargatBitmap, Originalbitmap.Size, PixelFormat.Format24bppRgb);
74

  
75
                OriginalImageData = new Image<Bgr, Byte>(Originalbitmap);
76
                TargatImageData = new Image<Bgr, Byte>(TargatBitmap);
77

  
78
                //Computes absolute different between this image and the other image
79
                // 원본이미지와 타겟이미지를 처리
80
                var tmp = OriginalImageData.AbsDiff(TargatImageData);
81

  
82
                // 틀린부분을 반환
83
                var matches = tmp.Not();
84

  
85
                result = matches.Data;
86

  
87
                matches.Dispose();
88
                tmp.Dispose();
89
            }
90
            catch (Exception ex)
91
            {
92
                throw ex;
93
            }
94
            
95
            return result;
96
        }
97

  
98
        /// <summary>
99
        /// MathchesImageData의 틀린 부분을 Rect로 반환
100
        /// </summary>
101
        /// <param name="data"></param>
102
        /// <param name="currentX"></param>
103
        /// <param name="currentY"></param>
104
        /// <param name="ImageWidth"></param>
105
        /// <param name="ImageHeight"></param>
106
        /// <param name="block"></param>
107
        /// <returns></returns>
108
        protected System.Windows.Rect? DataMatchScore(byte[,,] data, int currentX, int currentY, int ImageWidth, int ImageHeight, Size block)
109
        {
110
            System.Windows.Rect? result = null;
111

  
112
            int x = currentX;
113
            int y = currentY;
114
            int width = ImageWidth;
115
            int height = ImageHeight;
116

  
117
            for (int i = 0; i < block.Width; i++)
118
            {
119
                int wi = x + i;
120
                if (wi >= width) break;
121

  
122
                for (int j = 0; j < block.Height; j++)
123
                {
124
                    int hj = y + j;
125
                    if (hj >= height) break;
126

  
127
                    double matchScore = data[wi, hj, 0];
128

  
129
                    if (matchScore < gMatchScore)
130
                    {
131
                        result = new System.Windows.Rect(y, x, block.Width, block.Height);
132
                        return result;
133
                    }
134
                }
135
            }
136

  
137
            return result;
138
        }
139

  
140
        /// <summary>
141
        /// Image<TColor, TDepth>의 틀린 부분을 Rect로 반환
142
        /// </summary>
143
        /// <param name="data"></param>
144
        /// <param name="block"></param>
145
        /// <returns></returns>
146
        protected List<System.Windows.Rect> GetMatchPixels(byte[,,] data, Size block)
147
        {
... 이 차이점은 표시할 수 있는 최대 줄수를 초과해서 이 차이점은 잘렸습니다.

내보내기 Unified diff

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