1683 lines
49 KiB
VB.net
1683 lines
49 KiB
VB.net
Imports Emgu
|
|
Imports Emgu.CV
|
|
Imports Emgu.CV.Util
|
|
Imports Emgu.CV.Structure
|
|
Imports System.IO
|
|
Imports System.Windows.Forms.VisualStyles
|
|
|
|
|
|
Public Class clsVisione
|
|
|
|
Public Enum Errors
|
|
None = 0
|
|
Unknown = 10
|
|
End Enum
|
|
|
|
Public Enum eExpCorrMode
|
|
none = 0
|
|
minFactor = 1
|
|
avgAdd = 2
|
|
minAdd = 3
|
|
AvgFactor = 4
|
|
End Enum
|
|
|
|
Private _image1 As Bitmap = Nothing
|
|
Private _backImage As Bitmap = Nothing
|
|
Private _convBackImage As Bitmap = Nothing
|
|
Private _error As Errors
|
|
Private _exifValid As Boolean = False
|
|
Private _aperture As Double
|
|
Private _focalLength As Double
|
|
Private _iso As Short
|
|
Private _exptime As Double
|
|
Private _imageMng As clsImageMng = Nothing
|
|
Private _outimage As Image(Of Emgu.CV.Structure.Rgb, Byte)
|
|
Private _corImgDiff As Image(Of Emgu.CV.Structure.Gray, Byte)
|
|
Private _thrImage As Image(Of Emgu.CV.Structure.Gray, Byte)
|
|
Private _pdown As Integer = 0
|
|
Private _corImgDiff0 As Image(Of Emgu.CV.Structure.Gray, Byte) = Nothing
|
|
Private _corImgDiff1 As Image(Of Emgu.CV.Structure.Gray, Byte) = Nothing
|
|
Private _corImgDiff2 As Image(Of Emgu.CV.Structure.Gray, Byte) = Nothing
|
|
#If WinXp Then
|
|
Private _searchMode As CvEnum.RETR_TYPE = CvEnum.RETR_TYPE.CV_RETR_EXTERNAL
|
|
#Else
|
|
Private _searchMode As CvEnum.RetrType = CvEnum.RetrType.External
|
|
#End If
|
|
Private _rectExp() As Rectangle = Nothing
|
|
Private _expCorrection As eExpCorrMode = eExpCorrMode.none
|
|
Private _mm() As Integer
|
|
Private _metodoDiff As Integer = 1
|
|
Private _rectLastra As Rectangle = Nothing
|
|
Private _darkRappLevel As Double = 1
|
|
Private _thFactor As Double = 1
|
|
Private _thFactorNero As Double = 0.4
|
|
Private _bnero As Boolean = False
|
|
|
|
#If WinXp Then
|
|
Private _iterpType As CvEnum.INTER = CvEnum.INTER.CV_INTER_LINEAR
|
|
#Else
|
|
Private _iterpType As CvEnum.Inter = CvEnum.Inter.Linear
|
|
#End If
|
|
|
|
Public Property Image1 As Bitmap
|
|
Set(value As Bitmap)
|
|
DisposeImage1()
|
|
_image1 = value
|
|
End Set
|
|
Get
|
|
Return _image1
|
|
End Get
|
|
End Property
|
|
|
|
Public Property BackImage As Bitmap
|
|
Set(value As Bitmap)
|
|
DisposeBackImage()
|
|
_backImage = value
|
|
End Set
|
|
Get
|
|
Return _backImage
|
|
End Get
|
|
End Property
|
|
Public ReadOnly Property FinalImage As Bitmap
|
|
Get
|
|
Return If(_outimage Is Nothing, Nothing, _outimage.Bitmap)
|
|
End Get
|
|
End Property
|
|
|
|
Public WriteOnly Property BackImageFile As String
|
|
Set(FileName As String)
|
|
|
|
Try
|
|
BackImage = New Bitmap(FileName)
|
|
Catch ex As Exception
|
|
BackImage = Nothing
|
|
End Try
|
|
|
|
Try
|
|
If _backImage IsNot Nothing Then
|
|
Dim EW As New ExifWorks(FileName)
|
|
_focalLength = EW.FocalLength
|
|
_aperture = EW.Aperture
|
|
_iso = EW.ISO
|
|
_exptime = EW.ExposureTime
|
|
EW.Dispose()
|
|
_exifValid = True
|
|
End If
|
|
Catch ex As Exception
|
|
_exifValid = False
|
|
End Try
|
|
|
|
End Set
|
|
End Property
|
|
Public Property ReduceImage As Integer
|
|
Get
|
|
Return _pdown
|
|
End Get
|
|
Set(value As Integer)
|
|
_pdown = value
|
|
End Set
|
|
End Property
|
|
#If WinXp Then
|
|
Property SearchMode As CvEnum.RETR_TYPE
|
|
Set(value As CvEnum.RETR_TYPE)
|
|
_searchMode = value
|
|
End Set
|
|
Get
|
|
Return _searchMode
|
|
End Get
|
|
End Property
|
|
#Else
|
|
Property SearchMode As CvEnum.RetrType
|
|
Set(value As CvEnum.RetrType)
|
|
_searchMode = value
|
|
End Set
|
|
Get
|
|
Return _searchMode
|
|
End Get
|
|
End Property
|
|
#End If
|
|
|
|
Property ExpCorrType As eExpCorrMode
|
|
Get
|
|
Return _expCorrection
|
|
End Get
|
|
Set(value As eExpCorrMode)
|
|
_expCorrection = value
|
|
End Set
|
|
End Property
|
|
Property BorderType As Integer
|
|
Get
|
|
Return _metodoDiff
|
|
End Get
|
|
Set(value As Integer)
|
|
_metodoDiff = value
|
|
End Set
|
|
End Property
|
|
Property ThFactorNero As Double
|
|
Set(value As Double)
|
|
_thFactorNero = value
|
|
End Set
|
|
Get
|
|
Return _thFactorNero
|
|
End Get
|
|
End Property
|
|
Public ReadOnly Property Nero As Boolean
|
|
Get
|
|
Return _bnero
|
|
End Get
|
|
End Property
|
|
''' <summary>
|
|
''' Aggiunge una zona rettangolare pe l'analisi ispezione
|
|
''' </summary>
|
|
''' <remarks></remarks>
|
|
Public Sub AddExpRectangle(xLeft As Integer, yTop As Integer, xRight As Integer, yBottom As Integer)
|
|
|
|
If _rectExp Is Nothing Then
|
|
ReDim _rectExp(0)
|
|
Else
|
|
Array.Resize(_rectExp, _rectExp.Length + 1)
|
|
End If
|
|
|
|
Try
|
|
_rectExp(_rectExp.Length - 1) = New Rectangle(xLeft, yTop, xRight - xLeft, yBottom - yTop)
|
|
Catch ex As Exception
|
|
|
|
End Try
|
|
|
|
End Sub
|
|
Public Sub SetExpRectangle(xLeft As Integer, yTop As Integer, xRight As Integer, yBottom As Integer)
|
|
|
|
' lavora solo sul rectangolo 0
|
|
If _rectExp Is Nothing Then
|
|
ReDim _rectExp(0)
|
|
End If
|
|
|
|
Try
|
|
Dim x1 As Integer = Math.Min(xLeft, xRight)
|
|
Dim y1 As Integer = Math.Min(yTop, yBottom)
|
|
Dim w As Integer = Math.Abs(xRight - xLeft)
|
|
Dim h As Integer = Math.Abs(yBottom - yTop)
|
|
|
|
_rectExp(0) = New Rectangle(x1, y1, w, h)
|
|
Catch ex As Exception
|
|
|
|
End Try
|
|
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' Aggiunge una zona rettangolare pe l'analisi ispezione
|
|
''' </summary>
|
|
''' <remarks></remarks>
|
|
Public Sub SetStoneRectangle(xLeft As Integer, yTop As Integer, xRight As Integer, yBottom As Integer)
|
|
|
|
|
|
Try
|
|
Dim x1 As Integer = Math.Min(xLeft, xRight)
|
|
Dim y1 As Integer = Math.Min(yTop, yBottom)
|
|
Dim w As Integer = Math.Abs(xRight - xLeft)
|
|
Dim h As Integer = Math.Abs(yBottom - yTop)
|
|
|
|
_rectLastra = New Rectangle(x1, y1, w, h)
|
|
Catch ex As Exception
|
|
|
|
End Try
|
|
|
|
End Sub
|
|
Public Sub GetExpRectangle(ByRef xLeft As Integer, ByRef yTop As Integer, ByRef xRight As Integer, ByRef yBottom As Integer)
|
|
|
|
' metto un valore di default
|
|
xLeft = 100
|
|
yTop = 300
|
|
xRight = xLeft + 1000
|
|
yBottom = yTop + 750
|
|
|
|
Try
|
|
|
|
' lavora solo sul rectangolo 0
|
|
If _rectExp IsNot Nothing Then
|
|
With _rectExp(0)
|
|
If .Width > 0 And .Height > 0 Then
|
|
xLeft = .X
|
|
yTop = .Y
|
|
xRight = xLeft + .Width
|
|
yBottom = yTop + .Height
|
|
End If
|
|
End With
|
|
|
|
End If
|
|
|
|
Catch ex As Exception
|
|
|
|
End Try
|
|
|
|
|
|
End Sub
|
|
Public Sub GetStoneRectangle(ByRef xLeft As Integer, ByRef yTop As Integer, ByRef xRight As Integer, ByRef yBottom As Integer)
|
|
|
|
|
|
' lavora solo sul rectangolo 0
|
|
If _rectLastra.Height = 0 OrElse _rectLastra.Width = 0 Then
|
|
' metto un valore di default
|
|
xLeft = 100
|
|
yTop = 300
|
|
xRight = xLeft + 1000
|
|
yBottom = yTop + 750
|
|
Else
|
|
With _rectLastra
|
|
xLeft = .X
|
|
yTop = .Y
|
|
xRight = xLeft + .Width
|
|
yBottom = yTop + .Height
|
|
End With
|
|
|
|
End If
|
|
|
|
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' 'Trova i bordi sommando le differenze deri tre canali
|
|
''' </summary>
|
|
''' <remarks></remarks>
|
|
Public Function TrovaBordiMCh(ByRef trhVal As Integer) As Boolean
|
|
|
|
Console.WriteLine("MODALITÀ RICONOSCIMENTO BORDI: " & MainModule.IndexProc & " -- " & _metodoDiff.ToString)
|
|
Select Case _metodoDiff
|
|
Case 1
|
|
' somma delle differense sui tre canali
|
|
TrovaBordiMCh1(trhVal) ' lavora su img raddrizzata
|
|
Case 2
|
|
' rimossa
|
|
'TrovaBordiMCh2(trhVal)
|
|
Case 3
|
|
' differenza solo sui colori (mai utilizzata)
|
|
TrovaBordiMCh3(trhVal) ' lavora ancora su img non raddrizzata
|
|
Case 4
|
|
' non valuta se lastra bianca o nera (non ha più senso)
|
|
TrovaBordiMCh6(trhVal, False)
|
|
Case 5
|
|
' non usa il background
|
|
TrovaBordiMCh5(trhVal)
|
|
Case 6
|
|
' discreta
|
|
TrovaBordiMCh6(trhVal, True)
|
|
Case 7
|
|
' modalità attualmente migliore
|
|
TrovaBordiMCh7(trhVal, True)
|
|
Case 8
|
|
' in test
|
|
TrovaBordiMCh8()
|
|
Case Else
|
|
Console.WriteLine("MODALITÀ RICONOSCIMENTO NON VALIDA BORDI: " & MainModule.IndexProc)
|
|
Return False
|
|
End Select
|
|
|
|
Return True
|
|
End Function
|
|
|
|
Public Sub ApplicaTreshold(trhVal As Integer)
|
|
|
|
Dim tm As New Stopwatch
|
|
If _imageMng.FinalImage Is Nothing Then Return
|
|
Try
|
|
|
|
Dim t1 As Long
|
|
tm.Start()
|
|
If _metodoDiff = 7 Then
|
|
ApplicaTreshold7(trhVal)
|
|
Else
|
|
_outimage = New Image(Of Emgu.CV.Structure.Rgb, Byte)(_imageMng.FinalImage)
|
|
ApplicaTreshold4(trhVal)
|
|
End If
|
|
t1 = tm.ElapsedMilliseconds
|
|
|
|
Catch ex As Exception
|
|
|
|
End Try
|
|
|
|
End Sub
|
|
|
|
' porta i ciascun pixel alla stessa luminosità e poi fa la differenza dei colori
|
|
' lavora su img NON raddrizzata
|
|
' non è da utilizzare
|
|
Private Sub TrovaBordiMCh3(trhVal As Integer)
|
|
|
|
Try
|
|
|
|
Dim cvimage1 As New Image(Of Emgu.CV.Structure.Bgr, Byte)(_image1)
|
|
Dim cvbackImage As New Image(Of Emgu.CV.Structure.Bgr, Byte)(_backImage)
|
|
|
|
Dim cvimageDiff As Image(Of Emgu.CV.Structure.Gray, Byte) = Nothing
|
|
|
|
For j As Integer = 0 To _pdown
|
|
cvbackImage = cvbackImage.Resize(0.5, _iterpType)
|
|
cvimage1 = cvimage1.Resize(0.5, _iterpType)
|
|
Next
|
|
|
|
Dim add As Double = 0
|
|
Dim factor As Double = 1
|
|
CorreggiEsposizione(_image1, _backImage, add, factor)
|
|
cvimage1 = cvimage1.Mul(factor)
|
|
cvimage1 = cvimage1 + add
|
|
|
|
|
|
Dim nMaxByte As Integer = cvimage1.Width * cvimage1.Height
|
|
Dim maxval As Integer = 0
|
|
Dim minval As Integer = 10000
|
|
Dim nr, nb As Integer
|
|
|
|
Dim fattCol As Double = 1.0
|
|
Dim fatdif As Double = 1
|
|
Dim fr As Double = 1
|
|
Dim fg As Double = 1
|
|
Dim fb As Double = 1
|
|
|
|
ReDim _mm(nMaxByte)
|
|
Array.Clear(_mm, 0, nMaxByte)
|
|
|
|
|
|
For iy = 0 To cvimage1.Height - 1
|
|
|
|
nr = iy * cvimage1.Width
|
|
|
|
For ix = 0 To cvimage1.Width - 1
|
|
|
|
nb = nr + ix
|
|
|
|
Dim ri, gi, bi, smi As Double
|
|
Dim rbk, gbk, bbk, smbk As Double
|
|
|
|
ri = cvimage1.Data(iy, ix, 0)
|
|
gi = cvimage1.Data(iy, ix, 1)
|
|
bi = cvimage1.Data(iy, ix, 2)
|
|
|
|
rbk = cvbackImage.Data(iy, ix, 0)
|
|
gbk = cvbackImage.Data(iy, ix, 1)
|
|
bbk = cvbackImage.Data(iy, ix, 2)
|
|
|
|
|
|
_mm(nb) = fatdif * (Math.Abs(rbk - ri) * fr + Math.Abs(gbk - gi) * fg + Math.Abs(bbk - bi) * fb)
|
|
|
|
smi = ri + gi + bi
|
|
smbk = rbk + gbk + rbk
|
|
Dim rapp As Double = smi / smbk
|
|
If rapp > 1 Then
|
|
rbk = rbk * rapp
|
|
gbk = gbk * rapp
|
|
bbk = bbk * rapp
|
|
Else
|
|
ri = ri / rapp
|
|
gi = gi / rapp
|
|
bi = bi / rapp
|
|
End If
|
|
_mm(nb) = _mm(nb) + fattCol * (Math.Abs(rbk - ri) * fr + Math.Abs(gbk - gi) * fg + Math.Abs(bbk - bi) * fb)
|
|
If _mm(nb) > maxval Then maxval = _mm(nb)
|
|
If _mm(nb) < minval Then minval = _mm(nb)
|
|
Next
|
|
Next
|
|
|
|
minval = (CDbl(maxval) - 255) / 3
|
|
Dim fattConv As Double = 300 / (maxval - minval)
|
|
Dim bvsum As Integer
|
|
|
|
|
|
cvimageDiff = New Image(Of Emgu.CV.Structure.Gray, Byte)(cvimage1.Width, cvimage1.Height)
|
|
|
|
|
|
For iy = 0 To cvimage1.Height - 1
|
|
|
|
nr = iy * cvimage1.Width
|
|
|
|
For ix = 0 To cvimage1.Width - 1
|
|
nb = nr + ix
|
|
bvsum = Convert.ToInt32((_mm(nb) - minval) * fattConv)
|
|
bvsum = Math.Max(bvsum, 0)
|
|
bvsum = Math.Min(bvsum, 255)
|
|
cvimageDiff.Data(iy, ix, 0) = Convert.ToByte(bvsum)
|
|
Next
|
|
Next
|
|
|
|
|
|
#If DEBUG Then
|
|
|
|
Static mostra As Boolean = False
|
|
If mostra Then
|
|
Dim frm2 As FrmImgShow = New FrmImgShow(cvimageDiff)
|
|
frm2.ShowDialog()
|
|
frm2.DisposeForm()
|
|
frm2.Dispose()
|
|
End If
|
|
|
|
Try
|
|
cvimageDiff.Save("C:\temp\diffm3.png")
|
|
Catch ex As Exception
|
|
End Try
|
|
|
|
#End If
|
|
|
|
|
|
|
|
For j As Integer = 0 To _pdown
|
|
cvimageDiff = cvimageDiff.PyrUp
|
|
Next
|
|
|
|
_imageMng.InputImage = cvimageDiff.Bitmap
|
|
_imageMng.CorrezioneCompleta()
|
|
_corImgDiff = New Image(Of Emgu.CV.Structure.Gray, Byte)(_imageMng.FinalImage)
|
|
|
|
' correggo l'immagine originale
|
|
_imageMng.InputImage = _image1
|
|
_imageMng.CorrezioneCompleta()
|
|
_outimage = New Image(Of Emgu.CV.Structure.Rgb, Byte)(_imageMng.FinalImage)
|
|
|
|
' _outimage
|
|
|
|
'ThresholdBinaryInv --> dst(x,y) = if (src(x,y) > trhVal,0,maxVal)
|
|
'-> quello che è variato diventa nero, quello che non è variato resta bianco
|
|
'-> tanto più la variazione sulla lastra è piccola, tanto più posso abbassare trhVal
|
|
' -> il minimo valore pre trhVal è 0
|
|
|
|
ApplicaTreshold(trhVal)
|
|
_imageMng.SaveClickMsg(0)
|
|
|
|
Catch ex As Exception
|
|
Debug.Print("errore")
|
|
_imageMng.SaveClickMsg(1)
|
|
|
|
Finally
|
|
|
|
End Try
|
|
|
|
|
|
|
|
End Sub
|
|
|
|
Private Sub CorreggiEsposizione(Img As Bitmap, imgB As Bitmap, ByRef add As Double, ByRef factor As Double)
|
|
|
|
' aggiusto la luminosità
|
|
Try
|
|
|
|
add = 0
|
|
factor = 1
|
|
|
|
If (_expCorrection <> eExpCorrMode.none AndAlso _rectExp.Length > 0) Then
|
|
|
|
'Dim cvimageg As New Image(Of Emgu.CV.Structure.Gray, Byte)(_image1)
|
|
'Dim cvbackImageg As New Image(Of Emgu.CV.Structure.Gray, Byte)(_backImage)
|
|
|
|
Dim cvimageg As New Image(Of Emgu.CV.Structure.Gray, Byte)(Img)
|
|
Dim cvbackImageg As New Image(Of Emgu.CV.Structure.Gray, Byte)(imgB)
|
|
|
|
Dim mbk, mi As CV.Structure.Gray
|
|
Dim bkintensity As Double = 0
|
|
Dim imgintensity As Double = 0
|
|
Dim listrapp As New List(Of Double)
|
|
Dim listAdd As New List(Of Double)
|
|
Dim ResultDiff As Double = 0
|
|
Dim sumrapp As Double = 0
|
|
|
|
For i As Integer = 0 To _rectExp.Length - 1
|
|
|
|
cvbackImageg.ROI = _rectExp(i)
|
|
cvimageg.ROI = _rectExp(i)
|
|
|
|
|
|
#If DEBUG Then
|
|
cvimageg.Save("c:\temp\img" & i.ToString & ".png")
|
|
cvbackImageg.Save("c:\temp\back" & i & ".png")
|
|
#End If
|
|
|
|
mbk = cvbackImageg.GetAverage()
|
|
mi = cvimageg.GetAverage()
|
|
cvbackImageg.ROI = Nothing
|
|
cvimageg.ROI = Nothing
|
|
If mbk.Intensity > 10 AndAlso mi.Intensity > 10 Then
|
|
listrapp.Add(mbk.Intensity / mi.Intensity)
|
|
listAdd.Add(mbk.Intensity - mi.Intensity)
|
|
ResultDiff = ResultDiff + mbk.Intensity - mi.Intensity
|
|
sumrapp += mbk.Intensity / mi.Intensity
|
|
End If
|
|
|
|
#If DEBUG Then
|
|
' cvbackImage.Draw(_rectExp(i), New Bgr(255, 255, 0), 5)
|
|
#End If
|
|
Next
|
|
|
|
Dim rapp As Double = 10
|
|
Dim rok As Integer = 0
|
|
Dim addok As Integer = 0
|
|
Dim addfin As Integer = 255
|
|
|
|
For i = 0 To listrapp.Count - 1
|
|
If listrapp(i) > 1 And listrapp(i) < rapp Then
|
|
rapp = listrapp(i)
|
|
rok = i
|
|
End If
|
|
If listrapp(i) < 1 And 1 / listrapp(i) < rapp Then
|
|
rapp = 1 / listrapp(i)
|
|
rok = i
|
|
End If
|
|
If listAdd(i) > 0 And listAdd(i) < addfin Then
|
|
addfin = listAdd(i)
|
|
addok = i
|
|
End If
|
|
If listAdd(i) < 0 And listAdd(i) > -addfin Then
|
|
addfin = listAdd(i)
|
|
addok = i
|
|
End If
|
|
|
|
Next
|
|
Select Case _expCorrection
|
|
Case eExpCorrMode.minFactor
|
|
add = 0
|
|
factor = listrapp(rok)
|
|
Case eExpCorrMode.AvgFactor
|
|
add = 0
|
|
factor = sumrapp / listrapp.Count
|
|
Case eExpCorrMode.minAdd
|
|
add = listAdd(addok)
|
|
factor = 1
|
|
Case eExpCorrMode.avgAdd
|
|
factor = 1
|
|
add = ResultDiff / listrapp.Count
|
|
End Select
|
|
|
|
cvimageg.Dispose()
|
|
cvbackImageg.Dispose()
|
|
|
|
|
|
End If
|
|
|
|
Catch ex As Exception
|
|
|
|
End Try
|
|
|
|
|
|
|
|
End Sub
|
|
|
|
Private Sub CheckIfStoneDark(Img As Bitmap, imgB As Bitmap, ByRef dark As Boolean)
|
|
|
|
' aggiusto la luminosità
|
|
dark = False
|
|
Try
|
|
|
|
Dim cvimageg As New Image(Of Emgu.CV.Structure.Gray, Byte)(Img)
|
|
Dim cvbackImageg As New Image(Of Emgu.CV.Structure.Gray, Byte)(imgB)
|
|
Dim mbk, mi As CV.Structure.Gray
|
|
|
|
cvbackImageg.ROI = _rectLastra
|
|
cvimageg.ROI = _rectLastra
|
|
|
|
#If DEBUG Then
|
|
cvimageg.Save("c:\temp\RectEvalBN.png")
|
|
cvbackImageg.Save("c:\temp\RectEvalBNB.png")
|
|
#End If
|
|
|
|
mbk = cvbackImageg.GetAverage()
|
|
mi = cvimageg.GetAverage()
|
|
cvbackImageg.ROI = Nothing
|
|
cvimageg.ROI = Nothing
|
|
If mbk.Intensity < 10 Then Return
|
|
|
|
Dim rIntensity As Double = mi.Intensity / mbk.Intensity
|
|
|
|
dark = rIntensity < _darkRappLevel
|
|
|
|
Catch ex As Exception
|
|
|
|
End Try
|
|
|
|
|
|
End Sub
|
|
Private Sub CheckIfStoneDark(Img As Bitmap, ByRef dark As Boolean)
|
|
|
|
'Check senza usare il background
|
|
|
|
dark = False
|
|
Try
|
|
|
|
Dim cvimageg As New Image(Of Emgu.CV.Structure.Gray, Byte)(Img)
|
|
Dim mi As CV.Structure.Gray
|
|
|
|
cvimageg.ROI = _rectLastra
|
|
|
|
#If DEBUG Then
|
|
cvimageg.Save("c:\temp\RectEvalBN.png")
|
|
#End If
|
|
|
|
mi = cvimageg.GetAverage()
|
|
|
|
dark = mi.Intensity < 130
|
|
|
|
Catch ex As Exception
|
|
|
|
End Try
|
|
|
|
|
|
End Sub
|
|
' differenza sui tre canali
|
|
' corregge l'immagine prima di confrontare
|
|
Private Sub TrovaBordiMCh1(trhVal As Integer)
|
|
|
|
Try
|
|
|
|
Dim cvimage1Ch As Image(Of Emgu.CV.Structure.Gray, Byte)
|
|
Dim cvbackImageCh As Image(Of Emgu.CV.Structure.Gray, Byte)
|
|
|
|
' Se non c'è il back raddrizzato, lo raddrizzo
|
|
If _convBackImage Is Nothing Then
|
|
ConvertBackImage()
|
|
End If
|
|
|
|
If _convBackImage Is Nothing Then
|
|
Debug.Assert(False)
|
|
Return
|
|
End If
|
|
|
|
Dim cvbackImage As New Image(Of Emgu.CV.Structure.Bgr, Byte)(_convBackImage)
|
|
|
|
_imageMng.InputImage = _image1
|
|
_imageMng.CorrezioneCompleta()
|
|
|
|
_outimage = New Image(Of Emgu.CV.Structure.Rgb, Byte)(_imageMng.FinalImage)
|
|
Dim cvimage1 As New Image(Of Emgu.CV.Structure.Bgr, Byte)(_imageMng.FinalImage)
|
|
|
|
|
|
Dim add As Double = 0
|
|
Dim factor As Double = 1
|
|
CorreggiEsposizione(_outimage.Bitmap, _convBackImage, add, factor)
|
|
cvimage1 = cvimage1 * factor
|
|
cvimage1 = cvimage1 + add
|
|
|
|
For j As Integer = 0 To _pdown - 1
|
|
cvimage1 = cvimage1.Resize(0.5, _iterpType)
|
|
cvbackImage = cvbackImage.Resize(0.5, _iterpType)
|
|
Next
|
|
|
|
cvimage1Ch = cvimage1.Split(0)
|
|
cvbackImageCh = cvbackImage.Split(0)
|
|
_corImgDiff = cvbackImageCh.AbsDiff(cvimage1Ch) * 0.33
|
|
|
|
#If DEBUG Then
|
|
cvbackImageCh.AbsDiff(cvimage1Ch).Save("c:\temp\diffch0.png")
|
|
#End If
|
|
|
|
cvimage1Ch = cvimage1.Split(1)
|
|
cvbackImageCh = cvbackImage.Split(1)
|
|
|
|
_corImgDiff = _corImgDiff + cvbackImageCh.AbsDiff(cvimage1Ch) * 0.33
|
|
|
|
|
|
#If DEBUG Then
|
|
cvbackImageCh.AbsDiff(cvimage1Ch).Save("c:\temp\diffch1.png")
|
|
#End If
|
|
|
|
|
|
cvbackImageCh.Dispose()
|
|
cvimage1Ch.Dispose()
|
|
GC.Collect()
|
|
|
|
cvimage1Ch = cvimage1.Split(2)
|
|
cvbackImageCh = cvbackImage.Split(2)
|
|
|
|
_corImgDiff = _corImgDiff + cvbackImageCh.AbsDiff(cvimage1Ch) * 0.33
|
|
|
|
|
|
#If DEBUG Then
|
|
cvbackImageCh.AbsDiff(cvimage1Ch).Save("c:\temp\diffch2.png")
|
|
#End If
|
|
|
|
|
|
|
|
|
|
#If DEBUG Then
|
|
_corImgDiff.Save("c:\temp\img0.png")
|
|
#End If
|
|
|
|
|
|
' _outimage
|
|
|
|
'ThresholdBinaryInv --> dst(x,y) = if (src(x,y) > trhVal,0,maxVal)
|
|
'-> quello che è variato diventa nero, quello che non è variato resta bianco
|
|
'-> tanto più la variazione sulla lastra è piccola, tanto più posso abbassare trhVal
|
|
' -> il minimo valore pre trhVal è 0
|
|
|
|
For j As Integer = 0 To _pdown - 1
|
|
_corImgDiff = _corImgDiff.PyrUp
|
|
Next
|
|
|
|
ApplicaTreshold(trhVal)
|
|
_imageMng.SaveClickMsg(0)
|
|
|
|
Catch ex As Exception
|
|
Debug.Print("errore")
|
|
_imageMng.SaveClickMsg(1)
|
|
|
|
Finally
|
|
|
|
End Try
|
|
|
|
|
|
|
|
End Sub
|
|
|
|
Public ReadOnly Property IsInError As Boolean
|
|
Get
|
|
Return (_error <> Errors.None)
|
|
End Get
|
|
End Property
|
|
|
|
Private Sub DisposeImage1()
|
|
If _image1 IsNot Nothing Then
|
|
_image1.Dispose()
|
|
_image1 = Nothing
|
|
End If
|
|
|
|
End Sub
|
|
Private Sub DisposeBackImage()
|
|
If _backImage IsNot Nothing Then
|
|
_backImage.Dispose()
|
|
_backImage = Nothing
|
|
End If
|
|
If _convBackImage IsNot Nothing Then
|
|
_convBackImage.Dispose()
|
|
_convBackImage = Nothing
|
|
End If
|
|
End Sub
|
|
|
|
Private Function CorreggiPunti(p As Array) As Array
|
|
Dim po(p.Length - 1) As Point
|
|
|
|
For i As Integer = 0 To p.Length - 1
|
|
po(i) = _imageMng.CorreggiPunto(p(i))
|
|
Next
|
|
|
|
Return po
|
|
|
|
End Function
|
|
|
|
#If WinXp Then
|
|
Private Sub DebugSuDxf(writer As StreamWriter, p As Array)
|
|
#Else
|
|
Private Sub DebugSuDxf(writer As StreamWriter, p As VectorOfPoint)
|
|
#End If
|
|
|
|
|
|
Dim ZL As Double = 10
|
|
Dim i As Integer
|
|
#If WinXp Then
|
|
Dim lung As Integer = p.Length
|
|
#Else
|
|
Dim lung As Integer = p.Size
|
|
#End If
|
|
|
|
|
|
For i = 1 To lung - 1
|
|
|
|
writer.WriteLine("LINE")
|
|
writer.WriteLine("8")
|
|
writer.WriteLine("0")
|
|
writer.WriteLine("10")
|
|
writer.WriteLine(p(i - 1).X.ToString)
|
|
writer.WriteLine("20")
|
|
writer.WriteLine(p(i - 1).Y.ToString)
|
|
writer.WriteLine("30")
|
|
writer.WriteLine("0")
|
|
writer.WriteLine("11")
|
|
writer.WriteLine(p(i).X.ToString)
|
|
writer.WriteLine("21")
|
|
writer.WriteLine(p(i).Y.ToString)
|
|
writer.WriteLine("31")
|
|
writer.WriteLine(0)
|
|
writer.WriteLine("0")
|
|
Next
|
|
|
|
i = lung
|
|
writer.WriteLine("LINE")
|
|
writer.WriteLine("8")
|
|
writer.WriteLine("0")
|
|
writer.WriteLine("10")
|
|
writer.WriteLine(p(i - 1).X.ToString)
|
|
writer.WriteLine("20")
|
|
writer.WriteLine(p(i - 1).Y.ToString)
|
|
writer.WriteLine("30")
|
|
writer.WriteLine("0")
|
|
writer.WriteLine("11")
|
|
writer.WriteLine(p(0).X.ToString)
|
|
writer.WriteLine("21")
|
|
writer.WriteLine(p(0).Y.ToString)
|
|
writer.WriteLine("31")
|
|
writer.WriteLine(0)
|
|
writer.WriteLine("0")
|
|
|
|
|
|
End Sub
|
|
|
|
Public Sub New(imgMng As clsImageMng)
|
|
_imageMng = imgMng
|
|
End Sub
|
|
|
|
' differenza sul blu o sul giallo senza backg
|
|
' lavora sull'immagine raddrizzata
|
|
Private Sub TrovaBordiMCh5(trhVal As Integer)
|
|
|
|
|
|
Try
|
|
|
|
Dim cvimage1Ch As Image(Of Emgu.CV.Structure.Gray, Byte)
|
|
|
|
|
|
_imageMng.InputImage = _image1
|
|
_imageMng.CorrezioneCompleta()
|
|
|
|
_outimage = New Image(Of Emgu.CV.Structure.Rgb, Byte)(_imageMng.FinalImage)
|
|
Dim cvimage1 As New Image(Of Emgu.CV.Structure.Bgr, Byte)(_imageMng.FinalImage)
|
|
|
|
|
|
|
|
CheckIfStoneDark(cvimage1.Bitmap, _bnero)
|
|
|
|
For j As Integer = 0 To _pdown - 1
|
|
cvimage1 = cvimage1.Resize(0.5, _iterpType)
|
|
Next
|
|
|
|
If _bnero Then
|
|
cvimage1Ch = (255 - cvimage1.Split(1)) ' * 0.5
|
|
cvimage1Ch = ScaleGrayTo(127, cvimage1Ch)
|
|
|
|
_corImgDiff = cvimage1Ch
|
|
|
|
#If DEBUG Then
|
|
_corImgDiff.Save("c:\temp\ch1.png")
|
|
#End If
|
|
|
|
'cvimage1Ch.Dispose()
|
|
'GC.Collect()
|
|
|
|
' Canale G
|
|
cvimage1Ch = (255 - cvimage1.Split(2)) ' * 0.5
|
|
cvimage1Ch = ScaleGrayTo(127, cvimage1Ch)
|
|
|
|
_corImgDiff = _corImgDiff + cvimage1Ch
|
|
|
|
#If DEBUG Then
|
|
cvimage1Ch.Save("c:\temp\ch2.png")
|
|
#End If
|
|
|
|
|
|
|
|
Else
|
|
' Canale b
|
|
_corImgDiff = ScaleGrayTo(255, cvimage1.Split(0))
|
|
End If
|
|
|
|
|
|
|
|
#If DEBUG Then
|
|
_corImgDiff.Save("c:\temp\img0.png")
|
|
#End If
|
|
|
|
|
|
' _outimage
|
|
|
|
'ThresholdBinaryInv --> dst(x,y) = if (src(x,y) > trhVal,0,maxVal)
|
|
'-> quello che è variato diventa nero, quello che non è variato resta bianco
|
|
'-> tanto più la variazione sulla lastra è piccola, tanto più posso abbassare trhVal
|
|
' -> il minimo valore pre trhVal è 0
|
|
|
|
For j As Integer = 0 To _pdown - 1
|
|
_corImgDiff = _corImgDiff.PyrUp
|
|
Next
|
|
|
|
ApplicaTreshold(trhVal)
|
|
_imageMng.SaveClickMsg(0)
|
|
|
|
Catch ex As Exception
|
|
Debug.Print("errore")
|
|
_imageMng.SaveClickMsg(1)
|
|
|
|
Finally
|
|
|
|
End Try
|
|
|
|
|
|
|
|
End Sub
|
|
' differenza distinguendo se lastra bianca o nera
|
|
' lavora su immagine raddrizzata
|
|
Private Sub TrovaBordiMCh6(trhVal As Integer, valutaBiancoNero As Boolean)
|
|
|
|
Try
|
|
|
|
Dim cvimage1Ch As Image(Of Emgu.CV.Structure.Gray, Byte)
|
|
Dim cvbackImageCh As Image(Of Emgu.CV.Structure.Gray, Byte)
|
|
|
|
' Se non c'è il back raddrizzato, lo raddrizzo
|
|
If _convBackImage Is Nothing Then
|
|
ConvertBackImage()
|
|
End If
|
|
|
|
If _convBackImage Is Nothing Then
|
|
Debug.Assert(False)
|
|
Return
|
|
End If
|
|
|
|
Dim cvbackImage As New Image(Of Emgu.CV.Structure.Bgr, Byte)(_convBackImage)
|
|
|
|
_imageMng.InputImage = _image1
|
|
_imageMng.CorrezioneCompleta()
|
|
|
|
_outimage = New Image(Of Emgu.CV.Structure.Rgb, Byte)(_imageMng.FinalImage)
|
|
Dim cvimage1 As New Image(Of Emgu.CV.Structure.Bgr, Byte)(_imageMng.FinalImage)
|
|
|
|
|
|
Dim add As Double = 0
|
|
Dim factor As Double = 1
|
|
CorreggiEsposizione(_outimage.Bitmap, _convBackImage, add, factor)
|
|
cvimage1 = cvimage1 * factor
|
|
cvimage1 = cvimage1 + add
|
|
|
|
_thFactor = 1
|
|
_bnero = False
|
|
|
|
If valutaBiancoNero Then
|
|
|
|
CheckIfStoneDark(cvimage1.Bitmap, _convBackImage, _bnero)
|
|
If _bnero Then
|
|
_thFactor = _thFactorNero
|
|
End If
|
|
|
|
End If
|
|
|
|
For j As Integer = 0 To _pdown - 1
|
|
|
|
cvimage1 = cvimage1.Resize(0.5, _iterpType)
|
|
cvbackImage = cvbackImage.Resize(0.5, _iterpType)
|
|
Next
|
|
|
|
|
|
If _bnero Then
|
|
cvimage1Ch = (255 - cvimage1.Split(1)) * 0.5
|
|
cvbackImageCh = (255 - cvbackImage.Split(1)) * 0.5
|
|
|
|
_corImgDiff = cvbackImageCh.AbsDiff(cvimage1Ch)
|
|
_corImgDiff = ScaleGrayTo(127, _corImgDiff)
|
|
|
|
|
|
#If DEBUG Then
|
|
_corImgDiff.Save("c:\temp\diffch1.png")
|
|
#End If
|
|
|
|
cvbackImageCh.Dispose()
|
|
cvimage1Ch.Dispose()
|
|
GC.Collect()
|
|
|
|
' Canale G
|
|
cvimage1Ch = (255 - cvimage1.Split(2)) * 0.5
|
|
cvbackImageCh = (255 - cvbackImage.Split(2)) * 0.5
|
|
|
|
_corImgDiff = _corImgDiff + ScaleGrayTo(127, cvbackImageCh.AbsDiff(cvimage1Ch))
|
|
_corImgDiff = ScaleGrayTo(255, _corImgDiff)
|
|
|
|
#If DEBUG Then
|
|
cvbackImageCh.AbsDiff(cvimage1Ch).Save("c:\temp\diffch2.png")
|
|
#End If
|
|
|
|
|
|
Else
|
|
' Canale b
|
|
_corImgDiff = cvbackImage.Split(0).AbsDiff(cvimage1.Split(0))
|
|
_corImgDiff = ScaleGrayTo(255, _corImgDiff)
|
|
End If
|
|
|
|
|
|
|
|
#If DEBUG Then
|
|
_corImgDiff.Save("c:\temp\img0.png")
|
|
#End If
|
|
|
|
|
|
' _outimage
|
|
|
|
'ThresholdBinaryInv --> dst(x,y) = if (src(x,y) > trhVal,0,maxVal)
|
|
'-> quello che è variato diventa nero, quello che non è variato resta bianco
|
|
'-> tanto più la variazione sulla lastra è piccola, tanto più posso abbassare trhVal
|
|
' -> il minimo valore pre trhVal è 0
|
|
|
|
For j As Integer = 0 To _pdown - 1
|
|
_corImgDiff = _corImgDiff.PyrUp
|
|
Next
|
|
|
|
ApplicaTreshold(trhVal)
|
|
_imageMng.SaveClickMsg(0)
|
|
|
|
Catch ex As Exception
|
|
Debug.Print("errore")
|
|
_imageMng.SaveClickMsg(1)
|
|
|
|
Finally
|
|
|
|
End Try
|
|
|
|
End Sub
|
|
|
|
Private Sub TrovaBordiMCh7(trhVal As Integer, valutaBiancoNero As Boolean)
|
|
Try
|
|
' Ripolisco la memoria
|
|
DisposePreviousImages()
|
|
|
|
' Se non c'è il back raddrizzato, lo raddrizzo
|
|
Console.WriteLine("PREPARAZIONE BACK IMAGE: " & MainModule.IndexProc)
|
|
If _convBackImage Is Nothing Then
|
|
ConvertBackImage()
|
|
End If
|
|
|
|
If _convBackImage Is Nothing Then
|
|
Debug.Assert(False)
|
|
Console.WriteLine("BACK IMAGE NON DISPONIBILE: " & MainModule.IndexProc)
|
|
Return
|
|
End If
|
|
|
|
Dim cvbackImage As New Image(Of Emgu.CV.Structure.Bgr, Byte)(_convBackImage)
|
|
|
|
Console.WriteLine("PREPARAZIONE SLAB IMAGE: " & MainModule.IndexProc)
|
|
_imageMng.InputImage = _image1
|
|
_imageMng.CorrezioneCompleta()
|
|
|
|
_outimage = New Image(Of Emgu.CV.Structure.Rgb, Byte)(_imageMng.FinalImage)
|
|
' creo una copia dell'immagine ivertendo l'ordine dei primi 2 canali
|
|
Dim cvimage1 As New Image(Of Emgu.CV.Structure.Bgr, Byte)(_imageMng.FinalImage)
|
|
|
|
Dim add As Double = 0
|
|
Dim factor As Double = 1
|
|
CorreggiEsposizione(_outimage.Bitmap, _convBackImage, add, factor)
|
|
cvimage1 = cvimage1 * factor
|
|
cvimage1 = cvimage1 + add
|
|
|
|
_thFactor = 1
|
|
_bnero = False
|
|
|
|
If valutaBiancoNero Then
|
|
|
|
CheckIfStoneDark(cvimage1.Bitmap, _convBackImage, _bnero)
|
|
If _bnero Then
|
|
_thFactor = _thFactorNero
|
|
End If
|
|
|
|
End If
|
|
|
|
' Ridimensiono l'immaggine del 50% applicando un'iterpolazione di scala
|
|
For j As Integer = 0 To _pdown - 1
|
|
cvimage1 = cvimage1.Resize(0.5, _iterpType)
|
|
cvbackImage = cvbackImage.Resize(0.5, _iterpType)
|
|
Next
|
|
|
|
' Calcola la differenza assoluta pixel per pixel tra due immagini per ogni canele (0:B, 1:G, 2:R)
|
|
_corImgDiff0 = ScaleGrayTo(255, cvbackImage.Split(0).AbsDiff(cvimage1.Split(0)))
|
|
_corImgDiff1 = ScaleGrayTo(255, cvbackImage.Split(1).AbsDiff(cvimage1.Split(1)))
|
|
_corImgDiff2 = ScaleGrayTo(255, cvbackImage.Split(2).AbsDiff(cvimage1.Split(2)))
|
|
|
|
|
|
|
|
#If DEBUG Then
|
|
_corImgDiff0.Save("c:\temp\diffch0.png")
|
|
_corImgDiff1.Save("c:\temp\diffch1.png")
|
|
_corImgDiff2.Save("c:\temp\diffch2.png")
|
|
#End If
|
|
|
|
|
|
'For j As Integer = 0 To _pdown - 1
|
|
' _corImgDiff0 = _corImgDiff0.PyrUp
|
|
' _corImgDiff1 = _corImgDiff1.PyrUp
|
|
' _corImgDiff2 = _corImgDiff2.PyrUp
|
|
'Next
|
|
|
|
ApplicaTreshold7(trhVal)
|
|
_imageMng.SaveClickMsg(0)
|
|
|
|
Catch ex As Exception
|
|
Debug.Print("errore")
|
|
_imageMng.SaveClickMsg(1)
|
|
|
|
Finally
|
|
|
|
End Try
|
|
|
|
End Sub
|
|
|
|
Private Sub TrovaBordiMCh8()
|
|
|
|
#If WinXp Then
|
|
#Else
|
|
' in test, basato sui template (non sembra gran che)
|
|
Try
|
|
|
|
Dim resultImage As Emgu.CV.Image(Of Emgu.CV.Structure.Gray, Single)
|
|
Dim regione As System.Drawing.Rectangle = Nothing
|
|
Dim reg2 As System.Drawing.Rectangle = Nothing
|
|
Dim x0, y0 As Integer
|
|
Dim minscore As Double = 0.4
|
|
|
|
|
|
' Se non c'è il back raddrizzato, lo raddrizzo
|
|
If _convBackImage Is Nothing Then
|
|
ConvertBackImage()
|
|
End If
|
|
|
|
If _convBackImage Is Nothing Then
|
|
Debug.Assert(False)
|
|
Return
|
|
End If
|
|
|
|
Dim cvbackImage As New Image(Of Emgu.CV.Structure.Bgr, Byte)(_convBackImage)
|
|
|
|
_imageMng.InputImage = _image1
|
|
_imageMng.CorrezioneCompleta()
|
|
|
|
_outimage = New Image(Of Emgu.CV.Structure.Rgb, Byte)(_imageMng.FinalImage)
|
|
Dim cvimage1 As New Image(Of Emgu.CV.Structure.Bgr, Byte)(_imageMng.FinalImage)
|
|
|
|
Dim w As Integer = cvimage1.Width
|
|
Dim h As Integer = cvimage1.Height
|
|
Dim lato As Integer = 250
|
|
|
|
For x0 = 1 To w - lato - 1 Step lato / 2
|
|
For y0 = 1 To h - lato - 1 Step lato / 2
|
|
cvimage1.ROI = Nothing
|
|
cvbackImage.ROI = Nothing
|
|
regione = New System.Drawing.Rectangle(x0, y0, lato, lato)
|
|
reg2 = New System.Drawing.Rectangle(x0 + 5, y0 + 5, lato - 5, lato - 5)
|
|
|
|
cvimage1.ROI = regione
|
|
cvbackImage.ROI = regione
|
|
|
|
resultImage = cvimage1.MatchTemplate(cvbackImage, Emgu.CV.CvEnum.TemplateMatchingType.CcoeffNormed)
|
|
|
|
Dim min() As Double = Nothing, max() As Double = Nothing
|
|
Dim point1() As Point = Nothing, point2() As Point = Nothing
|
|
|
|
resultImage.MinMax(min, max, point1, point2)
|
|
If max(0) < minscore Then
|
|
Emgu.CV.CvInvoke.Line(_outimage, New Point(x0, y0), New Point(x0 + lato, y0),
|
|
New Emgu.CV.Structure.MCvScalar(0, 255, 0), 5, Emgu.CV.CvEnum.LineType.FourConnected, 0)
|
|
Emgu.CV.CvInvoke.Line(_outimage, New Point(x0 + lato, y0), New Point(x0 + lato, y0 + lato),
|
|
New Emgu.CV.Structure.MCvScalar(0, 255, 0), 5, Emgu.CV.CvEnum.LineType.FourConnected, 0)
|
|
Emgu.CV.CvInvoke.Line(_outimage, New Point(x0 + lato, y0 + lato), New Point(x0, y0 + lato),
|
|
New Emgu.CV.Structure.MCvScalar(0, 255, 0), 5, Emgu.CV.CvEnum.LineType.FourConnected, 0)
|
|
Emgu.CV.CvInvoke.Line(_outimage, New Point(x0, y0 + lato), New Point(x0, y0),
|
|
New Emgu.CV.Structure.MCvScalar(0, 255, 0), 5, Emgu.CV.CvEnum.LineType.FourConnected, 0)
|
|
End If
|
|
|
|
|
|
Next
|
|
Next
|
|
|
|
|
|
_imageMng.SaveClickMsg(0)
|
|
|
|
Catch ex As Exception
|
|
Debug.Print("errore")
|
|
_imageMng.SaveClickMsg(1)
|
|
|
|
Finally
|
|
|
|
End Try
|
|
|
|
#End If
|
|
|
|
End Sub
|
|
|
|
' ------------------------------------------- PROVA PROVA PROVA PROVA -------------------------------------------
|
|
Private Function NuovoRiconoscimentoBordi() As Image(Of Gray, Byte)
|
|
Dim edges As Image(Of Gray, Byte)
|
|
Dim thresholdValue As Double = 20
|
|
Dim bOk As Boolean = False
|
|
|
|
While Not bOk
|
|
' Carica l'immagine
|
|
Dim originalImage As Image(Of Bgr, Byte) = New Image(Of Bgr, Byte)(_imageMng.FinalImage)
|
|
' Carico l'immagine di sfondo
|
|
Dim backgroundImage As Image(Of Bgr, Byte) = New Image(Of Bgr, Byte)(_convBackImage)
|
|
' Creo un'immagine data dalla differenza dei valori tra le
|
|
Dim diffImage As Image(Of Bgr, Byte) = New Image(Of Bgr, Byte)(originalImage.Size)
|
|
CvInvoke.AbsDiff(originalImage, backgroundImage, diffImage)
|
|
' Converto l'immagine nella scala dei grigi
|
|
Dim grayDiff As Image(Of Gray, Byte) = diffImage.Convert(Of Gray, Byte)()
|
|
' Crea una maschera
|
|
Dim mask As Image(Of Gray, Byte) = New Image(Of Gray, Byte)(originalImage.Size)
|
|
' ciclo su ogni pixel visto che il codice non funziona ->CvInvoke.Set(mask, New MCvScalar(2))
|
|
For y As Integer = 0 To mask.Height - 1
|
|
For x As Integer = 0 To mask.Width - 1
|
|
mask.Data(y, x, 0) = 2 ' Imposta il pixel a 2
|
|
Next
|
|
Next
|
|
|
|
' I pixel della differenza che superano la soglia sono probabile foreground (3)
|
|
Dim tempBinaryMask As Image(Of Gray, Byte) = New Image(Of Gray, Byte)(originalImage.Size)
|
|
CvInvoke.Threshold(grayDiff, tempBinaryMask, thresholdValue, 255, Emgu.CV.CvEnum.ThresholdType.Binary)
|
|
' In forma estesa quello che avvien nel metodo BitwiseAnd
|
|
For y As Integer = 0 To mask.Height - 1
|
|
For x As Integer = 0 To mask.Width - 1
|
|
If tempBinaryMask.Data(y, x, 0) = 255 Then ' Se c'è una differenza significativa
|
|
mask.Data(y, x, 0) = 3 ' Imposta a probabile primo piano
|
|
End If
|
|
Next
|
|
Next
|
|
|
|
' PASSO 3: Identifica le aree di SFONDO CERTO (0 - GC_BGD)
|
|
Dim borderSize As Integer = 10 ' Ad esempio, 10 pixel dal bordo (regola se necessario)
|
|
For y As Integer = 0 To mask.Height - 1
|
|
For x As Integer = 0 To mask.Width - 1
|
|
If x < borderSize OrElse x >= mask.Width - borderSize OrElse
|
|
y < borderSize OrElse y >= mask.Height - borderSize Then
|
|
mask.Data(y, x, 0) = 0 ' Imposta a Sfondo Certo (GC_BGD)
|
|
End If
|
|
Next
|
|
Next
|
|
|
|
mask.Save(SaveDir & "mask__.png")
|
|
tempBinaryMask.Save(SaveDir & "tempBinaryMask__.png")
|
|
|
|
Dim outerRect As New Rectangle(0, 0, mask.Width, mask.Height)
|
|
|
|
Dim knownForegroundRect As New Rectangle(
|
|
CInt(mask.Width * 0.4), CInt(mask.Height * 0.4),
|
|
CInt(mask.Width * 0.2), CInt(mask.Height * 0.2)
|
|
)
|
|
If knownForegroundRect.X >= 0 AndAlso knownForegroundRect.Y >= 0 AndAlso
|
|
knownForegroundRect.Right <= mask.Width AndAlso knownForegroundRect.Bottom <= mask.Height Then
|
|
Dim roiMask As Image(Of Gray, Byte) = mask.GetSubRect(knownForegroundRect)
|
|
' CvInvoke.Set(roiMask, New MCvScalar(1)) ' Imposta a primo piano certo
|
|
For y As Integer = 0 To roiMask.Height - 1
|
|
For x As Integer = 0 To roiMask.Width - 1
|
|
roiMask.Data(y, x, 0) = 1 ' Imposta il pixel a 2
|
|
Next
|
|
Next
|
|
|
|
Else
|
|
MessageBox.Show("Il rettangolo di foreground certo è fuori dai limiti dell'immagine. Potrebbe influire sulla precisione.", "Avviso", MessageBoxButtons.OK, MessageBoxIcon.Warning)
|
|
End If
|
|
|
|
Dim maskOutput As Image(Of Gray, Byte) = New Image(Of Gray, Byte)(originalImage.Size)
|
|
' Copia la maschera iniziale nella maschera di output per l'input di GrabCut
|
|
mask.CopyTo(maskOutput)
|
|
|
|
Dim invalidPixelsCount As Integer = 0
|
|
For y As Integer = 0 To mask.Height - 1
|
|
For x As Integer = 0 To mask.Width - 1
|
|
Dim pixelVal As Byte = mask.Data(y, x, 0)
|
|
If pixelVal <> 0 AndAlso pixelVal <> 1 AndAlso pixelVal <> 2 AndAlso pixelVal <> 3 Then
|
|
invalidPixelsCount += 1
|
|
End If
|
|
Next
|
|
Next
|
|
If invalidPixelsCount > 0 Then
|
|
MessageBox.Show($"ATTENZIONE: Trovati {invalidPixelsCount} pixel con valori non validi nella maschera iniziale!", "Errore Maschera", MessageBoxButtons.OK, MessageBoxIcon.Error)
|
|
End If
|
|
|
|
Using bgdModel As Mat = New Mat()
|
|
Using fgdModel As Mat = New Mat()
|
|
|
|
Dim fullRect As Rectangle = New Rectangle(0, 0, originalImage.Width, originalImage.Height) ' Rettangolo che copre tutta l'immagine
|
|
|
|
' Ora GrabCut dovrebbe avere i campioni necessari per bgdModel e fgdModel
|
|
CvInvoke.GrabCut(originalImage, maskOutput, fullRect, bgdModel, fgdModel, 5, Emgu.CV.CvEnum.GrabcutInitType.InitWithMask)
|
|
|
|
End Using
|
|
End Using
|
|
|
|
' --- 4. Post-elaborazione della maschera di output di GrabCut ---
|
|
For y As Integer = 0 To maskOutput.Height - 1
|
|
For x As Integer = 0 To maskOutput.Width - 1
|
|
Dim pixelValue As Byte = maskOutput.Data(y, x, 0)
|
|
If pixelValue = 1 OrElse pixelValue = 3 Then ' GC_FGD (1) o GC_PR_FGD (3)
|
|
maskOutput.Data(y, x, 0) = 255 ' Primo piano (bianco)
|
|
Else ' GC_BGD (0) o GC_PR_BGD (2)
|
|
maskOutput.Data(y, x, 0) = 0 ' Sfondo (nero)
|
|
End If
|
|
Next
|
|
Next
|
|
|
|
' --- 5. Applica la maschera all'immagine originale ---
|
|
Using foreground As Image(Of Bgr, Byte) = originalImage.Copy(maskOutput)
|
|
foreground.Save(SaveDir & "EDGES_TEST.png")
|
|
End Using
|
|
|
|
' Gestione semplificata -----
|
|
'Dim maskOutput As Image(Of Gray, Byte) = New Image(Of Gray, Byte)(originalImage.Size)
|
|
'' Copia la maschera iniziale nella maschera di output per l'input di GrabCut
|
|
'mask.CopyTo(maskOutput)
|
|
'
|
|
'Dim cannyThreshold As Double = thresholdValue
|
|
'Dim cannyThresholdLinking As Double = 12 ' Deve essere inferiore a cannyThreshold
|
|
'Dim apertureSize As Integer = 3 ' Valori comuni: 3, 5, 7
|
|
'
|
|
'' Applica Dilate e Erode come hai già fatto
|
|
'Dim fattR_ As Integer = 7 ' O il valore appropriato per fattR
|
|
'maskOutput = maskOutput.Dilate(fattR_)
|
|
'maskOutput = maskOutput.Erode(fattR_)
|
|
'
|
|
'maskOutput.Save(SaveDir & "maskOutput.png")
|
|
'
|
|
'edges = New Image(Of Gray, Byte)(maskOutput.Size)
|
|
'CvInvoke.Canny(maskOutput, edges, cannyThreshold, cannyThresholdLinking, apertureSize)
|
|
'
|
|
'maskOutput.Save(SaveDir & "EDGES_TEST0.png")
|
|
'edges.Save(SaveDir & "EDGES_TEST.png")
|
|
'
|
|
'If MessageBox.Show("Il risultato ottenuto è accettabile?", "AVVISO", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk) = DialogResult.OK Then
|
|
' bOk = True
|
|
'End If
|
|
'
|
|
'thresholdValue = thresholdValue + 5
|
|
|
|
End While
|
|
|
|
Return edges
|
|
|
|
End Function
|
|
' ------------------------------------------- PROVA PROVA PROVA PROVA -------------------------------------------
|
|
|
|
Private Sub ApplicaTreshold4(trhVal As Integer)
|
|
|
|
|
|
Try
|
|
|
|
Dim tm As New Stopwatch
|
|
Dim t1, t2, t3, t4 As Double
|
|
|
|
If _corImgDiff Is Nothing Then Return
|
|
|
|
tm.Start()
|
|
|
|
Dim maxVal As Double = 255
|
|
|
|
Dim cvimageTh As Image(Of Emgu.CV.Structure.Gray, Byte)
|
|
|
|
cvimageTh = _corImgDiff.ThresholdBinary(New Emgu.CV.Structure.Gray(trhVal), New Emgu.CV.Structure.Gray(255))
|
|
Static fattR As Integer = 15
|
|
|
|
cvimageTh = cvimageTh.Dilate(fattR)
|
|
cvimageTh = cvimageTh.Erode(fattR)
|
|
|
|
''------------------- PROVA PROVA GrabCut
|
|
' cvimageTh = NuovoRiconoscimentoBordi()
|
|
''------------------- PROVA PROVA
|
|
|
|
t1 = tm.ElapsedMilliseconds
|
|
|
|
' Faccio la canny per didattica, ma non la uso
|
|
'Dim cvimageCanny As Image(Of Emgu.CV.Structure.Gray, Byte)
|
|
'cvimageCanny = cvimageTh.Canny(thr, thr * 2 / 3)
|
|
'Dim frm4 As FrmImgShow = New FrmImgShow(cvimageCanny)
|
|
'frm4.ShowDialog()
|
|
|
|
' Area massima
|
|
Dim areaMax As Double = 0
|
|
' Indice del contorno di area massima nella lista di contorni
|
|
Dim iareaMax As Integer = 0
|
|
|
|
#If WinXp Then
|
|
Dim contours As Contour(Of Point)
|
|
contours = cvimageTh.FindContours(CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_TC89_KCOS, CvEnum.RETR_TYPE.CV_RETR_EXTERNAL)
|
|
|
|
Dim ActualContour As Contour(Of Point) = Nothing
|
|
|
|
While Not contours Is Nothing
|
|
CvInvoke.cvBoundingRect(contours, True)
|
|
|
|
Dim area As Double = contours.Area
|
|
If area > areaMax Then
|
|
areaMax = area
|
|
ActualContour = contours
|
|
End If
|
|
contours = contours.HNext
|
|
End While
|
|
|
|
t2 = tm.ElapsedMilliseconds
|
|
|
|
|
|
#Else
|
|
' Una lista di contorni, ogni contorno è una lista di punti
|
|
Dim contours As New VectorOfVectorOfPoint
|
|
Dim Hierarchy As IOutputArray
|
|
CvInvoke.FindContours(cvimageTh, contours, Hierarchy, _searchMode, CvEnum.ChainApproxMethod.ChainApproxTc89Kcos)
|
|
|
|
t2 = tm.ElapsedMilliseconds
|
|
|
|
For i As Integer = 0 To contours.Size - 1
|
|
Dim area As Double = CvInvoke.ContourArea(contours(i), False)
|
|
If area > areaMax Then
|
|
areaMax = area
|
|
iareaMax = i
|
|
End If
|
|
Next
|
|
|
|
#End If
|
|
|
|
|
|
' parte iniziale del file DXF
|
|
Dim writer As New StreamWriter(SaveDir & "FinalImage.dxf")
|
|
writer.WriteLine("0")
|
|
writer.WriteLine("SECTION")
|
|
writer.WriteLine("2")
|
|
writer.WriteLine("ENTITIES")
|
|
writer.WriteLine("0")
|
|
|
|
Dim cntcont As Integer = 0
|
|
Dim maxLevel As Integer = 0
|
|
Dim thickness As Integer = 2
|
|
|
|
#If WinXp Then
|
|
|
|
CvInvoke.cvDrawContours(_outimage, ActualContour, New MCvScalar(255, 255, 0), New MCvScalar(255, 255, 0), maxLevel, 5,
|
|
CvEnum.LINE_TYPE.FOUR_CONNECTED, New Point(0, 0))
|
|
DebugSuDxf(writer, contours.ToArray())
|
|
|
|
#Else
|
|
|
|
If areaMax > 0 Then
|
|
CvInvoke.DrawContours(_outimage, contours, iareaMax, New MCvScalar(255, 255, 0), 5)
|
|
DebugSuDxf(writer, New VectorOfPoint(contours(iareaMax).ToArray()))
|
|
End If
|
|
#End If
|
|
|
|
|
|
writer.WriteLine("ENDSEC")
|
|
writer.WriteLine("0")
|
|
writer.WriteLine("EOF")
|
|
|
|
t3 = tm.ElapsedMilliseconds
|
|
|
|
#If WinXp Then
|
|
contours.Clear()
|
|
#Else
|
|
contours.Dispose()
|
|
#End If
|
|
contours = Nothing
|
|
|
|
writer.Close()
|
|
writer.Dispose()
|
|
writer = Nothing
|
|
|
|
|
|
'GC.Collect()
|
|
|
|
t4 = tm.ElapsedMilliseconds
|
|
|
|
Debug.Print(t3.ToString)
|
|
|
|
|
|
Catch ex As Exception
|
|
|
|
End Try
|
|
|
|
|
|
|
|
End Sub
|
|
|
|
Private Sub ApplicaTreshold7(trhVal As Integer)
|
|
|
|
|
|
trhVal = trhVal * _thFactor
|
|
|
|
' cnale R
|
|
If _corImgDiff1 Is Nothing Then Return
|
|
|
|
' pulisco la memoria
|
|
Try
|
|
If _thrImage IsNot Nothing Then
|
|
_thrImage.Dispose()
|
|
_thrImage = Nothing
|
|
End If
|
|
Catch ex As Exception
|
|
_thrImage = Nothing
|
|
End Try
|
|
|
|
Dim tm As New Stopwatch
|
|
Dim t1, t2, t3, t4 As Double
|
|
|
|
tm.Start()
|
|
|
|
_corImgDiff = _corImgDiff0
|
|
SommaThreshold(trhVal, 0)
|
|
_corImgDiff = _corImgDiff1
|
|
SommaThreshold(trhVal, 1)
|
|
_corImgDiff = _corImgDiff2
|
|
SommaThreshold(trhVal, 2)
|
|
|
|
t1 = tm.ElapsedMilliseconds
|
|
|
|
_corImgDiff = _thrImage
|
|
|
|
' raddoppio la dimensione dell'immagine (in precedenza dimezzata) '_pdown' volte
|
|
For j As Integer = 0 To _pdown - 1
|
|
_corImgDiff = _corImgDiff.PyrUp
|
|
Next
|
|
|
|
t2 = tm.ElapsedMilliseconds
|
|
|
|
|
|
#If DEBUG Then
|
|
_corImgDiff.Save("c:\temp\sumdiff.png")
|
|
#End If
|
|
|
|
_outimage = New Image(Of Emgu.CV.Structure.Rgb, Byte)(_imageMng.FinalImage)
|
|
ApplicaTreshold4(trhVal)
|
|
|
|
t3 = tm.ElapsedMilliseconds
|
|
|
|
GC.Collect()
|
|
t4 = tm.ElapsedMilliseconds
|
|
|
|
End Sub
|
|
|
|
Private Sub ConvertBackImage()
|
|
' Libero memoria
|
|
If _convBackImage IsNot Nothing Then
|
|
_convBackImage.Dispose()
|
|
_convBackImage = Nothing
|
|
End If
|
|
' verifico che esita l'immagine BackImg
|
|
If _backImage Is Nothing Then Return
|
|
|
|
_imageMng.InputImage = _backImage
|
|
_imageMng.CorrezioneCompleta()
|
|
_convBackImage = _imageMng.FinalImage.Clone()
|
|
|
|
End Sub
|
|
|
|
Private Function ScaleGrayTo(maxg As Double, img As Image(Of Emgu.CV.Structure.Gray, Byte)) As Image(Of Emgu.CV.Structure.Gray, Byte)
|
|
Dim minv As Double
|
|
Dim maxv As Double
|
|
Dim minp As Point
|
|
Dim maxp As Point
|
|
|
|
#If WinXp Then
|
|
CvInvoke.cvMinMaxLoc(img, minv, maxv, minp, maxp, Nothing)
|
|
#Else
|
|
' Restituisce il valore minimo e massimo della matrice associato alla sua posizione
|
|
CvInvoke.MinMaxLoc(img, minv, maxv, minp, maxp)
|
|
#End If
|
|
' minv = 0 -> NERO, maxv = 255 -> BIANCO
|
|
If (maxv - minv > 2) Then
|
|
' imposto fondo scala immagine a zero '(img - minv)' e riscalo i colori per andare da 0 a 255
|
|
img = (img - minv) * (maxg / (maxv - minv))
|
|
End If
|
|
Return img
|
|
End Function
|
|
|
|
Private Sub SommaThreshold(trhVal As Integer, nimg As Integer)
|
|
|
|
|
|
Try
|
|
|
|
Dim maxVal As Double = 255
|
|
|
|
Dim cvimageTh As Image(Of Emgu.CV.Structure.Gray, Byte)
|
|
|
|
' Misuro il tempo impiegato per eseguire determinate operazioni
|
|
Dim tm As New Stopwatch
|
|
Dim t1, t2, t3 As Double
|
|
tm.Start()
|
|
|
|
_corImgDiff.Save(SaveDir & "BlackAndWhite_00_" & nimg.ToString & ".png")
|
|
|
|
' creo un'immagine in bianco e nero (tutti i pixel con valore maggiore di soglia diventano 255, altrimenti 0)
|
|
cvimageTh = _corImgDiff.ThresholdBinary(New Emgu.CV.Structure.Gray(trhVal), New Emgu.CV.Structure.Gray(255))
|
|
|
|
cvimageTh.Save(SaveDir & "BlackAndWhite_01_" & nimg.ToString & ".png")
|
|
|
|
t1 = tm.ElapsedMilliseconds
|
|
|
|
' Numero di iterazioni
|
|
Static fattR As Integer = 7
|
|
' Closing = Dilate + Erode -> procedo a chiudere eventuali buchi
|
|
cvimageTh = cvimageTh.Dilate(fattR)
|
|
cvimageTh = cvimageTh.Erode(fattR)
|
|
|
|
cvimageTh.Save(SaveDir & "BlackAndWhite" & nimg.ToString & ".png")
|
|
|
|
t2 = tm.ElapsedMilliseconds
|
|
|
|
If _thrImage Is Nothing Then
|
|
_thrImage = cvimageTh
|
|
Else
|
|
' sommo il risultato all'immagine precedente
|
|
_thrImage = _thrImage.Add(cvimageTh)
|
|
End If
|
|
|
|
t3 = tm.ElapsedMilliseconds
|
|
|
|
#If DEBUG Then
|
|
cvimageTh.Save("c:\temp\thImage" & nimg.ToString & ".png")
|
|
#End If
|
|
|
|
'GC.Collect()
|
|
|
|
Catch ex As Exception
|
|
|
|
End Try
|
|
|
|
|
|
End Sub
|
|
|
|
Private Sub DisposePreviousImages()
|
|
|
|
Dim img As Image(Of Emgu.CV.Structure.Gray, Byte)
|
|
' Libera la memoria associata ai dati dell'immagine
|
|
For Each img In {_corImgDiff0, _corImgDiff1, _corImgDiff2, _corImgDiff, _thrImage}
|
|
Try
|
|
If img IsNot Nothing Then
|
|
img.Dispose()
|
|
img = Nothing
|
|
End If
|
|
Catch ex As Exception
|
|
|
|
End Try
|
|
Next
|
|
End Sub
|
|
End Class
|