Author: Slipy90
(2011/10/27 12:31) 7 months ago
GUI ÁTALAKÍTÁS ELŐTT II.
41
set { ImageFunction.thresholdHighValue = value; }
42
}
43
44
public static Image<Gray, Byte> BinarizeHSV(Image<Bgr, Byte> srcImage, byte thresholdVal)
public static Image<Gray, Byte> Binarize(Image<Bgr, Byte> srcImage, byte thresholdVal)
45
{
46
Image<Gray, Byte> dstImage = new Image<Gray, byte>(srcImage.Size);
47
48
Image<Luv, Byte> srcImageHSV = new Image<Luv, byte>(srcImage.Bitmap);
49
50
Image<Gray, Byte>[] channels = srcImageHSV.Split();
51
Image<Gray, Byte> imgSat = channels[1];
Image<Gray, Byte> imgMask = channels[1];
52
53
dstImage = imgSat
dstImage = imgMask
54
.ThresholdBinaryInv(new Gray(thresholdVal), new Gray(255))
55
.SmoothMedian(7)
56
//.Erode(1)
...
592
return new Image<Bgr, byte>(dstImage);
593
594
#endregion
595
596
597
public enum CameraMoveDirection
598
90
private void timerOriginal_Tick(object sender, EventArgs e)
91
92
// Élő képhez ez kell
93
capture.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_WIDTH, 1280);
//capture.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_WIDTH, 1280);
94
capture.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_HEIGHT, 720);
//capture.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_HEIGHT, 720);
95
captureFrame = capture.QueryFrame(); captureGrayFrame = capture.QueryGrayFrame();
//captureFrame = capture.QueryFrame(); captureGrayFrame = capture.QueryGrayFrame();
96
97
//if (firstDetect)
98
//{
108
histoForm.Image = captureGrayFrame;
109
110
111
//if (rBtnThresholdSimple.Checked)
imgBinarized = ImageFunction.Binarize(captureFrame, 152);
112
// imgBinarized = ImageFunction.BinarizeSimple(captureGrayFrame);
picBoxCamBinarized.Image = captureFrame.Or(imgBinarized.Convert<Bgr, Byte>());
113
//else if (rBtnThresholdDouble.Checked)
114
// imgBinarized = ImageFunction.BinarizeDouble(captureGrayFrame);
115
//else if (rBtnThresholdOtsu.Checked)
116
// imgBinarized = ImageFunction.BinarizeOtsu(captureGrayFrame);
117
118
//picBoxCamBinarized.Image = imgBinarized;
119
120
imgBinarized = ImageFunction.BinarizeHSV(captureFrame, 152);
121
picBoxCamBinarized.Image = imgBinarized;
122
123
//imgCannyEdgeDetected = ImageFunction.Canny(captureGrayFrame);
124
//if (numUpDownDilateIter.Value > 0 && numUpDownErodeIter.Value == 0)
125
212
picBoxCamOriginal.Image = captureFrame;
203
213
//firstCenterPoint = true;
204
214
205
215
216
//picBoxCamBinarized.Image = ImageFunction.GetCorners(captureGrayFrame);
217
//try
218
219
// //rawContours = ImageFunction.GetContours(imgCannyEdgeDetected, true, .5);
220
// PuzzleFunction.Cut(captureFrame, rawContours);
221
//}
222
//catch (ArgumentException ex)
223
224
// ErrorMessage(ex.Message);
225
226
227
//lbPuzzlePieces.DataSource = PuzzleFunction.PuzzlePieces.ToArray();
228
//picBoxCamOriginal.Image = captureFrame;
229
230
231
206
232
207
233
208
366
for (int i = 0; i < currPiece.Sides.Count; i++)
341
367
342
368
if (i == 0)
343
369
tmp.Draw(new CircleF(currPiece.Sides[i].Corners[0], 3), new Bgr(0, 255, 0), 1);
344
tmp.Draw(new CircleF(currPiece.Sides[i].Corners[0], 5), new Bgr(0, 255, 0), -1);
370
if (i == 1)
345
371
tmp.Draw(new CircleF(currPiece.Sides[i].Corners[0], 3), new Bgr(255, 0, 0), 1);
346
tmp.Draw(new CircleF(currPiece.Sides[i].Corners[0], 5), new Bgr(255, 0, 0), -1);
372
if (i == 2)
347
373
tmp.Draw(new CircleF(currPiece.Sides[i].Corners[0], 3), new Bgr(0, 0, 255), 1);
348
tmp.Draw(new CircleF(currPiece.Sides[i].Corners[0], 5), new Bgr(0, 0, 255), -1);
374
if (i == 3)
349
375
tmp.Draw(new CircleF(currPiece.Sides[i].Corners[0], 3), new Bgr(255, 255, 0), 1);
350
tmp.Draw(new CircleF(currPiece.Sides[i].Corners[0], 5), new Bgr(255, 255, 0), -1);
376
351
377
picBoxPuzzlePiece.Image = tmp;
352
picBoxCannyEdge.Image = tmp;
378
353
379
//picBoxCannyEdge.Image = PuzzlePiece.GenerateSignatureImage(currPiece.Signature);
354
380
355
34
this.kilépésToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
35
this.menuHisztogram = new System.Windows.Forms.ToolStripMenuItem();
36
this.statusStrip = new System.Windows.Forms.StatusStrip();
37
this.picBoxCannyEdge = new Emgu.CV.UI.ImageBox();
38
this.timerOriginal = new System.Windows.Forms.Timer(this.components);
39
this.groupBox1 = new System.Windows.Forms.GroupBox();
40
this.btnDetect = new System.Windows.Forms.Button();
this.picBoxCamOriginal = new Emgu.CV.UI.ImageBox();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.groupBox4 = new System.Windows.Forms.GroupBox();
this.labThresholdValHigh = new System.Windows.Forms.Label();
this.numUpDownThresholdHigh = new System.Windows.Forms.NumericUpDown();
this.labThresholdValLow = new System.Windows.Forms.Label();
this.numUpDownThresholdLow = new System.Windows.Forms.NumericUpDown();
this.groupBox3 = new System.Windows.Forms.GroupBox();
this.rBtnThresholdOtsu = new System.Windows.Forms.RadioButton();
this.rBtnThresholdDouble = new System.Windows.Forms.RadioButton();
this.rBtnThresholdSimple = new System.Windows.Forms.RadioButton();
this.picBoxCamBinarized = new Emgu.CV.UI.ImageBox();
this.groupBox5 = new System.Windows.Forms.GroupBox();
this.label3 = new System.Windows.Forms.Label();
this.numericUpDown1 = new System.Windows.Forms.NumericUpDown();
57
this.groupBox6 = new System.Windows.Forms.GroupBox();
58
this.numUpDownErodeIter = new System.Windows.Forms.NumericUpDown();
59
this.numUpDownDilateIter = new System.Windows.Forms.NumericUpDown();
60
this.label2 = new System.Windows.Forms.Label();
61
this.label1 = new System.Windows.Forms.Label();
62
this.gBoxPuzzlePieces = new System.Windows.Forms.GroupBox();
63
this.txtPuzzleSideType = new System.Windows.Forms.TextBox();
64
this.label4 = new System.Windows.Forms.Label();
68
this.btnAssembling = new System.Windows.Forms.Button();
69
this.label5 = new System.Windows.Forms.Label();
70
this.labCamMoveDirection = new System.Windows.Forms.Label();
this.histogram = new Emgu.CV.UI.HistogramBox();
71
this.labTeszt = new System.Windows.Forms.Label();
72
65
66
67
73
this.menuStrip.SuspendLayout();
74
((System.ComponentModel.ISupportInitialize)(this.picBoxCannyEdge)).BeginInit();
75
this.groupBox1.SuspendLayout();
76
((System.ComponentModel.ISupportInitialize)(this.picBoxCamOriginal)).BeginInit();
77
this.groupBox2.SuspendLayout();
78
this.groupBox4.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.numUpDownThresholdLow)).BeginInit();
79
((System.ComponentModel.ISupportInitialize)(this.picBoxCamBinarized)).BeginInit();
80
this.gBoxPuzzlePieces.SuspendLayout();
81
((System.ComponentModel.ISupportInitialize)(this.picBoxPuzzlePiece)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.numUpDownThresholdHigh)).BeginInit();
82
this.groupBox3.SuspendLayout();
83
84
this.groupBox5.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();
85
this.groupBox6.SuspendLayout();
86
((System.ComponentModel.ISupportInitialize)(this.numUpDownDilateIter)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.numUpDownErodeIter)).BeginInit();
87
88
89
this.SuspendLayout();
//
// menuStrip
131
this.statusStrip.TabIndex = 6;
132
this.statusStrip.Text = "statusStrip1";
133
134
// picBoxCannyEdge
135
136
this.picBoxCannyEdge.Location = new System.Drawing.Point(6, 19);
137
this.picBoxCannyEdge.Name = "picBoxCannyEdge";
138
this.picBoxCannyEdge.Size = new System.Drawing.Size(309, 220);
139
this.picBoxCannyEdge.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
140
this.picBoxCannyEdge.TabIndex = 7;
141
this.picBoxCannyEdge.TabStop = false;
142
143
// timerOriginal
144
145
this.timerOriginal.Enabled = true;
this.groupBox4.TabStop = false;
this.groupBox4.Text = "Küszöb érték(ek)";
209
210
// labThresholdValHigh
this.labThresholdValHigh.AutoSize = true;
this.labThresholdValHigh.Location = new System.Drawing.Point(128, 21);
this.labThresholdValHigh.Name = "labThresholdValHigh";
this.labThresholdValHigh.Size = new System.Drawing.Size(35, 13);
this.labThresholdValHigh.TabIndex = 8;
this.labThresholdValHigh.Text = "Felső:";
this.labThresholdValHigh.Visible = false;
// numUpDownThresholdHigh
this.numUpDownThresholdHigh.Location = new System.Drawing.Point(172, 19);
this.numUpDownThresholdHigh.Maximum = new decimal(new int[] {
234
255,
235
0,
236
237
0});
238
this.numUpDownThresholdHigh.Name = "numUpDownThresholdHigh";
239
this.numUpDownThresholdHigh.Size = new System.Drawing.Size(40, 20);
240
this.numUpDownThresholdHigh.TabIndex = 9;
241
this.numUpDownThresholdHigh.Value = new decimal(new int[] {
242
100,
243
244
245
246
this.numUpDownThresholdHigh.Visible = false;
247
this.numUpDownThresholdHigh.ValueChanged += new System.EventHandler(this.numUpDownThresholdHigh_ValueChanged);
248
249
// labThresholdValLow
211
250
251
this.labThresholdValLow.AutoSize = true;
274
275
this.numUpDownThresholdLow.ValueChanged += new System.EventHandler(this.numUpDownThresholdLow_ValueChanged);
276
277
// groupBox3
278
279
this.groupBox3.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
280
| System.Windows.Forms.AnchorStyles.Right)));
281
this.groupBox3.Controls.Add(this.rBtnThresholdOtsu);
282
this.groupBox3.Controls.Add(this.rBtnThresholdDouble);
283
this.groupBox3.Controls.Add(this.rBtnThresholdSimple);
284
this.groupBox3.Location = new System.Drawing.Point(6, 245);
285
this.groupBox3.Name = "groupBox3";
286
this.groupBox3.Size = new System.Drawing.Size(309, 49);
287
this.groupBox3.TabIndex = 8;
288
this.groupBox3.TabStop = false;
289
this.groupBox3.Text = "Módszer";
290
291
// rBtnThresholdOtsu
292
293
this.rBtnThresholdOtsu.AutoSize = true;
294
this.rBtnThresholdOtsu.Checked = true;
295
this.rBtnThresholdOtsu.Location = new System.Drawing.Point(172, 19);
296
this.rBtnThresholdOtsu.Name = "rBtnThresholdOtsu";
297
this.rBtnThresholdOtsu.Size = new System.Drawing.Size(47, 17);
298
this.rBtnThresholdOtsu.TabIndex = 0;
299
this.rBtnThresholdOtsu.TabStop = true;
300
this.rBtnThresholdOtsu.Text = "Otsu";
301
this.rBtnThresholdOtsu.UseVisualStyleBackColor = true;
302
this.rBtnThresholdOtsu.CheckedChanged += new System.EventHandler(this.rBtnThresholdOtsu_CheckedChanged);
303
304
// rBtnThresholdDouble
305
306
this.rBtnThresholdDouble.AutoSize = true;
307
this.rBtnThresholdDouble.Location = new System.Drawing.Point(80, 19);
308
this.rBtnThresholdDouble.Name = "rBtnThresholdDouble";
309
this.rBtnThresholdDouble.Size = new System.Drawing.Size(86, 17);
310
this.rBtnThresholdDouble.TabIndex = 0;
311
this.rBtnThresholdDouble.Text = "Hiszterézises";
312
this.rBtnThresholdDouble.UseVisualStyleBackColor = true;
313
this.rBtnThresholdDouble.CheckedChanged += new System.EventHandler(this.rBtnThresholdDouble_CheckedChanged);
314
315
// rBtnThresholdSimple
316
317
this.rBtnThresholdSimple.AutoSize = true;
318
this.rBtnThresholdSimple.Location = new System.Drawing.Point(6, 19);
319
this.rBtnThresholdSimple.Name = "rBtnThresholdSimple";
320
this.rBtnThresholdSimple.Size = new System.Drawing.Size(68, 17);
321
this.rBtnThresholdSimple.TabIndex = 0;
322
this.rBtnThresholdSimple.Text = "Egyszerű";
323
this.rBtnThresholdSimple.UseVisualStyleBackColor = true;
324
this.rBtnThresholdSimple.CheckedChanged += new System.EventHandler(this.rBtnThresholdSimple_CheckedChanged);
325
326
// picBoxCamBinarized
327
328
this.picBoxCamBinarized.Location = new System.Drawing.Point(6, 19);
332
this.picBoxCamBinarized.TabIndex = 5;
333
this.picBoxCamBinarized.TabStop = false;
334
335
// groupBox5
336
337
this.groupBox5.Controls.Add(this.label3);
338
this.groupBox5.Controls.Add(this.numericUpDown1);
339
this.groupBox5.Controls.Add(this.groupBox6);
340
this.groupBox5.Controls.Add(this.picBoxCannyEdge);
this.groupBox5.Location = new System.Drawing.Point(666, 28);
this.groupBox5.Name = "groupBox5";
this.groupBox5.Size = new System.Drawing.Size(320, 357);
this.groupBox5.TabIndex = 11;
this.groupBox5.TabStop = false;
this.groupBox5.Text = "Éldetektált kép";
// label3
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(12, 317);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(179, 13);
this.label3.TabIndex = 10;
this.label3.Text = "A puzzle darab %os aránya a képen:";
356
357
// numericUpDown1
358
359
this.numericUpDown1.Location = new System.Drawing.Point(197, 315);
360
this.numericUpDown1.Name = "numericUpDown1";
361
this.numericUpDown1.Size = new System.Drawing.Size(40, 20);
362
this.numericUpDown1.TabIndex = 11;
363
this.numericUpDown1.Value = new decimal(new int[] {
364
80,
365
// groupBox6
this.groupBox6.Controls.Add(this.numUpDownErodeIter);
this.groupBox6.Controls.Add(this.numUpDownDilateIter);
this.groupBox6.Controls.Add(this.label2);
this.groupBox6.Controls.Add(this.label1);
this.groupBox6.Location = new System.Drawing.Point(6, 245);
this.groupBox6.Name = "groupBox6";
this.groupBox6.Size = new System.Drawing.Size(308, 49);
this.groupBox6.TabIndex = 9;
this.groupBox6.TabStop = false;
this.groupBox6.Text = "Dialtáció/Erózió iterációk száma";
381
382
// numUpDownErodeIter
383
384
this.numUpDownErodeIter.Location = new System.Drawing.Point(178, 19);
385
this.numUpDownErodeIter.Maximum = new decimal(new int[] {
386
1000,
387
388
389
390
this.numUpDownErodeIter.Name = "numUpDownErodeIter";
391
this.numUpDownErodeIter.Size = new System.Drawing.Size(40, 20);
392
this.numUpDownErodeIter.TabIndex = 10;
393
this.numUpDownErodeIter.ValueChanged += new System.EventHandler(this.numUpDownErodeIter_ValueChanged);
394
395
// numUpDownDilateIter
396
397
this.numUpDownDilateIter.Location = new System.Drawing.Point(63, 19);
398
this.numUpDownDilateIter.Maximum = new decimal(new int[] {
399
400
401
402
403
this.numUpDownDilateIter.Name = "numUpDownDilateIter";
404
this.numUpDownDilateIter.Size = new System.Drawing.Size(40, 20);
405
this.numUpDownDilateIter.TabIndex = 10;
406
this.numUpDownDilateIter.Value = new decimal(new int[] {
407
1,
408
409
410
411
this.numUpDownDilateIter.ValueChanged += new System.EventHandler(this.numUpDownDilateIter_ValueChanged);
412
413
// label2
414
415
this.label2.AutoSize = true;
416
this.label2.Location = new System.Drawing.Point(121, 21);
417
this.label2.Name = "label2";
418
this.label2.Size = new System.Drawing.Size(39, 13);
419
this.label2.TabIndex = 7;
420
this.label2.Text = "Erózió:";
421
this.label2.TextAlign = System.Drawing.ContentAlignment.TopRight;
422
423
// label1
424
425
this.label1.AutoSize = true;
426
this.label1.Location = new System.Drawing.Point(6, 21);
427
this.label1.Name = "label1";
428
this.label1.Size = new System.Drawing.Size(51, 13);
429
this.label1.TabIndex = 7;
430
this.label1.Text = "Dilatáció:";
431
this.label1.TextAlign = System.Drawing.ContentAlignment.TopRight;
432
433
// gBoxPuzzlePieces
434
435
this.gBoxPuzzlePieces.Controls.Add(this.txtPuzzleSideType);
517
this.labCamMoveDirection.TabIndex = 16;
518
this.labCamMoveDirection.Text = "-";
519
// histogram
this.histogram.Location = new System.Drawing.Point(339, 406);
this.histogram.Name = "histogram";
this.histogram.Size = new System.Drawing.Size(647, 225);
this.histogram.TabIndex = 14;
520
// labTeszt
521
522
this.labTeszt.AutoSize = true;
526
this.labTeszt.TabIndex = 16;
527
this.labTeszt.Text = "-";
528
529
530
531
532
533
534
436
535
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
523
524
525
536
// MainForm
537
538
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
555
this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
556
this.menuStrip.ResumeLayout(false);
557
this.menuStrip.PerformLayout();
558
((System.ComponentModel.ISupportInitialize)(this.picBoxCannyEdge)).EndInit();
559
this.groupBox1.ResumeLayout(false);
560
((System.ComponentModel.ISupportInitialize)(this.picBoxCamOriginal)).EndInit();
561
this.groupBox2.ResumeLayout(false);
562
this.groupBox4.ResumeLayout(false);
563
this.groupBox4.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.numUpDownThresholdLow)).EndInit();
564
((System.ComponentModel.ISupportInitialize)(this.picBoxCamBinarized)).EndInit();
565
this.gBoxPuzzlePieces.ResumeLayout(false);
566
this.gBoxPuzzlePieces.PerformLayout();
567
((System.ComponentModel.ISupportInitialize)(this.picBoxPuzzlePiece)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.numUpDownThresholdHigh)).EndInit();
568
this.groupBox3.ResumeLayout(false);
569
this.groupBox3.PerformLayout();
570
571
this.groupBox5.ResumeLayout(false);
this.groupBox5.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit();
572
this.groupBox6.ResumeLayout(false);
573
this.groupBox6.PerformLayout();
574
((System.ComponentModel.ISupportInitialize)(this.numUpDownDilateIter)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.numUpDownErodeIter)).EndInit();
575
576
577
578
579
this.ResumeLayout(false);
580
this.PerformLayout();
581
586
private System.Windows.Forms.MenuStrip menuStrip;
587
private System.Windows.Forms.ToolStripMenuItem menuFile;
588
private System.Windows.Forms.ToolStripMenuItem kilépésToolStripMenuItem;
589
private System.Windows.Forms.StatusStrip statusStrip;
590
private Emgu.CV.UI.ImageBox picBoxCannyEdge;
591
private System.Windows.Forms.Timer timerOriginal;
private System.Windows.Forms.GroupBox groupBox1;
private Emgu.CV.UI.ImageBox picBoxCamOriginal;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.GroupBox groupBox4;
private System.Windows.Forms.Label labThresholdValHigh;
private System.Windows.Forms.NumericUpDown numUpDownThresholdHigh;
private System.Windows.Forms.Label labThresholdValLow;
599
private System.Windows.Forms.NumericUpDown numUpDownThresholdLow;
600
private System.Windows.Forms.GroupBox groupBox3;
private Emgu.CV.UI.ImageBox picBoxCamBinarized;
601
private System.Windows.Forms.RadioButton rBtnThresholdOtsu;
602
private System.Windows.Forms.RadioButton rBtnThresholdDouble;
603
private System.Windows.Forms.RadioButton rBtnThresholdSimple;
604
605
private System.Windows.Forms.GroupBox groupBox5;
606
private System.Windows.Forms.GroupBox groupBox6;
607
private System.Windows.Forms.NumericUpDown numUpDownErodeIter;
608
private System.Windows.Forms.NumericUpDown numUpDownDilateIter;
609
private System.Windows.Forms.Label label2;
610
private System.Windows.Forms.Label label1;
611
private System.Windows.Forms.Label label3;
612
private System.Windows.Forms.NumericUpDown numericUpDown1;
613
private System.Windows.Forms.ToolStripMenuItem menuHisztogram;
614
private System.Windows.Forms.GroupBox gBoxPuzzlePieces;
615
private System.Windows.Forms.ListBox lbPuzzlePieces;
622
private System.Windows.Forms.Button btnAssembling;
623
private System.Windows.Forms.Label label5;
624
private System.Windows.Forms.Label labCamMoveDirection;
private Emgu.CV.UI.HistogramBox histogram;
616
625
private System.Windows.Forms.Label labTeszt;
617
626
618
619
620
621
627
628
629
30
D:\BMF\JPS\trunk\JPS_PuzzleDetectorWithCam\JPS_PuzzleDetectorWithCam\bin\Debug\JPS_PuzzleDetectorWithCam.exe
31
D:\BMF\JPS\trunk\JPS_PuzzleDetectorWithCam\JPS_PuzzleDetectorWithCam\bin\Debug\JPS_PuzzleDetectorWithCam.pdb
32
D:\BMF\JPS\trunk\JPS_PuzzleDetectorWithCam\JPS_PuzzleDetectorWithCam\bin\Debug\ZedGraph.dll
33
D:\BMF\JPS\trunk\JPS_PuzzleDetectorWithCam\JPS_PuzzleDetectorWithCam\bin\Debug\Emgu.CV.xml
D:\BMF\JPS\trunk\JPS_PuzzleDetectorWithCam\JPS_PuzzleDetectorWithCam\bin\Debug\Emgu.CV.UI.xml
D:\BMF\JPS\trunk\JPS_PuzzleDetectorWithCam\JPS_PuzzleDetectorWithCam\bin\Debug\Emgu.Util.xml
E:\BMF\JPS\trunk\JPS_PuzzleDetectorWithCam\JPS_PuzzleDetectorWithCam\obj\x86\Debug\JPS_PuzzleDetectorWithCam.HistogramForm.resources
D:\BMF\JPS\trunk\JPS_PuzzleDetectorWithCam\JPS_PuzzleDetectorWithCam\obj\x86\Debug\JPS_PuzzleDetectorWithCam.HistogramForm.resources
D:\svn\trunk\JPS_PuzzleDetectorWithCam\JPS_PuzzleDetectorWithCam\obj\x86\Debug\JPS_PuzzleDetectorWithCam.exe
101
d:\BMF\JPS\trunk\JPS_PuzzleDetectorWithCam\JPS_PuzzleDetectorWithCam\bin\Debug\Accord.Statistics.xml
102
d:\BMF\JPS\trunk\JPS_PuzzleDetectorWithCam\JPS_PuzzleDetectorWithCam\bin\Debug\Accord.pdb
99
103
d:\BMF\JPS\trunk\JPS_PuzzleDetectorWithCam\JPS_PuzzleDetectorWithCam\bin\Debug\Accord.xml
100
D:\BMF\JPS\trunk\JPS_PuzzleDetectorWithCam\JPS_PuzzleDetectorWithCam\bin\Debug\ZedGraph.xml
8
using Emgu.CV.CvEnum;
9
using System.IO;
10
using System.Diagnostics;
11
using System.Threading.Tasks;
12
namespace JPS_PuzzleDetectorWithCam
13
14
public static void Cut(Image<Bgr, Byte> srcImage, List<CustomContour> contours)
ClearPuzzlePieces();
for (int i = 0; i < contours.Count; i++)
Stopwatch sw = new Stopwatch();
sw.Restart();
MCvBox2D minAreaRect = contours[i].OriginalContour.GetMinAreaRect();
minAreaRect.size = new SizeF((int)(minAreaRect.size.Width*1.5), (int)(minAreaRect.size.Height*1.5));
minAreaRect.size = new SizeF((int)(minAreaRect.size.Width * 1.5), (int)(minAreaRect.size.Height * 1.5));
Image<Bgr, Byte> imgCurrPiece = new Image<Bgr, byte>(
new Size((int)minAreaRect.size.Width, (int)minAreaRect.size.Height)
new PuzzlePiece(imgCurrPiece, puzzleCounter++.ToString(), contours[i].CenterOfMass)
);
catch (Exception)
catch (Exception ex)
if (puzzlePieces.Count > 1)
System.Windows.Forms.MessageBox.Show(ex.Message);
//if (puzzlePieces.Count > 1)
puzzlePieces.Remove(puzzlePieces.Last());
puzzleCounter--;
// puzzlePieces.Remove(puzzlePieces.Last());
// puzzleCounter--;
else
//else
// ClearPuzzlePieces();
//throw ex;
sw.Stop();
public static List<Point> GetCorners(Image<Bgr, Byte> imgPiece, CustomContour contour)
public static List<Point> GetCorners(Image<Bgr, Byte> imgPiece, CustomContour contour, List<MCvConvexityDefect> realConvexityDefects)
List<Point> corners = new List<Point>();
104
Image<Bgr, Byte> tmpImage = new Image<Bgr, byte>(imgPiece.Bitmap);
105
using (Image<Gray, Byte> imgConvexHull = new Image<Gray, byte>(imgPiece.Size))
106
MCvBox2D minAreaRect = contour.OriginalContour.GetMinAreaRect();
107
using (MemStorage memStorage = new MemStorage())
imgConvexHull.Draw(contour.OriginalContour.GetConvexHull(ORIENTATION.CV_CLOCKWISE), new Gray(255), 1);
double minAreaRectArea = minAreaRect.size.Width * minAreaRect.size.Height;
corners = CornersFromConvexityDefects(contour.ConvexityDefects);
int diff = (int)(minAreaRectArea - contour.ConvexHull.Area);
tmpImage = new Image<Bgr, byte>(imgPiece.Size);
tmpImage.Draw(minAreaRect, new Bgr(System.Drawing.Color.Aqua), -1);
tmpImage.Draw(contour.OriginalContour.GetConvexHull(ORIENTATION.CV_CLOCKWISE), new Bgr(System.Drawing.Color.Beige), -1);
tmpImage.Draw(contour.OriginalContour, new Bgr(System.Drawing.Color.Purple), -1);
//SetRealConvexityDefects(contour.ConvexityDefects, contour.CenterOfMass);
if (diff < minAreaRectArea * 0.1)
corners = CornersFromNonOutboundedPieces(minAreaRect, contour);
126
127
corners = CornersFromConvexityDefects(contour, realConvexityDefects, ImageFunction.Binarize(imgPiece, 152));
128
129
130
Parallel.For(0, corners.Count, i => {
tmpImage.Draw(new CircleF(corners[i], 3), new Bgr(0, 0, 255), -1);
});
imgConvexHull.Draw(contour.OriginalContour, new Gray(255), 1);
if (corners.Count != 4)
PointF[][] goodFeatures = imgConvexHull.GoodFeaturesToTrack(10, .1, imgConvexHull.Width / 3, 5);
imgConvexHull.FindCornerSubPix(goodFeatures, new Size(5, 5), new Size(-1, -1), new MCvTermCriteria(100));
List<Point> minAreaRectCorners = new List<Point>();
minAreaRectCorners.Add(new Point(
(int)minAreaRect.center.X - (int)minAreaRect.size.Width / 2,
(int)minAreaRect.center.Y - (int)minAreaRect.size.Height / 2));
146
147
(int)minAreaRect.center.Y + (int)minAreaRect.size.Height / 2));
148
149
(int)minAreaRect.center.X + (int)minAreaRect.size.Width / 2,
150
151
152
153
154
List<PointF> usefulGoodFeatures = goodFeatures[0].ToList();
155
List<Point> nearestCorners = new List<Point>();
156
for (int i = 0; i < corners.Count; i++)
157
Parallel.For(0, corners.Count, i =>
158
tmpImage.Draw(new CircleF(corners[i], 3), new Bgr(0,255,255), -1);
159
List<int> distOfCorners = new List<int>();
160
for (int j = 0; j < minAreaRectCorners.Count; j++)
161
162
distOfCorners.Add(
163
(corners[i].X - minAreaRectCorners[j].X) * (corners[i].X - minAreaRectCorners[j].X) +
164
(corners[i].Y - minAreaRectCorners[j].Y) * (corners[i].Y - minAreaRectCorners[j].Y)
165
166
167
nearestCorners.Add(minAreaRectCorners[distOfCorners.IndexOf(distOfCorners.Min())]);
168
169
170
for (int i = 0; i < nearestCorners.Count; i++)
171
172
minAreaRectCorners.Remove(nearestCorners[i]);
173
174
double range = 5.0;
175
PointF[][] goodFeatures = imgConvexHull.GoodFeaturesToTrack(30, .1, 10, 5);
176
//imgConvexHull.FindCornerSubPix(goodFeatures, new Size(5, 5), new Size(-1, -1), new MCvTermCriteria(100));
177
178
179
180
Parallel.For(0, usefulGoodFeatures.Count, i =>
181
for (int j = 0; j < goodFeatures[0].Count(); j++)
182
tmpImage.Draw(new CircleF(usefulGoodFeatures[i], 1), new Bgr(0, 255, 0), -1);
183
tmpImage.Draw(new CircleF(goodFeatures[0][j], 3), new Bgr(0, 0, 255), -1);
if (goodFeatures[0][j].X > corners[i].X - range && goodFeatures[0][j].X < corners[i].X + range &&
goodFeatures[0][j].Y > corners[i].Y - range && goodFeatures[0][j].Y < corners[i].Y + range)
usefulGoodFeatures.Remove(goodFeatures[0][j]);
184
range = 1.0;
185
List<int> distances = new List<int>();
List<Point> tmpUsefulCorners = new List<Point>();
List<Point> contourPoints = contour.GetUnsortedContourPoints();
186
187
List<Point> nearestContourPoints;
188
Point usefulGoodFeature;
189
int range = 3;
190
tmpImage = new Image<Bgr, byte>(imgPiece.Bitmap);
191
for (int i = 0; i < minAreaRectCorners.Count; i++)
192
193
distances = new List<int>();
194
for (int j = 0; j < usefulGoodFeatures.Count; j++)
195
196
distances.Add(
197
(minAreaRectCorners[i].X - (int)usefulGoodFeatures[j].X) * (minAreaRectCorners[i].X - (int)usefulGoodFeatures[j].X) +
198
(minAreaRectCorners[i].Y - (int)usefulGoodFeatures[j].Y) * (minAreaRectCorners[i].Y - (int)usefulGoodFeatures[j].Y)
199
200
201
for (int i = 0; i < usefulGoodFeatures.Count; i++)
202
nearestContourPoints = new List<Point>();
usefulGoodFeature = Point.Round(usefulGoodFeatures[distances.IndexOf(distances.Min())]);
for (int j = 0; j < contourPoints.Count; j++)
if (usefulGoodFeatures[i].X > contourPoints[j].X - range && usefulGoodFeatures[i].X < contourPoints[j].X + range &&
if (usefulGoodFeature.X > contourPoints[j].X - range &&
usefulGoodFeatures[i].Y > contourPoints[j].Y - range && usefulGoodFeatures[i].Y < contourPoints[j].Y + range)
usefulGoodFeature.X < contourPoints[j].X + range &&
usefulGoodFeature.Y > contourPoints[j].Y - range &&
usefulGoodFeature.Y < contourPoints[j].Y + range)
tmpUsefulCorners.Add(contourPoints[j]);
//corners.Add(contourPoints[k]);
tmpImage.Draw(new CircleF(contourPoints[j], 3), new Bgr(0, 0, 255), 1);
//tmpImage.Draw(new CircleF(contourPoints[k], 3), new Bgr(System.Drawing.Color.Yellow), 1);
nearestContourPoints.Add(contourPoints[j]);
int currDistance = 0;
List<Point> usefulCorners = new List<Point>();
for (int j = 0; j < nearestContourPoints.Count; j++)
usefulCorners.AddRange(tmpUsefulCorners);
for (int i = 0; i < tmpUsefulCorners.Count - 1; i++)
currDistance =
(tmpUsefulCorners[i].X - tmpUsefulCorners[i + 1].X) * (tmpUsefulCorners[i].X - tmpUsefulCorners[i + 1].X) +
(tmpUsefulCorners[i].Y - tmpUsefulCorners[i + 1].Y) * (tmpUsefulCorners[i].Y - tmpUsefulCorners[i + 1].Y);
if (currDistance < 10)
usefulCorners.Remove(tmpUsefulCorners[i]);
tmpImage.Draw(new CircleF(tmpUsefulCorners[i + 1], 5), new Bgr(0, 255, 255), 1);
(nearestContourPoints[i].X - (int)usefulGoodFeature.X) * (nearestContourPoints[i].X - (int)usefulGoodFeature.X) +
(nearestContourPoints[i].Y - (int)usefulGoodFeature.Y) * (nearestContourPoints[i].Y - (int)usefulGoodFeature.Y)
corners.Add(nearestContourPoints[distances.IndexOf(distances.Min())]);
tmpImage.Draw(new CircleF(corners.Last(), 3), new Bgr(System.Drawing.Color.Yellow), 1);
tmpImage.Draw(new CircleF(corners[0], 3), new Bgr(0, 255, 0), 1);
tmpImage.Draw(new CircleF(corners[1], 3), new Bgr(0, 255, 0), 1);
if (usefulCorners.Count > 2)
//for (int i = 0; i < nearestGoodFeatures.Count; i++)
// tmpImage.Draw(new CircleF(nearestGoodFeatures[i], 1), new Bgr(255, 255, 255), -1);
tmpImage.Draw(contour.OriginalContour, new Bgr(System.Drawing.Color.DarkOrange), 1);
//double range = 5.0;
for (int i = 0; i < usefulCorners.Count; i++)
//for (int i = 0; i < corners.Count; i++)
// for (int j = 0; j < goodFeatures[0].Count(); j++)
(corners[0].X - usefulCorners[i].X) * (corners[0].X - usefulCorners[i].X) +
// {
(corners[0].Y - usefulCorners[i].Y) * (corners[0].Y - usefulCorners[i].Y));
// tmpImage.Draw(new CircleF(goodFeatures[0][j], 3), new Bgr(0, 0, 255), -1);
// if (goodFeatures[0][j].X > corners[i].X - range && goodFeatures[0][j].X < corners[i].X + range &&
// goodFeatures[0][j].Y > corners[i].Y - range && goodFeatures[0][j].Y < corners[i].Y + range)
// usefulGoodFeatures.Remove(goodFeatures[0][j]);
// }
while (usefulCorners.Count != 2)
//range = 1.0;
//List<Point> tmpUsefulCorners = new List<Point>();
usefulCorners.RemoveAt(distances.IndexOf(distances.Min()));
252
//List<Point> contourPoints = contour.GetUnsortedContourPoints();
distances.Remove(distances.Min());
253
corners.AddRange(usefulCorners);
254
//tmpImage = new Image<Bgr, byte>(imgPiece.Bitmap);
255
256
//for (int i = 0; i < usefulGoodFeatures.Count; i++)
257
258
// for (int j = 0; j < contourPoints.Count; j++)
259
260
// if (usefulGoodFeatures[i].X > contourPoints[j].X - range && usefulGoodFeatures[i].X < contourPoints[j].X + range &&
261
// usefulGoodFeatures[i].Y > contourPoints[j].Y - range && usefulGoodFeatures[i].Y < contourPoints[j].Y + range)
262
263
// tmpUsefulCorners.Add(contourPoints[j]);
264
// tmpImage.Draw(new CircleF(contourPoints[j], 3), new Bgr(0, 0, 255), 1);
265
266
267
268
269
//int currDistance = 0;
270
//List<Point> usefulCorners = new List<Point>();
271
//usefulCorners.AddRange(tmpUsefulCorners);
272
//for (int i = 0; i < tmpUsefulCorners.Count - 1; i++)
273
// currDistance =
// (tmpUsefulCorners[i].X - tmpUsefulCorners[i + 1].X) * (tmpUsefulCorners[i].X - tmpUsefulCorners[i + 1].X) +
// (tmpUsefulCorners[i].Y - tmpUsefulCorners[i + 1].Y) * (tmpUsefulCorners[i].Y - tmpUsefulCorners[i + 1].Y);
// if (currDistance < 10)
// usefulCorners.Remove(tmpUsefulCorners[i]);
// tmpImage.Draw(new CircleF(tmpUsefulCorners[i + 1], 5), new Bgr(0, 255, 255), 1);
//tmpImage.Draw(new CircleF(corners[0], 3), new Bgr(0, 255, 0), 1);
//tmpImage.Draw(new CircleF(corners[1], 3), new Bgr(0, 255, 0), 1);
//if (usefulCorners.Count > 2)
// List<int> distances = new List<int>();
// for (int i = 0; i < usefulCorners.Count; i++)
// distances.Add(
// (corners[0].X - usefulCorners[i].X) * (corners[0].X - usefulCorners[i].X) +
// (corners[0].Y - usefulCorners[i].Y) * (corners[0].Y - usefulCorners[i].Y));
// while (usefulCorners.Count != 2)
// usefulCorners.RemoveAt(distances.IndexOf(distances.Min()));
// distances.Remove(distances.Min());
//corners.AddRange(usefulCorners);
return corners;
private static List<MCvConvexityDefect> realConvexityDefects = new List<MCvConvexityDefect>();
//private static List<MCvConvexityDefect> realConvexityDefects = new List<MCvConvexityDefect>();
private static List<Point> CornersFromConvexityDefects(List<MCvConvexityDefect> convexivityDefects)
//private static void SetRealConvexityDefects(List<MCvConvexityDefect> convexityDefects, Point centerOfMass)
// float avgOfDepths = 0;
// for (int i = 0; i < convexityDefects.Count; i++)
// avgOfDepths += convexityDefects[i].Depth;
// avgOfDepths /= convexityDefects.Count;
// realConvexityDefects = new List<MCvConvexityDefect>();
// foreach (MCvConvexityDefect defect in convexityDefects)
// if (defect.Depth > avgOfDepths)
// realConvexityDefects.Add(defect);
329
private static List<Point> CornersFromConvexityDefects(CustomContour contour, List<MCvConvexityDefect> realConvexityDefects, Image<Gray, Byte> currPiece)
330
331
List<MCvConvexityDefect> convexivityDefects = contour.ConvexityDefects;
Point centerOfMass = contour.CenterOfMass;
List<Point> cornerPoints = new List<Point>();
float avgOfDepths = 0;
//float avgOfDepths = 0;
for (int i = 0; i < convexivityDefects.Count; i++)
//for (int i = 0; i < convexivityDefects.Count; i++)
avgOfDepths += convexivityDefects[i].Depth;
// avgOfDepths += convexivityDefects[i].Depth;
avgOfDepths /= convexivityDefects.Count;
//avgOfDepths /= convexivityDefects.Count;
List<MCvConvexityDefect> goodConvexivityDefects = new List<MCvConvexityDefect>();
//List<MCvConvexityDefect> goodConvexivityDefects = new List<MCvConvexityDefect>();
//Image<Bgr, Byte> tmpImage = new Image<Bgr, byte>(currPiece.ImgThresholdedPiece.Bitmap);
List<Point> possibleCornerPoints = new List<Point>();
foreach (MCvConvexityDefect defect in convexivityDefects)
if (defect.Depth > avgOfDepths)
goodConvexivityDefects.Add(defect);
//tmpImage.Draw(new CircleF(defect.StartPoint, 3), new Bgr(255, 0, 0), 1);
//tmpImage.Draw(new CircleF(defect.DepthPoint, 3), new Bgr(0, 255, 0), 1);
//tmpImage.Draw(new CircleF(defect.EndPoint, 3), new Bgr(0, 0, 255), 1);
realConvexityDefects = goodConvexivityDefects;
Image<Bgr, Byte> tmpImage = new Image<Bgr, byte>(currPiece.Bitmap);
tmpImage.Draw(new Cross2DF(centerOfMass, 5,5), new Bgr(0,255,0), 1);
avgOfDepths = 0;
List<double> distancesOfCenterToDepths = new List<double>();
for (int i = 0; i < goodConvexivityDefects.Count; i++)
avgOfDepths += goodConvexivityDefects[i].Depth;
avgOfDepths /= goodConvexivityDefects.Count;
//avgOfDepths += 1;
foreach (MCvConvexityDefect defect in realConvexityDefects)
//avgOfDepths = (float)Math.Ceiling(avgOfDepths);
List<double> avgDevOfDepts = new List<double>();
double currDev = 0;
double avgOfDev = 0;
currDev = avgOfDepths - goodConvexivityDefects[i].Depth;
distancesOfCenterToDepths.Add(
avgDevOfDepts.Add(currDev);
(centerOfMass.X - defect.DepthPoint.X) * (centerOfMass.X - (int)defect.DepthPoint.X) +
avgOfDev += Math.Abs(currDev);
(centerOfMass.Y - defect.DepthPoint.Y) * (centerOfMass.Y - (int)defect.DepthPoint.Y)
tmpImage.Draw(new CircleF(defect.StartPoint, 3), new Bgr(255, 0, 0), 1);
tmpImage.Draw(new CircleF(defect.DepthPoint, 3), new Bgr(0, 255, 0), 1);
tmpImage.Draw(new CircleF(defect.EndPoint, 3), new Bgr(0, 0, 255), 1);
avgOfDev /= goodConvexivityDefects.Count;
avgOfDev *= -1;
double avgOfCenterToDepth = distancesOfCenterToDepths.Average() * 0.85;
//tmpImage = new Image<Bgr, byte>(currPiece.ImgThresholdedPiece.Bitmap);
for (int i = 0; i < realConvexityDefects.Count; i++)
if (avgDevOfDepts[i] > avgOfDev && goodConvexivityDefects[i].Depth < avgOfDepths * 1.12)
if (distancesOfCenterToDepths[i] > avgOfCenterToDepth)
possibleCornerPoints.Add(goodConvexivityDefects[i].StartPoint);
//good convexity defects-be kell ezeket betenni!!!
possibleCornerPoints.Add(goodConvexivityDefects[i].EndPoint);
//realConvexityDefects.Add(goodConvexivityDefects[i]);
possibleCornerPoints.Add(realConvexityDefects[i].StartPoint);
//tmpImage.Draw(new CircleF(goodConvexivityDefects[i].StartPoint, 3), new Bgr(255, 0, 0), 1);
possibleCornerPoints.Add(realConvexityDefects[i].DepthPoint);
//tmpImage.Draw(new CircleF(goodConvexivityDefects[i].EndPoint, 3), new Bgr(0, 255, 0), 1);
possibleCornerPoints.Add(realConvexityDefects[i].EndPoint);
tmpImage.Draw(new CircleF(realConvexityDefects[i].DepthPoint, 3), new Bgr(0, 255, 0), -1);
List<double> distances = new List<double>();
//goodConvexivityDefects = realConvexityDefects;
for (int i = 0; i < possibleCornerPoints.Count; i++)
////realConvexityDefects = goodConvexivityDefects;
if (i == possibleCornerPoints.Count - 1)
distances.Add(Math.Floor(Math.Sqrt(
(possibleCornerPoints[i].X - possibleCornerPoints[0].X) * (possibleCornerPoints[i].X - possibleCornerPoints[0].X) +
(possibleCornerPoints[i].Y - possibleCornerPoints[0].Y) * (possibleCornerPoints[i].Y - possibleCornerPoints[0].Y))));
(possibleCornerPoints[i + 1].X - possibleCornerPoints[i].X) * (possibleCornerPoints[i + 1].X - possibleCornerPoints[i].X) +
(possibleCornerPoints[i + 1].Y - possibleCornerPoints[i].Y) * (possibleCornerPoints[i + 1].Y - possibleCornerPoints[i].Y))));
double avgOfDistances = distances.Average();
//avgOfDepths = 0;
//for (int i = 0; i < goodConvexivityDefects.Count; i++)
// avgOfDepths += goodConvexivityDefects[i].Depth;
//avgOfDepths /= goodConvexivityDefects.Count;
List<double> avgDevOfDistances = new List<double>();
////avgOfDepths += 1;
currDev = 0;
////avgOfDepths = (float)Math.Ceiling(avgOfDepths);
avgOfDev = 0;
//List<double> avgDevOfDepts = new List<double>();
for (int i = 0; i < distances.Count; i++)
//double currDev = 0;
//double avgOfDev = 0;
// currDev = avgOfDepths - goodConvexivityDefects[i].Depth;
// avgDevOfDepts.Add(currDev);
// avgOfDev += Math.Abs(currDev);
//avgOfDev /= goodConvexivityDefects.Count;
//avgOfDev *= -1;
//List<Point> possibleCornerPoints = new List<Point>();
//tmpImage = new Image<Bgr, byte>(currPiece.Bitmap);
// if (avgDevOfDepts[i] > avgOfDev * 1.05 && goodConvexivityDefects[i].Depth < avgOfDepths * 1.12)
// possibleCornerPoints.Add(goodConvexivityDefects[i].StartPoint);
// possibleCornerPoints.Add(goodConvexivityDefects[i].DepthPoint);
// possibleCornerPoints.Add(goodConvexivityDefects[i].EndPoint);
// tmpImage.Draw(new CircleF(goodConvexivityDefects[i].StartPoint, 3), new Bgr(255, 0, 0), 1);
// tmpImage.Draw(new CircleF(goodConvexivityDefects[i].DepthPoint, 3), new Bgr(0, 255, 0), 1);
// tmpImage.Draw(new CircleF(goodConvexivityDefects[i].EndPoint, 3), new Bgr(0, 0, 255), 1);
// !!Uj sarok kivalaszto algoritmus!!
#region sarok kivalasztas
double distA, distB = 0;
Point start, depth, end;
List<Point> goodCornerPoints = new List<Point>();
tmpImage = new Image<Bgr, byte>(currPiece.Bitmap);
for (int i = 0; i < possibleCornerPoints.Count; i += 3)
currDev = avgOfDistances - distances[i];
avgDevOfDistances.Add(currDev);
avgOfDev /= distances.Count;
// 3 fo pont felvetele az egyertelmuseg miatt
start = possibleCornerPoints[i];
depth = possibleCornerPoints[i + 1];
if (avgDevOfDistances[i] < avgOfDev)
end = possibleCornerPoints[i + 2];
tmpImage.Draw(new CircleF(start, 3), new Bgr(255, 0, 0), -1);
tmpImage.Draw(new CircleF(depth, 3), new Bgr(0, 255, 0), -1);
tmpImage.Draw(new CircleF(end, 3), new Bgr(0, 0, 255), -1);
// start es a depth pont tavolsaga
distA = Math.Sqrt(
(start.X - depth.X) * (start.X - depth.X) +
(start.Y - depth.Y) * (start.Y - depth.Y));
// end es a depth pont tavolsaga
distB = Math.Sqrt(
(end.X - depth.X) * (end.X - depth.X) +
(end.Y - depth.Y) * (end.Y - depth.Y));
tmpImage.Draw(new LineSegment2D(start, depth), new Bgr(System.Drawing.Color.Cyan), 2);
tmpImage.Draw(new LineSegment2D(end, depth), new Bgr(System.Drawing.Color.PaleGreen), 2);
// Ha nagyon kozel vannak egymashoz akkor ellenorizni kell, hogy biztos sarok pont-e amit annak hisz.
if (Math.Abs(distA - distB) < distB * 0.2)
// Ha a start tavolsaga nagyobb
cornerPoints.Add(possibleCornerPoints[i]);
if (distA > distB)
// Kiszamoljuk az elozo/utolso ponttol valo tavolsagot
if (i != 0)
(start.X - possibleCornerPoints[i - 1].X) * (start.X - possibleCornerPoints[i - 1].X) +
(start.Y - possibleCornerPoints[i - 1].Y) * (start.Y - possibleCornerPoints[i - 1].Y));
tmpImage.Draw(new LineSegment2D(start, possibleCornerPoints[i - 1]), new Bgr(System.Drawing.Color.SkyBlue), 1);
(start.X - possibleCornerPoints.Last().X) * (start.X - possibleCornerPoints.Last().X) +
(start.Y - possibleCornerPoints.Last().Y) * (start.Y - possibleCornerPoints.Last().Y));
tmpImage.Draw(new LineSegment2D(start, possibleCornerPoints.Last()), new Bgr(System.Drawing.Color.Navy), 1);
//tmpImage.Draw(new CircleF(possibleCornerPoints[i], 3), new Bgr(255, 0, 0), 1);
// Kezdo es vegpont kozotti tavolsag
(end.X - start.X) * (end.X - start.X) +
(end.Y - start.Y) * (end.Y - start.Y));
if (i == distances.Count - 1)
tmpImage.Draw(new LineSegment2D(end, start), new Bgr(System.Drawing.Color.Orange), 2);
cornerPoints.Add(possibleCornerPoints[0]);
// Ha a kiszamolt tavolsag kisebb mint a kezdo es vegpont kozotti tavolsag 10%-a vagy
//tmpImage.Draw(new CircleF(possibleCornerPoints[0], 3), new Bgr(0, 255, 0), 1);
// nagyobb, mint a ketszerese akkor a kezdo pont lesz a sarok, kulonben a vegpont
if (distB * 0.1 > distA || distB * 2 < distA)
goodCornerPoints.Add(start);
goodCornerPoints.Add(end);
// Kulonben
cornerPoints.Add(possibleCornerPoints[i + 1]);
// Kiszamoljuk a kovetkezo/elso ponttol valo tavolsagot
//tmpImage.Draw(new CircleF(possibleCornerPoints[i + 1], 3), new Bgr(0, 255, 0), 1);
if (i != possibleCornerPoints.Count - 3)
(end.X - possibleCornerPoints[i + 3].X) * (end.X - possibleCornerPoints[i + 3].X) +
(end.Y - possibleCornerPoints[i + 3].Y) * (end.Y - possibleCornerPoints[i + 3].Y));
tmpImage.Draw(new LineSegment2D(end, possibleCornerPoints[i + 3]), new Bgr(System.Drawing.Color.Red), 2);
(end.X - possibleCornerPoints[0].X) * (end.X - possibleCornerPoints[0].X) +
(end.Y - possibleCornerPoints[0].Y) * (end.Y - possibleCornerPoints[0].Y));
tmpImage.Draw(new LineSegment2D(end, possibleCornerPoints[0]), new Bgr(System.Drawing.Color.Purple), 2);
// Ha egyertelmuen eldontheto, hogy melyik a nagyobb akkor a nagyobb a sarok
tmpImage.Draw(new CircleF(goodCornerPoints.Last(), 5), new Bgr(System.Drawing.Color.Cyan), -1);
//Image<Bgr, Byte> tmpImage = new Image<Bgr, byte>(currPiece.ImgPiece.Bitmap);
// kozeli sarkok szurese
List<double> distancesOfGoodCorners = new List<double>();
for (int i = 0; i < goodCornerPoints.Count(); i++)
if (i == goodCornerPoints.Count - 1)
distancesOfGoodCorners.Add(Math.Floor(Math.Sqrt(
(goodCornerPoints[i].X - goodCornerPoints[0].X) * (goodCornerPoints[i].X - goodCornerPoints[0].X) +
(goodCornerPoints[i].Y - goodCornerPoints[0].Y) * (goodCornerPoints[i].Y - goodCornerPoints[0].Y))));
539
tmpImage.Draw(new LineSegment2D(goodCornerPoints[i], goodCornerPoints[0]), new Bgr(System.Drawing.Color.Beige), 3);
540
tmpImage.Draw(new CircleF(goodCornerPoints[i], 5), new Bgr(System.Drawing.Color.Cyan), -1);
541
tmpImage.Draw(new CircleF(goodCornerPoints[0], 5), new Bgr(System.Drawing.Color.DarkOliveGreen), -1);
542
543
544
545
546
(goodCornerPoints[i + 1].X - goodCornerPoints[i].X) * (goodCornerPoints[i + 1].X - goodCornerPoints[i].X) +
547
(goodCornerPoints[i + 1].Y - goodCornerPoints[i].Y) * (goodCornerPoints[i + 1].Y - goodCornerPoints[i].Y))));
548
tmpImage.Draw(new LineSegment2D(goodCornerPoints[i + 1], goodCornerPoints[i]), new Bgr(System.Drawing.Color.Beige), 3);
549
tmpImage.Draw(new CircleF(goodCornerPoints[i + 1], 5), new Bgr(System.Drawing.Color.Cyan), -1);
550
tmpImage.Draw(new CircleF(goodCornerPoints[i], 5), new Bgr(System.Drawing.Color.DarkOliveGreen), -1);
551
552
553
554
double distMin = distancesOfGoodCorners.Min();
double distAvg = distancesOfGoodCorners.Average();
for (int i = 0; i < distancesOfGoodCorners.Count; i++)
if (distancesOfGoodCorners.Max() * 0.1 > distancesOfGoodCorners[i])
int falseCorner1Idx = contourPoints.IndexOf(goodCornerPoints[i]);
int falseCorner2Idx = contourPoints.IndexOf(goodCornerPoints[i + 1]);
int finalCornerIdx = 0;
if (falseCorner1Idx != falseCorner2Idx)
finalCornerIdx = (int)Math.Ceiling((falseCorner1Idx + falseCorner2Idx) / 2.0);
finalCornerIdx = falseCorner2Idx;
cornerPoints.Add(contourPoints[finalCornerIdx]);
tmpImage.Draw(new CircleF(cornerPoints.Last(), 3), new Bgr(0, 0, 255), -1);
i++;
//tmpImage.Draw(new CircleF(contourPoints[falseCorner1Idx], 1), new Bgr(System.Drawing.Color.HotPink), -1);
//tmpImage.Draw(new CircleF(contourPoints[falseCorner2Idx], 1), new Bgr(System.Drawing.Color.Aquamarine), -1);
//tmpImage.Draw(new CircleF(contourPoints[finalCornerIdx], 1), new Bgr(System.Drawing.Color.Brown), -1);
582
cornerPoints.Add(goodCornerPoints[i]);
583
584
585
//for (int i = 0; i < possibleCornerPoints.Count; i++)
// if (i == possibleCornerPoints.Count - 1)
// distancesOfGoodCorners.Add(Math.Floor(Math.Sqrt(
// (possibleCornerPoints[i].X - possibleCornerPoints[0].X) * (possibleCornerPoints[i].X - possibleCornerPoints[0].X) +
// (possibleCornerPoints[i].Y - possibleCornerPoints[0].Y) * (possibleCornerPoints[i].Y - possibleCornerPoints[0].Y))));
// tmpImage.Draw(new LineSegment2D(possibleCornerPoints[i], possibleCornerPoints[0]), new Bgr(System.Drawing.Color.Beige), 3);
// tmpImage.Draw(new CircleF(possibleCornerPoints[i], 5), new Bgr(System.Drawing.Color.Cyan), -1);
// tmpImage.Draw(new CircleF(possibleCornerPoints[0], 5), new Bgr(System.Drawing.Color.DarkOliveGreen), -1);
// else
// (possibleCornerPoints[i + 1].X - possibleCornerPoints[i].X) * (possibleCornerPoints[i + 1].X - possibleCornerPoints[i].X) +
// (possibleCornerPoints[i + 1].Y - possibleCornerPoints[i].Y) * (possibleCornerPoints[i + 1].Y - possibleCornerPoints[i].Y))));
// tmpImage.Draw(new LineSegment2D(possibleCornerPoints[i+1], possibleCornerPoints[i]), new Bgr(System.Drawing.Color.Beige), 3);
// tmpImage.Draw(new CircleF(possibleCornerPoints[i+1], 5), new Bgr(System.Drawing.Color.Cyan), -1);
// tmpImage.Draw(new CircleF(possibleCornerPoints[i], 5), new Bgr(System.Drawing.Color.DarkOliveGreen), -1);
//double avgOfDistances = distancesOfGoodCorners.Average();
//List<double> avgDevOfDistances = new List<double>();
//currDev = 0;
//avgOfDev = 0;
//for (int i = 0; i < distances.Count; i++)
// currDev = avgOfDistances - distances[i];
// avgDevOfDistances.Add(currDev);
//avgOfDev /= distances.Count;
// if (avgDevOfDistances[i] < avgOfDev)
// tmpImage = new Image<Bgr, byte>(currPiece.Bitmap);
// cornerPoints.Add(possibleCornerPoints[i]);
630
// tmpImage.Draw(new CircleF(possibleCornerPoints[i], 3), new Bgr(255, 0, 0), 1);
631
632
// if (i == distances.Count - 1)
633
634
// cornerPoints.Add(possibleCornerPoints[0]);
635
// tmpImage.Draw(new CircleF(possibleCornerPoints[0], 3), new Bgr(0, 255, 0), 1);
636
637
638
639
// cornerPoints.Add(possibleCornerPoints[i + 1]);
640
// tmpImage.Draw(new CircleF(possibleCornerPoints[i + 1], 3), new Bgr(0, 255, 0), 1);
641
642
643
644
645
646
//for (int i = 0; i < cornerPoints.Count; i++)
647
648
// tmpImage.Draw(new CircleF(cornerPoints[i], 3), new Bgr(0, 0, 255), -1);
649
// tmpImage.Draw(new CircleF(cornerPoints[i], 3), new Bgr(0, 255, 0), -1);
650
651
return cornerPoints;
652
653
654
private static List<Point> CornersFromNonOutboundedPieces(MCvBox2D minAreaRect, CustomContour contour)
655
656
Point a = new Point((int)minAreaRect.center.X - (int)minAreaRect.size.Width / 2, (int)minAreaRect.center.Y - (int)minAreaRect.size.Height / 2);
657
Point b = new Point((int)minAreaRect.center.X - (int)minAreaRect.size.Width / 2, (int)minAreaRect.center.Y + (int)minAreaRect.size.Height / 2);
658
Point c = new Point((int)minAreaRect.center.X + (int)minAreaRect.size.Width / 2, (int)minAreaRect.center.Y + (int)minAreaRect.size.Height / 2);
659
Point d = new Point((int)minAreaRect.center.X + (int)minAreaRect.size.Width / 2, (int)minAreaRect.center.Y - (int)minAreaRect.size.Height / 2);
660
public static List<PuzzleSide> GetSides(Contour<Point> contour, List<Point> corners, Image<Bgr, Byte> imgMaskedPiece)
661
int minOfA, minOfB, minOfC, minOfD;
662
minOfA = minOfB = minOfC = minOfD = 5000;
663
int minIdxOfA, minIdxOfB, minIdxOfC, minIdxOfD, currDistOfA, currDistOfB, currDistOfC, currDistOfD;
664
minIdxOfA = minIdxOfB = minIdxOfC = minIdxOfD = currDistOfA = currDistOfB = currDistOfC = currDistOfD = 0;
665
double range = minAreaRect.size.Width * 0.3;
666
667
668
Point currContourPoint;
669
Parallel.For(0, contour.OriginalContour.Count(), i =>
670
671
currContourPoint = contour.OriginalContour[i];
672
if (a.X + range > currContourPoint.X && a.Y + range > currContourPoint.Y)
673
674
currDistOfA = (a.X - currContourPoint.X) * (a.X - currContourPoint.X) + (a.Y - currContourPoint.Y) * (a.Y - currContourPoint.Y);
675
if (currDistOfA < minOfA)
676
677
minIdxOfA = i;
678
minOfA = currDistOfA;
679
680
681
if (b.X + range > currContourPoint.X && b.Y - range < currContourPoint.Y)
682
683
currDistOfB = (b.X - currContourPoint.X) * (b.X - currContourPoint.X) + (b.Y - currContourPoint.Y) * (b.Y - currContourPoint.Y);
684
if (currDistOfB < minOfB)
685
686
minIdxOfB = i;
687
minOfB = currDistOfB;
688
689
690
691
if (c.X - range < currContourPoint.X && c.Y - range < currContourPoint.Y)
692
693
currDistOfC = (c.X - currContourPoint.X) * (c.X - currContourPoint.X) + (c.Y - currContourPoint.Y) * (c.Y - currContourPoint.Y);
694
if (currDistOfC < minOfC)
695
696
minIdxOfC = i;
697
minOfC = currDistOfC;
698
699
700
701
if (d.X - range < currContourPoint.X && d.Y + range > currContourPoint.Y)
702
703
currDistOfD = (d.X - currContourPoint.X) * (d.X - currContourPoint.X) + (d.Y - currContourPoint.Y) * (d.Y - currContourPoint.Y);
704
if (currDistOfD < minOfD)
705
706
minIdxOfD = i;
707
minOfD = currDistOfD;
708
709
710
711
712
713
714
715
corners.Add(contour.OriginalContour[minIdxOfA]);
716
corners.Add(contour.OriginalContour[minIdxOfB]);
717
corners.Add(contour.OriginalContour[minIdxOfC]);
718
corners.Add(contour.OriginalContour[minIdxOfD]);
719
720
721
722
723
public static List<PuzzleSide> GetSides(Contour<Point> contour, List<Point> corners, List<MCvConvexityDefect> realConvexityDefects, Image<Bgr, Byte> imgMaskedPiece)
724
List<PuzzleSide> sides = new List<PuzzleSide>();
725
List<Point> contourPoints = contour.ToList();
726
set { position = value; }
public PuzzlePiece(Image<Bgr, Byte> colourPiece, string puzzleName, Point puzzlePosition)
private List<MCvConvexityDefect> realConvexityDefects = new List<MCvConvexityDefect>();
private void SetRealConvexityDefects(List<MCvConvexityDefect> convexityDefects, Point centerOfMass)
for (int i = 0; i < convexityDefects.Count; i++)
avgOfDepths += convexityDefects[i].Depth;
avgOfDepths /= convexityDefects.Count;
realConvexityDefects = new List<MCvConvexityDefect>();
foreach (MCvConvexityDefect defect in convexityDefects)
realConvexityDefects.Add(defect);
name = puzzleName;
iD = PuzzleFunction.PuzzlePieces.Count();
position = puzzlePosition;
imgThresholdedPiece = ImageFunction.BinarizeHSV(colourPiece, 130);
imgThresholdedPiece = ImageFunction.Binarize(colourPiece, 152);
imgThresholdedPiece = imgThresholdedPiece.Erode(2);
//imgThresholdedPiece = imgThresholdedPiece.Erode(2);
imgThresholdedPiece = imgThresholdedPiece.Dilate(2);
//imgThresholdedPiece = imgThresholdedPiece.Dilate(2);
Image<Bgr, Byte> tmp = new Image<Bgr, byte>(imgThresholdedPiece.Bitmap);
if (rawContours.Count != 0)
//CustomContour contour = ImageFunction.GetContours(imgThresholdedPiece, .5)[0];
tmp = new Image<Bgr, byte>(imgThresholdedPiece.Bitmap);
tmp.Draw(rawContours[0].OriginalContour, new Bgr(0,255,0), 1);
CustomContour contour = rawContours[0];
List<Point> corners = SortCorners(PuzzleFunction.GetCorners(imgPiece, contour), contour.GetUnsortedContourPoints());
SetRealConvexityDefects(contour.ConvexityDefects, contour.CenterOfMass);
sides = PuzzleFunction.GetSides(contour.OriginalContour, corners, imgMaskedPiece);
List<Point> corners = SortCorners(PuzzleFunction.GetCorners(imgPiece, contour, realConvexityDefects), contour.GetUnsortedContourPoints());
sides = PuzzleFunction.GetSides(contour.OriginalContour, corners, realConvexityDefects, imgMaskedPiece);
SetPieceType();
SortSides();
signature = GetSignature(sides, contour.CenterOfMass);
set { ImageFunction.thresholdHighValue = value; }set { ImageFunction.thresholdHighValue = value; }public static Image<Gray, Byte> BinarizeHSV(Image<Bgr, Byte> srcImage, byte thresholdVal){{Image<Gray, Byte> imgSat = channels[1];Image<Gray, Byte> imgMask = channels[1];dstImage = imgSatdstImage = imgMask{{//capture.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_WIDTH, 1280);//capture.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_HEIGHT, 720);//captureFrame = capture.QueryFrame(); captureGrayFrame = capture.QueryGrayFrame();//{//{//if (rBtnThresholdSimple.Checked)imgBinarized = ImageFunction.Binarize(captureFrame, 152);// imgBinarized = ImageFunction.BinarizeSimple(captureGrayFrame);picBoxCamBinarized.Image = captureFrame.Or(imgBinarized.Convert<Bgr, Byte>());//else if (rBtnThresholdDouble.Checked)// imgBinarized = ImageFunction.BinarizeDouble(captureGrayFrame);//else if (rBtnThresholdOtsu.Checked)// imgBinarized = ImageFunction.BinarizeOtsu(captureGrayFrame);//picBoxCamBinarized.Image = imgBinarized;imgBinarized = ImageFunction.BinarizeHSV(captureFrame, 152);picBoxCamBinarized.Image = imgBinarized;//{//{//picBoxCamBinarized.Image = ImageFunction.GetCorners(captureGrayFrame);//try//{// //rawContours = ImageFunction.GetContours(imgCannyEdgeDetected, true, .5);// PuzzleFunction.Cut(captureFrame, rawContours);//}//catch (ArgumentException ex)//{// ErrorMessage(ex.Message);//}//lbPuzzlePieces.DataSource = PuzzleFunction.PuzzlePieces.ToArray();//picBoxCamOriginal.Image = captureFrame;//lbPuzzlePieces.DataSource = PuzzleFunction.PuzzlePieces.ToArray();{{tmp.Draw(new CircleF(currPiece.Sides[i].Corners[0], 3), new Bgr(0, 255, 0), 1);tmp.Draw(new CircleF(currPiece.Sides[i].Corners[0], 5), new Bgr(0, 255, 0), -1);tmp.Draw(new CircleF(currPiece.Sides[i].Corners[0], 3), new Bgr(255, 0, 0), 1);tmp.Draw(new CircleF(currPiece.Sides[i].Corners[0], 5), new Bgr(255, 0, 0), -1);tmp.Draw(new CircleF(currPiece.Sides[i].Corners[0], 3), new Bgr(0, 0, 255), 1);tmp.Draw(new CircleF(currPiece.Sides[i].Corners[0], 5), new Bgr(0, 0, 255), -1);tmp.Draw(new CircleF(currPiece.Sides[i].Corners[0], 3), new Bgr(255, 255, 0), 1);tmp.Draw(new CircleF(currPiece.Sides[i].Corners[0], 5), new Bgr(255, 255, 0), -1);picBoxPuzzlePiece.Image = tmp;picBoxCannyEdge.Image = tmp;this.picBoxCannyEdge = new Emgu.CV.UI.ImageBox();this.labThresholdValHigh = new System.Windows.Forms.Label();this.numUpDownThresholdHigh = new System.Windows.Forms.NumericUpDown();this.groupBox3 = new System.Windows.Forms.GroupBox();this.rBtnThresholdOtsu = new System.Windows.Forms.RadioButton();this.rBtnThresholdDouble = new System.Windows.Forms.RadioButton();this.rBtnThresholdSimple = new System.Windows.Forms.RadioButton();this.groupBox5 = new System.Windows.Forms.GroupBox();this.label3 = new System.Windows.Forms.Label();this.numericUpDown1 = new System.Windows.Forms.NumericUpDown();this.groupBox6 = new System.Windows.Forms.GroupBox();this.numUpDownErodeIter = new System.Windows.Forms.NumericUpDown();this.numUpDownDilateIter = new System.Windows.Forms.NumericUpDown();this.label2 = new System.Windows.Forms.Label();this.label1 = new System.Windows.Forms.Label();this.histogram = new Emgu.CV.UI.HistogramBox();this.picBoxCannyEdge = new Emgu.CV.UI.ImageBox();this.groupBox6 = new System.Windows.Forms.GroupBox();this.label1 = new System.Windows.Forms.Label();this.label2 = new System.Windows.Forms.Label();this.numUpDownDilateIter = new System.Windows.Forms.NumericUpDown();this.numUpDownErodeIter = new System.Windows.Forms.NumericUpDown();this.numericUpDown1 = new System.Windows.Forms.NumericUpDown();this.label3 = new System.Windows.Forms.Label();this.groupBox5 = new System.Windows.Forms.GroupBox();((System.ComponentModel.ISupportInitialize)(this.picBoxCannyEdge)).BeginInit();((System.ComponentModel.ISupportInitialize)(this.numUpDownThresholdLow)).BeginInit();((System.ComponentModel.ISupportInitialize)(this.picBoxCamBinarized)).BeginInit();((System.ComponentModel.ISupportInitialize)(this.picBoxCannyEdge)).BeginInit();this.groupBox5.SuspendLayout();((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();((System.ComponentModel.ISupportInitialize)(this.numUpDownDilateIter)).BeginInit();((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();this.gBoxPuzzlePieces.SuspendLayout();this.groupBox5.SuspendLayout();((System.ComponentModel.ISupportInitialize)(this.picBoxPuzzlePiece)).BeginInit();// picBoxCannyEdge//this.picBoxCannyEdge.Location = new System.Drawing.Point(6, 19);this.picBoxCannyEdge.Name = "picBoxCannyEdge";this.picBoxCannyEdge.Size = new System.Drawing.Size(309, 220);this.picBoxCannyEdge.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;this.picBoxCannyEdge.TabIndex = 7;this.picBoxCannyEdge.TabStop = false;//// labThresholdValHigh//this.labThresholdValHigh.AutoSize = true;this.labThresholdValHigh.Location = new System.Drawing.Point(128, 21);this.labThresholdValHigh.Name = "labThresholdValHigh";this.labThresholdValHigh.Size = new System.Drawing.Size(35, 13);this.labThresholdValHigh.TabIndex = 8;this.labThresholdValHigh.Text = "Felső:";this.labThresholdValHigh.Visible = false;//// numUpDownThresholdHigh//this.numUpDownThresholdHigh.Location = new System.Drawing.Point(172, 19);this.numUpDownThresholdHigh.Maximum = new decimal(new int[] {255,0,0,0});this.numUpDownThresholdHigh.Name = "numUpDownThresholdHigh";this.numUpDownThresholdHigh.Size = new System.Drawing.Size(40, 20);this.numUpDownThresholdHigh.TabIndex = 9;this.numUpDownThresholdHigh.Value = new decimal(new int[] {100,0,0,0});this.numUpDownThresholdHigh.Visible = false;this.numUpDownThresholdHigh.ValueChanged += new System.EventHandler(this.numUpDownThresholdHigh_ValueChanged);//// groupBox3//this.groupBox3.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)| System.Windows.Forms.AnchorStyles.Right)));this.groupBox3.Controls.Add(this.rBtnThresholdOtsu);this.groupBox3.Controls.Add(this.rBtnThresholdDouble);this.groupBox3.Controls.Add(this.rBtnThresholdSimple);this.groupBox3.Location = new System.Drawing.Point(6, 245);this.groupBox3.Name = "groupBox3";this.groupBox3.Size = new System.Drawing.Size(309, 49);this.groupBox3.TabIndex = 8;this.groupBox3.TabStop = false;this.groupBox3.Text = "Módszer";//// rBtnThresholdOtsu//this.rBtnThresholdOtsu.AutoSize = true;this.rBtnThresholdOtsu.Checked = true;this.rBtnThresholdOtsu.Location = new System.Drawing.Point(172, 19);this.rBtnThresholdOtsu.Name = "rBtnThresholdOtsu";this.rBtnThresholdOtsu.Size = new System.Drawing.Size(47, 17);this.rBtnThresholdOtsu.TabIndex = 0;this.rBtnThresholdOtsu.TabStop = true;this.rBtnThresholdOtsu.Text = "Otsu";this.rBtnThresholdOtsu.UseVisualStyleBackColor = true;this.rBtnThresholdOtsu.CheckedChanged += new System.EventHandler(this.rBtnThresholdOtsu_CheckedChanged);//// rBtnThresholdDouble//this.rBtnThresholdDouble.AutoSize = true;this.rBtnThresholdDouble.Location = new System.Drawing.Point(80, 19);this.rBtnThresholdDouble.Name = "rBtnThresholdDouble";this.rBtnThresholdDouble.Size = new System.Drawing.Size(86, 17);this.rBtnThresholdDouble.TabIndex = 0;this.rBtnThresholdDouble.Text = "Hiszterézises";this.rBtnThresholdDouble.UseVisualStyleBackColor = true;this.rBtnThresholdDouble.CheckedChanged += new System.EventHandler(this.rBtnThresholdDouble_CheckedChanged);//// rBtnThresholdSimple//this.rBtnThresholdSimple.AutoSize = true;this.rBtnThresholdSimple.Location = new System.Drawing.Point(6, 19);this.rBtnThresholdSimple.Name = "rBtnThresholdSimple";this.rBtnThresholdSimple.Size = new System.Drawing.Size(68, 17);this.rBtnThresholdSimple.TabIndex = 0;this.rBtnThresholdSimple.Text = "Egyszerű";this.rBtnThresholdSimple.UseVisualStyleBackColor = true;this.rBtnThresholdSimple.CheckedChanged += new System.EventHandler(this.rBtnThresholdSimple_CheckedChanged);//// groupBox5//this.groupBox5.Controls.Add(this.label3);this.groupBox5.Controls.Add(this.numericUpDown1);this.groupBox5.Controls.Add(this.groupBox6);this.groupBox5.Controls.Add(this.picBoxCannyEdge);this.groupBox5.Location = new System.Drawing.Point(666, 28);this.groupBox5.Name = "groupBox5";this.groupBox5.Size = new System.Drawing.Size(320, 357);this.groupBox5.TabIndex = 11;this.groupBox5.TabStop = false;this.groupBox5.Text = "Éldetektált kép";//// label3//this.label3.AutoSize = true;this.label3.Location = new System.Drawing.Point(12, 317);this.label3.Name = "label3";this.label3.Size = new System.Drawing.Size(179, 13);this.label3.TabIndex = 10;this.label3.Text = "A puzzle darab %os aránya a képen:";//// numericUpDown1//this.numericUpDown1.Location = new System.Drawing.Point(197, 315);this.numericUpDown1.Name = "numericUpDown1";this.numericUpDown1.Size = new System.Drawing.Size(40, 20);this.numericUpDown1.TabIndex = 11;this.numericUpDown1.Value = new decimal(new int[] {80,0,0,0});//// groupBox6//this.groupBox6.Controls.Add(this.numUpDownErodeIter);this.groupBox6.Controls.Add(this.numUpDownDilateIter);this.groupBox6.Controls.Add(this.label2);this.groupBox6.Controls.Add(this.label1);this.groupBox6.Location = new System.Drawing.Point(6, 245);this.groupBox6.Name = "groupBox6";this.groupBox6.Size = new System.Drawing.Size(308, 49);this.groupBox6.TabIndex = 9;this.groupBox6.TabStop = false;this.groupBox6.Text = "Dialtáció/Erózió iterációk száma";//// numUpDownErodeIter//this.numUpDownErodeIter.Location = new System.Drawing.Point(178, 19);this.numUpDownErodeIter.Maximum = new decimal(new int[] {1000,0,0,0});this.numUpDownErodeIter.Name = "numUpDownErodeIter";this.numUpDownErodeIter.Size = new System.Drawing.Size(40, 20);this.numUpDownErodeIter.TabIndex = 10;this.numUpDownErodeIter.ValueChanged += new System.EventHandler(this.numUpDownErodeIter_ValueChanged);//// numUpDownDilateIter//this.numUpDownDilateIter.Location = new System.Drawing.Point(63, 19);this.numUpDownDilateIter.Maximum = new decimal(new int[] {1000,0,0,0});this.numUpDownDilateIter.Name = "numUpDownDilateIter";this.numUpDownDilateIter.Size = new System.Drawing.Size(40, 20);this.numUpDownDilateIter.TabIndex = 10;this.numUpDownDilateIter.Value = new decimal(new int[] {1,0,0,0});this.numUpDownDilateIter.ValueChanged += new System.EventHandler(this.numUpDownDilateIter_ValueChanged);//// label2//this.label2.AutoSize = true;this.label2.Location = new System.Drawing.Point(121, 21);this.label2.Name = "label2";this.label2.Size = new System.Drawing.Size(39, 13);this.label2.TabIndex = 7;this.label2.Text = "Erózió:";this.label2.TextAlign = System.Drawing.ContentAlignment.TopRight;//// label1//this.label1.AutoSize = true;this.label1.Location = new System.Drawing.Point(6, 21);this.label1.Name = "label1";this.label1.Size = new System.Drawing.Size(51, 13);this.label1.TabIndex = 7;this.label1.Text = "Dilatáció:";this.label1.TextAlign = System.Drawing.ContentAlignment.TopRight;//this.numUpDownThresholdHigh.Maximum = new decimal(new int[] {this.numUpDownThresholdHigh.Value = new decimal(new int[] {// histogram// picBoxCannyEdgethis.histogram.Location = new System.Drawing.Point(339, 406);this.picBoxCannyEdge.Location = new System.Drawing.Point(6, 19);this.histogram.Name = "histogram";this.picBoxCannyEdge.Name = "picBoxCannyEdge";this.histogram.Size = new System.Drawing.Size(647, 225);this.picBoxCannyEdge.Size = new System.Drawing.Size(309, 220);this.histogram.TabIndex = 14;this.picBoxCannyEdge.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;this.picBoxCannyEdge.TabIndex = 7;this.picBoxCannyEdge.TabStop = false;this.numUpDownDilateIter.Maximum = new decimal(new int[] {this.numUpDownDilateIter.Value = new decimal(new int[] {this.numUpDownErodeIter.Maximum = new decimal(new int[] {this.numericUpDown1.Value = new decimal(new int[] {((System.ComponentModel.ISupportInitialize)(this.picBoxCannyEdge)).EndInit();((System.ComponentModel.ISupportInitialize)(this.numUpDownThresholdLow)).EndInit();((System.ComponentModel.ISupportInitialize)(this.picBoxCamBinarized)).EndInit();((System.ComponentModel.ISupportInitialize)(this.picBoxCannyEdge)).EndInit();this.groupBox5.ResumeLayout(false);this.groupBox5.PerformLayout();((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit();((System.ComponentModel.ISupportInitialize)(this.numUpDownDilateIter)).EndInit();((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit();this.gBoxPuzzlePieces.ResumeLayout(false);this.groupBox5.ResumeLayout(false);this.gBoxPuzzlePieces.PerformLayout();this.groupBox5.PerformLayout();((System.ComponentModel.ISupportInitialize)(this.picBoxPuzzlePiece)).EndInit();private System.Windows.Forms.StatusStrip statusStrip;private System.Windows.Forms.StatusStrip statusStrip;private Emgu.CV.UI.ImageBox picBoxCannyEdge;private System.Windows.Forms.GroupBox groupBox4;private System.Windows.Forms.GroupBox groupBox4;private System.Windows.Forms.Label labThresholdValHigh;private System.Windows.Forms.NumericUpDown numUpDownThresholdHigh;private System.Windows.Forms.NumericUpDown numUpDownThresholdLow;private System.Windows.Forms.NumericUpDown numUpDownThresholdLow;private System.Windows.Forms.GroupBox groupBox3;private Emgu.CV.UI.ImageBox picBoxCamBinarized;private System.Windows.Forms.RadioButton rBtnThresholdOtsu;private System.Windows.Forms.RadioButton rBtnThresholdDouble;private System.Windows.Forms.RadioButton rBtnThresholdSimple;private Emgu.CV.UI.ImageBox picBoxCamBinarized;private System.Windows.Forms.GroupBox groupBox5;private System.Windows.Forms.GroupBox groupBox6;private System.Windows.Forms.NumericUpDown numUpDownErodeIter;private System.Windows.Forms.NumericUpDown numUpDownDilateIter;private System.Windows.Forms.Label label2;private System.Windows.Forms.Label label1;private System.Windows.Forms.Label label3;private System.Windows.Forms.NumericUpDown numericUpDown1;private Emgu.CV.UI.HistogramBox histogram;private Emgu.CV.UI.ImageBox picBoxCannyEdge;private System.Windows.Forms.GroupBox groupBox6;private System.Windows.Forms.NumericUpDown numUpDownErodeIter;private System.Windows.Forms.NumericUpDown numUpDownDilateIter;private System.Windows.Forms.Label label2;private System.Windows.Forms.Label label1;private System.Windows.Forms.NumericUpDown numericUpDown1;private System.Windows.Forms.Label label3;private System.Windows.Forms.GroupBox groupBox5;D:\BMF\JPS\trunk\JPS_PuzzleDetectorWithCam\JPS_PuzzleDetectorWithCam\bin\Debug\Emgu.CV.xmlD:\BMF\JPS\trunk\JPS_PuzzleDetectorWithCam\JPS_PuzzleDetectorWithCam\bin\Debug\Emgu.CV.UI.xmlD:\BMF\JPS\trunk\JPS_PuzzleDetectorWithCam\JPS_PuzzleDetectorWithCam\bin\Debug\Emgu.Util.xml{{{{for (int i = 0; i < contours.Count; i++){Stopwatch sw = new Stopwatch();sw.Restart();for (int i = 0; i < contours.Count; i++){minAreaRect.size = new SizeF((int)(minAreaRect.size.Width*1.5), (int)(minAreaRect.size.Height*1.5));minAreaRect.size = new SizeF((int)(minAreaRect.size.Width * 1.5), (int)(minAreaRect.size.Height * 1.5));catch (Exception ex){{if (puzzlePieces.Count > 1)System.Windows.Forms.MessageBox.Show(ex.Message);{//if (puzzlePieces.Count > 1)puzzlePieces.Remove(puzzlePieces.Last());//{puzzleCounter--;// puzzlePieces.Remove(puzzlePieces.Last());}// puzzleCounter--;else//}{//elseClearPuzzlePieces();//{}// ClearPuzzlePieces();//}}}}sw.Stop();}public static List<Point> GetCorners(Image<Bgr, Byte> imgPiece, CustomContour contour, List<MCvConvexityDefect> realConvexityDefects){{using (Image<Gray, Byte> imgConvexHull = new Image<Gray, byte>(imgPiece.Size))MCvBox2D minAreaRect = contour.OriginalContour.GetMinAreaRect();Stopwatch sw = new Stopwatch();using (Image<Gray, Byte> imgConvexHull = new Image<Gray, byte>(imgPiece.Size)){{{{imgConvexHull.Draw(contour.OriginalContour.GetConvexHull(ORIENTATION.CV_CLOCKWISE), new Gray(255), 1);double minAreaRectArea = minAreaRect.size.Width * minAreaRect.size.Height;corners = CornersFromConvexityDefects(contour.ConvexityDefects);int diff = (int)(minAreaRectArea - contour.ConvexHull.Area);tmpImage = new Image<Bgr, byte>(imgPiece.Size);tmpImage.Draw(minAreaRect, new Bgr(System.Drawing.Color.Aqua), -1);tmpImage.Draw(contour.OriginalContour.GetConvexHull(ORIENTATION.CV_CLOCKWISE), new Bgr(System.Drawing.Color.Beige), -1);tmpImage.Draw(contour.OriginalContour, new Bgr(System.Drawing.Color.Purple), -1);sw.Restart();//SetRealConvexityDefects(contour.ConvexityDefects, contour.CenterOfMass);if (diff < minAreaRectArea * 0.1)corners = CornersFromNonOutboundedPieces(minAreaRect, contour);elsecorners = CornersFromConvexityDefects(contour, realConvexityDefects, ImageFunction.Binarize(imgPiece, 152));sw.Stop();Parallel.For(0, corners.Count, i => {tmpImage.Draw(new CircleF(corners[i], 3), new Bgr(0, 0, 255), -1);});imgConvexHull.Draw(contour.OriginalContour, new Gray(255), 1);{{PointF[][] goodFeatures = imgConvexHull.GoodFeaturesToTrack(10, .1, imgConvexHull.Width / 3, 5);sw.Restart();imgConvexHull.FindCornerSubPix(goodFeatures, new Size(5, 5), new Size(-1, -1), new MCvTermCriteria(100));List<Point> minAreaRectCorners = new List<Point>();minAreaRectCorners.Add(new Point((int)minAreaRect.center.X - (int)minAreaRect.size.Width / 2,(int)minAreaRect.center.Y - (int)minAreaRect.size.Height / 2));minAreaRectCorners.Add(new Point((int)minAreaRect.center.X - (int)minAreaRect.size.Width / 2,(int)minAreaRect.center.Y + (int)minAreaRect.size.Height / 2));minAreaRectCorners.Add(new Point((int)minAreaRect.center.X + (int)minAreaRect.size.Width / 2,(int)minAreaRect.center.Y + (int)minAreaRect.size.Height / 2));minAreaRectCorners.Add(new Point((int)minAreaRect.center.X + (int)minAreaRect.size.Width / 2,(int)minAreaRect.center.Y - (int)minAreaRect.size.Height / 2));List<PointF> usefulGoodFeatures = goodFeatures[0].ToList();List<Point> nearestCorners = new List<Point>();for (int i = 0; i < corners.Count; i++)Parallel.For(0, corners.Count, i =>{{tmpImage.Draw(new CircleF(corners[i], 3), new Bgr(0,255,255), -1);List<int> distOfCorners = new List<int>();for (int j = 0; j < minAreaRectCorners.Count; j++){distOfCorners.Add((corners[i].X - minAreaRectCorners[j].X) * (corners[i].X - minAreaRectCorners[j].X) +(corners[i].Y - minAreaRectCorners[j].Y) * (corners[i].Y - minAreaRectCorners[j].Y));}nearestCorners.Add(minAreaRectCorners[distOfCorners.IndexOf(distOfCorners.Min())]);});for (int i = 0; i < nearestCorners.Count; i++){minAreaRectCorners.Remove(nearestCorners[i]);double range = 5.0;PointF[][] goodFeatures = imgConvexHull.GoodFeaturesToTrack(30, .1, 10, 5);//imgConvexHull.FindCornerSubPix(goodFeatures, new Size(5, 5), new Size(-1, -1), new MCvTermCriteria(100));for (int i = 0; i < corners.Count; i++)List<PointF> usefulGoodFeatures = goodFeatures[0].ToList();Parallel.For(0, usefulGoodFeatures.Count, i =>{{for (int j = 0; j < goodFeatures[0].Count(); j++)tmpImage.Draw(new CircleF(usefulGoodFeatures[i], 1), new Bgr(0, 255, 0), -1);{});tmpImage.Draw(new CircleF(goodFeatures[0][j], 3), new Bgr(0, 0, 255), -1);if (goodFeatures[0][j].X > corners[i].X - range && goodFeatures[0][j].X < corners[i].X + range &&goodFeatures[0][j].Y > corners[i].Y - range && goodFeatures[0][j].Y < corners[i].Y + range)usefulGoodFeatures.Remove(goodFeatures[0][j]);}}range = 1.0;List<int> distances = new List<int>();List<Point> tmpUsefulCorners = new List<Point>();tmpImage = new Image<Bgr, byte>(imgPiece.Bitmap);for (int i = 0; i < minAreaRectCorners.Count; i++){distances = new List<int>();for (int j = 0; j < usefulGoodFeatures.Count; j++){distances.Add((minAreaRectCorners[i].X - (int)usefulGoodFeatures[j].X) * (minAreaRectCorners[i].X - (int)usefulGoodFeatures[j].X) +(minAreaRectCorners[i].Y - (int)usefulGoodFeatures[j].Y) * (minAreaRectCorners[i].Y - (int)usefulGoodFeatures[j].Y));}for (int i = 0; i < usefulGoodFeatures.Count; i++)nearestContourPoints = new List<Point>();{usefulGoodFeature = Point.Round(usefulGoodFeatures[distances.IndexOf(distances.Min())]);{{if (usefulGoodFeatures[i].X > contourPoints[j].X - range && usefulGoodFeatures[i].X < contourPoints[j].X + range &&if (usefulGoodFeature.X > contourPoints[j].X - range &&usefulGoodFeatures[i].Y > contourPoints[j].Y - range && usefulGoodFeatures[i].Y < contourPoints[j].Y + range)usefulGoodFeature.X < contourPoints[j].X + range &&usefulGoodFeature.Y > contourPoints[j].Y - range &&usefulGoodFeature.Y < contourPoints[j].Y + range){{tmpUsefulCorners.Add(contourPoints[j]);//corners.Add(contourPoints[k]);tmpImage.Draw(new CircleF(contourPoints[j], 3), new Bgr(0, 0, 255), 1);//tmpImage.Draw(new CircleF(contourPoints[k], 3), new Bgr(System.Drawing.Color.Yellow), 1);nearestContourPoints.Add(contourPoints[j]);}int currDistance = 0;distances = new List<int>();List<Point> usefulCorners = new List<Point>();for (int j = 0; j < nearestContourPoints.Count; j++)usefulCorners.AddRange(tmpUsefulCorners);for (int i = 0; i < tmpUsefulCorners.Count - 1; i++){currDistance =(tmpUsefulCorners[i].X - tmpUsefulCorners[i + 1].X) * (tmpUsefulCorners[i].X - tmpUsefulCorners[i + 1].X) +(tmpUsefulCorners[i].Y - tmpUsefulCorners[i + 1].Y) * (tmpUsefulCorners[i].Y - tmpUsefulCorners[i + 1].Y);if (currDistance < 10){{usefulCorners.Remove(tmpUsefulCorners[i]);distances.Add(tmpImage.Draw(new CircleF(tmpUsefulCorners[i + 1], 5), new Bgr(0, 255, 255), 1);(nearestContourPoints[i].X - (int)usefulGoodFeature.X) * (nearestContourPoints[i].X - (int)usefulGoodFeature.X) +(nearestContourPoints[i].Y - (int)usefulGoodFeature.Y) * (nearestContourPoints[i].Y - (int)usefulGoodFeature.Y));tmpImage.Draw(new CircleF(corners[0], 3), new Bgr(0, 255, 0), 1);tmpImage.Draw(new CircleF(corners[1], 3), new Bgr(0, 255, 0), 1);if (usefulCorners.Count > 2)//for (int i = 0; i < nearestGoodFeatures.Count; i++){//{List<int> distances = new List<int>();// tmpImage.Draw(new CircleF(nearestGoodFeatures[i], 1), new Bgr(255, 255, 255), -1);//}tmpImage.Draw(contour.OriginalContour, new Bgr(System.Drawing.Color.DarkOrange), 1);sw.Stop();for (int i = 0; i < usefulCorners.Count; i++)//for (int i = 0; i < corners.Count; i++){//{distances.Add(// for (int j = 0; j < goodFeatures[0].Count(); j++)(corners[0].X - usefulCorners[i].X) * (corners[0].X - usefulCorners[i].X) +// {(corners[0].Y - usefulCorners[i].Y) * (corners[0].Y - usefulCorners[i].Y));// tmpImage.Draw(new CircleF(goodFeatures[0][j], 3), new Bgr(0, 0, 255), -1);}// if (goodFeatures[0][j].X > corners[i].X - range && goodFeatures[0][j].X < corners[i].X + range &&// goodFeatures[0][j].Y > corners[i].Y - range && goodFeatures[0][j].Y < corners[i].Y + range)// usefulGoodFeatures.Remove(goodFeatures[0][j]);// }//}while (usefulCorners.Count != 2)//range = 1.0;{//List<Point> tmpUsefulCorners = new List<Point>();usefulCorners.RemoveAt(distances.IndexOf(distances.Min()));//List<Point> contourPoints = contour.GetUnsortedContourPoints();distances.Remove(distances.Min());}}corners.AddRange(usefulCorners);//tmpImage = new Image<Bgr, byte>(imgPiece.Bitmap);//for (int i = 0; i < usefulGoodFeatures.Count; i++)//{// for (int j = 0; j < contourPoints.Count; j++)// {// if (usefulGoodFeatures[i].X > contourPoints[j].X - range && usefulGoodFeatures[i].X < contourPoints[j].X + range &&// usefulGoodFeatures[i].Y > contourPoints[j].Y - range && usefulGoodFeatures[i].Y < contourPoints[j].Y + range)// {// tmpUsefulCorners.Add(contourPoints[j]);// tmpImage.Draw(new CircleF(contourPoints[j], 3), new Bgr(0, 0, 255), 1);// }// }//}//int currDistance = 0;//List<Point> usefulCorners = new List<Point>();//usefulCorners.AddRange(tmpUsefulCorners);//for (int i = 0; i < tmpUsefulCorners.Count - 1; i++)//{// currDistance =// (tmpUsefulCorners[i].X - tmpUsefulCorners[i + 1].X) * (tmpUsefulCorners[i].X - tmpUsefulCorners[i + 1].X) +// (tmpUsefulCorners[i].Y - tmpUsefulCorners[i + 1].Y) * (tmpUsefulCorners[i].Y - tmpUsefulCorners[i + 1].Y);// if (currDistance < 10)// {// usefulCorners.Remove(tmpUsefulCorners[i]);// tmpImage.Draw(new CircleF(tmpUsefulCorners[i + 1], 5), new Bgr(0, 255, 255), 1);// }//}//tmpImage.Draw(new CircleF(corners[0], 3), new Bgr(0, 255, 0), 1);//tmpImage.Draw(new CircleF(corners[1], 3), new Bgr(0, 255, 0), 1);//if (usefulCorners.Count > 2)//{// List<int> distances = new List<int>();// for (int i = 0; i < usefulCorners.Count; i++)// {// distances.Add(// (corners[0].X - usefulCorners[i].X) * (corners[0].X - usefulCorners[i].X) +// (corners[0].Y - usefulCorners[i].Y) * (corners[0].Y - usefulCorners[i].Y));// }// while (usefulCorners.Count != 2)// {// usefulCorners.RemoveAt(distances.IndexOf(distances.Min()));// distances.Remove(distances.Min());// }//}//corners.AddRange(usefulCorners);//private static List<MCvConvexityDefect> realConvexityDefects = new List<MCvConvexityDefect>();private static List<Point> CornersFromConvexityDefects(List<MCvConvexityDefect> convexivityDefects)//private static void SetRealConvexityDefects(List<MCvConvexityDefect> convexityDefects, Point centerOfMass)//{// float avgOfDepths = 0;// for (int i = 0; i < convexityDefects.Count; i++)// avgOfDepths += convexityDefects[i].Depth;// avgOfDepths /= convexityDefects.Count;// realConvexityDefects = new List<MCvConvexityDefect>();// foreach (MCvConvexityDefect defect in convexityDefects)// if (defect.Depth > avgOfDepths)// realConvexityDefects.Add(defect);//}private static List<Point> CornersFromConvexityDefects(CustomContour contour, List<MCvConvexityDefect> realConvexityDefects, Image<Gray, Byte> currPiece){{float avgOfDepths = 0;//float avgOfDepths = 0;for (int i = 0; i < convexivityDefects.Count; i++)//for (int i = 0; i < convexivityDefects.Count; i++)avgOfDepths += convexivityDefects[i].Depth;// avgOfDepths += convexivityDefects[i].Depth;avgOfDepths /= convexivityDefects.Count;//avgOfDepths /= convexivityDefects.Count;List<MCvConvexityDefect> goodConvexivityDefects = new List<MCvConvexityDefect>();//List<MCvConvexityDefect> goodConvexivityDefects = new List<MCvConvexityDefect>();//Image<Bgr, Byte> tmpImage = new Image<Bgr, byte>(currPiece.ImgThresholdedPiece.Bitmap);List<Point> possibleCornerPoints = new List<Point>();foreach (MCvConvexityDefect defect in convexivityDefects)if (defect.Depth > avgOfDepths){goodConvexivityDefects.Add(defect);//tmpImage.Draw(new CircleF(defect.StartPoint, 3), new Bgr(255, 0, 0), 1);//tmpImage.Draw(new CircleF(defect.DepthPoint, 3), new Bgr(0, 255, 0), 1);//tmpImage.Draw(new CircleF(defect.EndPoint, 3), new Bgr(0, 0, 255), 1);}realConvexityDefects = goodConvexivityDefects;Image<Bgr, Byte> tmpImage = new Image<Bgr, byte>(currPiece.Bitmap);tmpImage.Draw(new Cross2DF(centerOfMass, 5,5), new Bgr(0,255,0), 1);avgOfDepths = 0;List<double> distancesOfCenterToDepths = new List<double>();for (int i = 0; i < goodConvexivityDefects.Count; i++)avgOfDepths += goodConvexivityDefects[i].Depth;avgOfDepths /= goodConvexivityDefects.Count;//avgOfDepths += 1;foreach (MCvConvexityDefect defect in realConvexityDefects)//avgOfDepths = (float)Math.Ceiling(avgOfDepths);List<double> avgDevOfDepts = new List<double>();double currDev = 0;double avgOfDev = 0;for (int i = 0; i < goodConvexivityDefects.Count; i++){{currDev = avgOfDepths - goodConvexivityDefects[i].Depth;distancesOfCenterToDepths.Add(avgDevOfDepts.Add(currDev);(centerOfMass.X - defect.DepthPoint.X) * (centerOfMass.X - (int)defect.DepthPoint.X) +avgOfDev += Math.Abs(currDev);(centerOfMass.Y - defect.DepthPoint.Y) * (centerOfMass.Y - (int)defect.DepthPoint.Y));tmpImage.Draw(new CircleF(defect.StartPoint, 3), new Bgr(255, 0, 0), 1);tmpImage.Draw(new CircleF(defect.DepthPoint, 3), new Bgr(0, 255, 0), 1);tmpImage.Draw(new CircleF(defect.EndPoint, 3), new Bgr(0, 0, 255), 1);avgOfDev /= goodConvexivityDefects.Count;avgOfDev *= -1;List<Point> possibleCornerPoints = new List<Point>();double avgOfCenterToDepth = distancesOfCenterToDepths.Average() * 0.85;//tmpImage = new Image<Bgr, byte>(currPiece.ImgThresholdedPiece.Bitmap);for (int i = 0; i < realConvexityDefects.Count; i++)for (int i = 0; i < goodConvexivityDefects.Count; i++){{if (avgDevOfDepts[i] > avgOfDev && goodConvexivityDefects[i].Depth < avgOfDepths * 1.12)if (distancesOfCenterToDepths[i] > avgOfCenterToDepth){{possibleCornerPoints.Add(goodConvexivityDefects[i].StartPoint);//good convexity defects-be kell ezeket betenni!!!possibleCornerPoints.Add(goodConvexivityDefects[i].EndPoint);//realConvexityDefects.Add(goodConvexivityDefects[i]);possibleCornerPoints.Add(realConvexityDefects[i].StartPoint);//tmpImage.Draw(new CircleF(goodConvexivityDefects[i].StartPoint, 3), new Bgr(255, 0, 0), 1);possibleCornerPoints.Add(realConvexityDefects[i].DepthPoint);//tmpImage.Draw(new CircleF(goodConvexivityDefects[i].EndPoint, 3), new Bgr(0, 255, 0), 1);possibleCornerPoints.Add(realConvexityDefects[i].EndPoint);tmpImage.Draw(new CircleF(realConvexityDefects[i].DepthPoint, 3), new Bgr(0, 255, 0), -1);List<double> distances = new List<double>();//goodConvexivityDefects = realConvexityDefects;for (int i = 0; i < possibleCornerPoints.Count; i++)////realConvexityDefects = goodConvexivityDefects;{if (i == possibleCornerPoints.Count - 1)distances.Add(Math.Floor(Math.Sqrt((possibleCornerPoints[i].X - possibleCornerPoints[0].X) * (possibleCornerPoints[i].X - possibleCornerPoints[0].X) +(possibleCornerPoints[i].Y - possibleCornerPoints[0].Y) * (possibleCornerPoints[i].Y - possibleCornerPoints[0].Y))));elsedistances.Add(Math.Floor(Math.Sqrt((possibleCornerPoints[i + 1].X - possibleCornerPoints[i].X) * (possibleCornerPoints[i + 1].X - possibleCornerPoints[i].X) +(possibleCornerPoints[i + 1].Y - possibleCornerPoints[i].Y) * (possibleCornerPoints[i + 1].Y - possibleCornerPoints[i].Y))));}double avgOfDistances = distances.Average();//avgOfDepths = 0;//for (int i = 0; i < goodConvexivityDefects.Count; i++)// avgOfDepths += goodConvexivityDefects[i].Depth;//avgOfDepths /= goodConvexivityDefects.Count;List<double> avgDevOfDistances = new List<double>();////avgOfDepths += 1;currDev = 0;////avgOfDepths = (float)Math.Ceiling(avgOfDepths);avgOfDev = 0;//List<double> avgDevOfDepts = new List<double>();for (int i = 0; i < distances.Count; i++)//double currDev = 0;//double avgOfDev = 0;//for (int i = 0; i < goodConvexivityDefects.Count; i++)//{// currDev = avgOfDepths - goodConvexivityDefects[i].Depth;// avgDevOfDepts.Add(currDev);// avgOfDev += Math.Abs(currDev);//}//avgOfDev /= goodConvexivityDefects.Count;//avgOfDev *= -1;//List<Point> possibleCornerPoints = new List<Point>();//tmpImage = new Image<Bgr, byte>(currPiece.Bitmap);//for (int i = 0; i < goodConvexivityDefects.Count; i++)//{// if (avgDevOfDepts[i] > avgOfDev * 1.05 && goodConvexivityDefects[i].Depth < avgOfDepths * 1.12)// {// possibleCornerPoints.Add(goodConvexivityDefects[i].StartPoint);// possibleCornerPoints.Add(goodConvexivityDefects[i].DepthPoint);// possibleCornerPoints.Add(goodConvexivityDefects[i].EndPoint);// tmpImage.Draw(new CircleF(goodConvexivityDefects[i].StartPoint, 3), new Bgr(255, 0, 0), 1);// tmpImage.Draw(new CircleF(goodConvexivityDefects[i].DepthPoint, 3), new Bgr(0, 255, 0), 1);// tmpImage.Draw(new CircleF(goodConvexivityDefects[i].EndPoint, 3), new Bgr(0, 0, 255), 1);// }//}// !!Uj sarok kivalaszto algoritmus!!#region sarok kivalasztasdouble distA, distB = 0;Point start, depth, end;List<Point> goodCornerPoints = new List<Point>();tmpImage = new Image<Bgr, byte>(currPiece.Bitmap);for (int i = 0; i < possibleCornerPoints.Count; i += 3){{currDev = avgOfDistances - distances[i];avgDevOfDistances.Add(currDev);avgOfDev += Math.Abs(currDev);}avgOfDev /= distances.Count;avgOfDev *= -1;// 3 fo pont felvetele az egyertelmuseg miattfor (int i = 0; i < distances.Count; i++)start = possibleCornerPoints[i];{depth = possibleCornerPoints[i + 1];if (avgDevOfDistances[i] < avgOfDev)end = possibleCornerPoints[i + 2];tmpImage.Draw(new CircleF(start, 3), new Bgr(255, 0, 0), -1);tmpImage.Draw(new CircleF(depth, 3), new Bgr(0, 255, 0), -1);tmpImage.Draw(new CircleF(end, 3), new Bgr(0, 0, 255), -1);// start es a depth pont tavolsagadistA = Math.Sqrt((start.X - depth.X) * (start.X - depth.X) +(start.Y - depth.Y) * (start.Y - depth.Y));// end es a depth pont tavolsagadistB = Math.Sqrt((end.X - depth.X) * (end.X - depth.X) +(end.Y - depth.Y) * (end.Y - depth.Y));tmpImage.Draw(new LineSegment2D(start, depth), new Bgr(System.Drawing.Color.Cyan), 2);tmpImage.Draw(new LineSegment2D(end, depth), new Bgr(System.Drawing.Color.PaleGreen), 2);// Ha nagyon kozel vannak egymashoz akkor ellenorizni kell, hogy biztos sarok pont-e amit annak hisz.if (Math.Abs(distA - distB) < distB * 0.2){{//tmpImage = new Image<Bgr, byte>(currPiece.ImgThresholdedPiece.Bitmap);// Ha a start tavolsaga nagyobbcornerPoints.Add(possibleCornerPoints[i]);if (distA > distB){// Kiszamoljuk az elozo/utolso ponttol valo tavolsagotif (i != 0){distA = Math.Sqrt((start.X - possibleCornerPoints[i - 1].X) * (start.X - possibleCornerPoints[i - 1].X) +(start.Y - possibleCornerPoints[i - 1].Y) * (start.Y - possibleCornerPoints[i - 1].Y));tmpImage.Draw(new LineSegment2D(start, possibleCornerPoints[i - 1]), new Bgr(System.Drawing.Color.SkyBlue), 1);}else{distA = Math.Sqrt((start.X - possibleCornerPoints.Last().X) * (start.X - possibleCornerPoints.Last().X) +(start.Y - possibleCornerPoints.Last().Y) * (start.Y - possibleCornerPoints.Last().Y));tmpImage.Draw(new LineSegment2D(start, possibleCornerPoints.Last()), new Bgr(System.Drawing.Color.Navy), 1);}//tmpImage.Draw(new CircleF(possibleCornerPoints[i], 3), new Bgr(255, 0, 0), 1);// Kezdo es vegpont kozotti tavolsagdistB = Math.Sqrt((end.X - start.X) * (end.X - start.X) +(end.Y - start.Y) * (end.Y - start.Y));if (i == distances.Count - 1)tmpImage.Draw(new LineSegment2D(end, start), new Bgr(System.Drawing.Color.Orange), 2);{cornerPoints.Add(possibleCornerPoints[0]);// Ha a kiszamolt tavolsag kisebb mint a kezdo es vegpont kozotti tavolsag 10%-a vagy//tmpImage.Draw(new CircleF(possibleCornerPoints[0], 3), new Bgr(0, 255, 0), 1);// nagyobb, mint a ketszerese akkor a kezdo pont lesz a sarok, kulonben a vegpontif (distB * 0.1 > distA || distB * 2 < distA)goodCornerPoints.Add(start);elsegoodCornerPoints.Add(end);{{cornerPoints.Add(possibleCornerPoints[i + 1]);// Kiszamoljuk a kovetkezo/elso ponttol valo tavolsagot//tmpImage.Draw(new CircleF(possibleCornerPoints[i + 1], 3), new Bgr(0, 255, 0), 1);if (i != possibleCornerPoints.Count - 3){distA = Math.Sqrt((end.X - possibleCornerPoints[i + 3].X) * (end.X - possibleCornerPoints[i + 3].X) +(end.Y - possibleCornerPoints[i + 3].Y) * (end.Y - possibleCornerPoints[i + 3].Y));tmpImage.Draw(new LineSegment2D(end, possibleCornerPoints[i + 3]), new Bgr(System.Drawing.Color.Red), 2);}else{distA = Math.Sqrt((end.X - possibleCornerPoints[0].X) * (end.X - possibleCornerPoints[0].X) +(end.Y - possibleCornerPoints[0].Y) * (end.Y - possibleCornerPoints[0].Y));tmpImage.Draw(new LineSegment2D(end, possibleCornerPoints[0]), new Bgr(System.Drawing.Color.Purple), 2);}// Kezdo es vegpont kozotti tavolsagdistB = Math.Sqrt((end.X - start.X) * (end.X - start.X) +(end.Y - start.Y) * (end.Y - start.Y));tmpImage.Draw(new LineSegment2D(end, start), new Bgr(System.Drawing.Color.Orange), 2);// Ha a kiszamolt tavolsag kisebb mint a kezdo es vegpont kozotti tavolsag 10%-a vagy// nagyobb, mint a ketszerese akkor a kezdo pont lesz a sarok, kulonben a vegpontif (distB * 0.1 > distA || distB * 2 < distA)goodCornerPoints.Add(end);elsegoodCornerPoints.Add(start);{//Image<Bgr, Byte> tmpImage = new Image<Bgr, byte>(currPiece.ImgPiece.Bitmap);// kozeli sarkok szurese{{{{{{//{// {// {//{//{// {// {// {//{//{// tmpImage.Draw(new CircleF(cornerPoints[i], 3), new Bgr(0, 0, 255), -1);// tmpImage.Draw(new CircleF(cornerPoints[i], 3), new Bgr(0, 255, 0), -1);{public static List<PuzzleSide> GetSides(Contour<Point> contour, List<Point> corners, Image<Bgr, Byte> imgMaskedPiece)int minOfA, minOfB, minOfC, minOfD;minOfA = minOfB = minOfC = minOfD = 5000;int minIdxOfA, minIdxOfB, minIdxOfC, minIdxOfD, currDistOfA, currDistOfB, currDistOfC, currDistOfD;minIdxOfA = minIdxOfB = minIdxOfC = minIdxOfD = currDistOfA = currDistOfB = currDistOfC = currDistOfD = 0;double range = minAreaRect.size.Width * 0.3;Stopwatch sw = new Stopwatch();sw.Restart();Point currContourPoint;Parallel.For(0, contour.OriginalContour.Count(), i =>{currContourPoint = contour.OriginalContour[i];if (a.X + range > currContourPoint.X && a.Y + range > currContourPoint.Y){currDistOfA = (a.X - currContourPoint.X) * (a.X - currContourPoint.X) + (a.Y - currContourPoint.Y) * (a.Y - currContourPoint.Y);if (currDistOfA < minOfA){minIdxOfA = i;minOfA = currDistOfA;}}if (b.X + range > currContourPoint.X && b.Y - range < currContourPoint.Y){currDistOfB = (b.X - currContourPoint.X) * (b.X - currContourPoint.X) + (b.Y - currContourPoint.Y) * (b.Y - currContourPoint.Y);if (currDistOfB < minOfB){minIdxOfB = i;minOfB = currDistOfB;}}if (c.X - range < currContourPoint.X && c.Y - range < currContourPoint.Y){currDistOfC = (c.X - currContourPoint.X) * (c.X - currContourPoint.X) + (c.Y - currContourPoint.Y) * (c.Y - currContourPoint.Y);if (currDistOfC < minOfC){minIdxOfC = i;minOfC = currDistOfC;}}if (d.X - range < currContourPoint.X && d.Y + range > currContourPoint.Y){currDistOfD = (d.X - currContourPoint.X) * (d.X - currContourPoint.X) + (d.Y - currContourPoint.Y) * (d.Y - currContourPoint.Y);if (currDistOfD < minOfD){minIdxOfD = i;minOfD = currDistOfD;}}});sw.Stop();List<Point> corners = new List<Point>();corners.Add(contour.OriginalContour[minIdxOfA]);corners.Add(contour.OriginalContour[minIdxOfB]);corners.Add(contour.OriginalContour[minIdxOfC]);corners.Add(contour.OriginalContour[minIdxOfD]);return corners;}public static List<PuzzleSide> GetSides(Contour<Point> contour, List<Point> corners, List<MCvConvexityDefect> realConvexityDefects, Image<Bgr, Byte> imgMaskedPiece){{set { position = value; }set { position = value; }public PuzzlePiece(Image<Bgr, Byte> colourPiece, string puzzleName, Point puzzlePosition)private List<MCvConvexityDefect> realConvexityDefects = new List<MCvConvexityDefect>();private void SetRealConvexityDefects(List<MCvConvexityDefect> convexityDefects, Point centerOfMass){float avgOfDepths = 0;for (int i = 0; i < convexityDefects.Count; i++)avgOfDepths += convexityDefects[i].Depth;avgOfDepths /= convexityDefects.Count;realConvexityDefects = new List<MCvConvexityDefect>();foreach (MCvConvexityDefect defect in convexityDefects)if (defect.Depth > avgOfDepths)realConvexityDefects.Add(defect);}public PuzzlePiece(Image<Bgr, Byte> colourPiece, string puzzleName, Point puzzlePosition){{imgThresholdedPiece = ImageFunction.BinarizeHSV(colourPiece, 130);imgThresholdedPiece = ImageFunction.Binarize(colourPiece, 152);//imgThresholdedPiece = imgThresholdedPiece.Erode(2);//imgThresholdedPiece = imgThresholdedPiece.Dilate(2);{{List<Point> corners = SortCorners(PuzzleFunction.GetCorners(imgPiece, contour), contour.GetUnsortedContourPoints());SetRealConvexityDefects(contour.ConvexityDefects, contour.CenterOfMass);sides = PuzzleFunction.GetSides(contour.OriginalContour, corners, imgMaskedPiece);List<Point> corners = SortCorners(PuzzleFunction.GetCorners(imgPiece, contour, realConvexityDefects), contour.GetUnsortedContourPoints());{{