1171 lines
40 KiB
VB.net
1171 lines
40 KiB
VB.net
Imports System.Runtime
|
|
|
|
|
|
Imports Emgu.CV.CvEnum
|
|
Imports Emgu.CV.Structure
|
|
Imports System.Math
|
|
Imports System.IO
|
|
Imports System.Globalization
|
|
Imports Emgu.CV
|
|
Imports System.Threading
|
|
Imports Emgu.CV.Util
|
|
Imports System.Drawing.Imaging
|
|
|
|
Public Class clsImageMng
|
|
|
|
|
|
#Region "membri privati"
|
|
|
|
Private m_dimx As Short = 1 '3888
|
|
Private m_dimy As Short = 1 ' 2592
|
|
Private m_Pos_x_mm, m_Pos_y_mm As Double
|
|
' Posizione in mm del punto_3 (ibl=3) rispetto all'origine (punto_0)
|
|
Private m_Pos_x_z0_mm, m_Pos_y_z0_mm As Double
|
|
Private m_bCorrected As Boolean = False
|
|
Private m_pmm_bs As New clPuntomm
|
|
Private m_pmm_bs_lev0 As New clPuntomm
|
|
Private m_scale_center As New clPuntomm
|
|
Private m_fscalaxmm As Double
|
|
Private m_scale_centerZ As Double
|
|
Private m_punto0 As New clCoppiaPunto
|
|
Private m_puntoH(4) As clCoppiaPunto
|
|
Private m_bCorrAltezzaEnabled As Boolean
|
|
' posizione in px dei punti dell'immagine originale rispetto al punto punto_0 (itl=0)
|
|
Private m_pdst(3) As System.Drawing.PointF ' punti nuova foto
|
|
' indice per distinguere i punti salvati nei vettori 'm_pworld', 'm_psrc', 'm_pdst'
|
|
Const itl As Integer = 0 ' top left
|
|
Const itr As Integer = 1 ' top right
|
|
Const ibl As Integer = 3 ' Bottom right
|
|
Const ibr As Integer = 2 ' Bottom left
|
|
' Dimensione immagine dopo aver calcolato le estensioni oltre al riquadro
|
|
Private m_dim_XProsp As Short = 1 ' dimens. img con prospettiva corretta
|
|
Private m_dim_YProsp As Short = 1
|
|
' mm to px all'altezza zero del tavolo
|
|
Private m_mm2PixelProspZ0 As Double
|
|
Private m_mm2PixelProspFinal As Double
|
|
' Estension in Pixel dell'immagine
|
|
Private m_ExtXL_pix As Integer, m_ExtXR_pix As Integer ' sinistra e destra
|
|
Private m_ExtYT_pix As Integer, m_ExtYB_pix As Integer ' sopra e sotto
|
|
' Estension in mm dell'immagine
|
|
Private m_ExtXL_mm As Single, m_ExtXR_mm As Single ' sinistra e destra
|
|
Private m_ExtYT_mm As Single, m_ExtYB_mm As Single ' sopra e sotto
|
|
#If WinXP Then
|
|
Private m_MatDir As Matrix(Of Double) 'HomographyMatrix ' Per creare l'immagine correttta, data la coord. XY, mi dà il pixel da prendere
|
|
Private m_MatInv As Matrix(Of Double) 'HomographyMatrix ' Per ottenere la coord. in mm da un valore in pixel dell'imm. originale
|
|
#Else
|
|
' 'HomographyMatrix' matrice di correzione prospettica (dalle in pixel a quelle world) 'HomographyMatrix '
|
|
Private m_MatInv(2, 2) As Double
|
|
' 'HomographyMatrix' matrice di correzione prospettica (dalle coordinate world a quelle locali in px)
|
|
Private m_MatDir(2, 2) As Double
|
|
#End If
|
|
|
|
Private m_NomeFileCorrezProsp As String
|
|
Private m_ProspCalibrated As Boolean = False
|
|
Private m_SpessLastra As Double = 0
|
|
Private m_SpessCorr As Double = 0
|
|
Private _thprocess As Thread = Nothing
|
|
Private m_UndistImage As Drawing.Bitmap = Nothing
|
|
Private m_FinalImage As Drawing.Bitmap = Nothing
|
|
Private m_InputImage As Drawing.Bitmap = Nothing
|
|
Private m_dim_XProspExt As Integer
|
|
Private m_dim_YProspExt As Integer
|
|
Private m_FileCalibLens As String = Nothing
|
|
Private m_FileCalibProsp As String = Nothing
|
|
Private m_widthImagePixMax As Integer = 6000
|
|
Private MatConvP(m_dimx, m_dimy) As clPuntoPix
|
|
Private m_CalimageWidth As Integer = 0
|
|
|
|
' [ fx 0.0 cx
|
|
' 0.0 fy cy
|
|
' 0.0 0.0 1.0 ]
|
|
Private _cameraMatrix As Matrix(Of Double) = Nothing
|
|
' [ k1, k2, p1, p2, p3 ]
|
|
Private _distCoeffs As Matrix(Of Double) = Nothing
|
|
|
|
Private Shared ReadOnly m_sync As New Object
|
|
' vettore di correzione prospettica: convertita in matrice (m_MatDir)
|
|
Private _perspMatDir As Emgu.CV.Mat
|
|
|
|
Private _ocvMapx As Emgu.CV.Matrix(Of Single)
|
|
Private _ocvMapy As Emgu.CV.Matrix(Of Single)
|
|
Private m_jpgQuality As Long = 80
|
|
|
|
#End Region
|
|
|
|
#Region "membri pubblici"
|
|
Public m_fileCaliLensRead As Boolean = False
|
|
Public m_fileCaliProspRead As Boolean = False
|
|
Public m_bMatProspOk As Boolean = False
|
|
' --- variabili per la correzione prospettica
|
|
Public m_AltRif As Double
|
|
Public m_ZCali As Double
|
|
' punti world in mm riferiti rispetto all'origine punto_0 (itl=0)
|
|
Public m_pworld(3) As System.Drawing.PointF
|
|
' punti foto riferiti rispetto all'origine immagine
|
|
Public m_psrc(3) As System.Drawing.PointF
|
|
#End Region
|
|
|
|
#Region "eventi"
|
|
Public Event FineCorrezioneLente()
|
|
Public Event FineCorrezioneProspettiva()
|
|
Public Event AvanzamentoCorrezioneLente(value As Double)
|
|
Public Event AvanzamentoCorrezioneProspettiva(value As Double)
|
|
Public Event ProcessAborted(err As Integer)
|
|
#End Region
|
|
|
|
#Region "Classi Private"
|
|
|
|
Private Class clPuntoPix
|
|
Public X As Single
|
|
Public Y As Single
|
|
End Class
|
|
Private Class clPuntomm
|
|
Public x As Double
|
|
Public y As Double
|
|
End Class
|
|
Private Class clCoppiaPunto
|
|
Public XTrg As Double
|
|
Public YTrg As Double
|
|
Public XSrc As Double
|
|
Public YSrc As Double
|
|
End Class
|
|
#End Region
|
|
|
|
#Region "Costruttori"
|
|
|
|
Public Sub New()
|
|
Dim i As Integer
|
|
|
|
For i = 0 To 3
|
|
If IsNothing(m_puntoH(i)) Then m_puntoH(i) = New clCoppiaPunto
|
|
Next
|
|
m_ProspCalibrated = False
|
|
End Sub
|
|
Protected Overrides Sub Finalize()
|
|
MyBase.Finalize()
|
|
End Sub
|
|
|
|
#End Region
|
|
|
|
#Region "Proprietà"
|
|
|
|
Public ReadOnly Property UndistorcedImage As Bitmap
|
|
Get
|
|
SyncLock m_sync
|
|
Return m_UndistImage
|
|
End SyncLock
|
|
End Get
|
|
End Property
|
|
Public ReadOnly Property FinalImage As Bitmap
|
|
Get
|
|
SyncLock m_sync
|
|
Return m_FinalImage
|
|
End SyncLock
|
|
End Get
|
|
End Property
|
|
Public Property InputImage As Bitmap
|
|
Get
|
|
Return m_InputImage
|
|
End Get
|
|
Set(value As Bitmap)
|
|
m_InputImage = value
|
|
End Set
|
|
End Property
|
|
|
|
Public Property MaxPxWidthOutImage As Integer
|
|
Set(value As Integer)
|
|
m_widthImagePixMax = value
|
|
End Set
|
|
Get
|
|
Return m_widthImagePixMax
|
|
End Get
|
|
End Property
|
|
|
|
Public ReadOnly Property mm2pixelAtZ As Double
|
|
Get
|
|
Return m_mm2PixelProspFinal
|
|
End Get
|
|
End Property
|
|
|
|
#End Region
|
|
|
|
#Region "Metodi Pubblici"
|
|
|
|
Public Function SetFileCalibrazione(NomeFileCaliLens As String, NomeFileCaliProsp As String) As Boolean
|
|
|
|
m_FileCalibLens = NomeFileCaliLens
|
|
m_FileCalibProsp = NomeFileCaliProsp
|
|
|
|
Return True
|
|
|
|
|
|
End Function
|
|
|
|
Public Sub Correggi()
|
|
|
|
' corregge solo la lente e carica il file di calibrazione prospettiva per dare la possibilità di calibrare dall'interfaccia
|
|
Try
|
|
|
|
If Not m_fileCaliLensRead Then
|
|
m_fileCaliLensRead = LeggiFileCalibrazioneLenteOCV(m_FileCalibLens)
|
|
End If
|
|
|
|
If Not m_fileCaliProspRead Then
|
|
m_fileCaliProspRead = LeggiFileCorrezProsp(m_FileCalibProsp)
|
|
End If
|
|
|
|
If Not m_UndistImage Is Nothing Then
|
|
'm_UndistImage.Dispose()
|
|
m_UndistImage = Nothing
|
|
End If
|
|
|
|
Dim outFrame As New Image(Of Emgu.CV.Structure.Rgb, Byte)(m_InputImage.Width, m_InputImage.Height)
|
|
Dim newIntrinsecMatrix As IInputArray
|
|
CvInvoke.Undistort(New Image(Of Emgu.CV.Structure.Rgb, Byte)(m_InputImage), outFrame, _cameraMatrix, _distCoeffs, newIntrinsecMatrix)
|
|
|
|
m_UndistImage = outFrame.Bitmap
|
|
|
|
GC.Collect()
|
|
|
|
m_UndistImage.Save(DirTmp & "corrected.bmp", System.Drawing.Imaging.ImageFormat.Bmp)
|
|
|
|
m_bCorrected = True
|
|
|
|
RaiseEvent AvanzamentoCorrezioneProspettiva(100)
|
|
|
|
Catch ex As Exception
|
|
|
|
If Not m_UndistImage Is Nothing Then
|
|
'm_UndistImage.Dispose()
|
|
m_UndistImage = Nothing
|
|
End If
|
|
Throw New Exception(ex.Message)
|
|
End Try
|
|
|
|
End Sub
|
|
|
|
Public Sub DownloadCompletato()
|
|
m_bCorrected = False
|
|
End Sub
|
|
|
|
|
|
'* c00*xi + c01*yi + c02
|
|
'* ui = ---------------------
|
|
'* c20*xi + c21*yi + c22
|
|
'*
|
|
'* c10*xi + c11*yi + c12
|
|
'* vi = ---------------------
|
|
'* c20*xi + c21*yi + c22
|
|
|
|
Public Sub CorreggiProspettiva(ByVal SpessLastra As Double)
|
|
|
|
If Not m_bMatProspOk Then
|
|
CalcolaMatriceCorrezioneProspettiva()
|
|
CalcolaMatriceOCV()
|
|
End If
|
|
|
|
If m_bMatProspOk Then
|
|
CorreggiProspettivaDaMatriceOCV(SpessLastra)
|
|
End If
|
|
|
|
End Sub
|
|
|
|
Public Sub CalcolaDatiCorrezione()
|
|
' forzo il ricalcolo
|
|
m_ProspCalibrated = False
|
|
CalcolaDatiCorrezioneDiretta()
|
|
CalcolaDatiCorrezioneInversa()
|
|
m_bCorrAltezzaEnabled = True
|
|
If Not TrovaDatiScalatura() Then m_bCorrAltezzaEnabled = False
|
|
If Not TrovaOffsetPosizione() Then m_bCorrAltezzaEnabled = False
|
|
End Sub
|
|
|
|
' Salvo file di calibrazione
|
|
Public Sub SalvaFileCorrezioneProsp()
|
|
|
|
Dim writer As StreamWriter
|
|
Dim i As Integer
|
|
Dim nfi As New CultureInfo("en-US", False)
|
|
|
|
|
|
writer = New StreamWriter(m_NomeFileCorrezProsp)
|
|
writer.WriteLine("ProspPnt")
|
|
For i = 0 To 3
|
|
writer.WriteLine("{0} {1} {2} {3}", m_pworld(i).X.ToString("0.00", nfi.NumberFormat), m_pworld(i).Y.ToString("0.00", nfi.NumberFormat),
|
|
m_psrc(i).X.ToString("0", nfi.NumberFormat), m_psrc(i).Y.ToString("0", nfi.NumberFormat))
|
|
Next
|
|
writer.WriteLine("Extend={0} {1} {2} {3}", m_ExtXL_mm.ToString("0", nfi.NumberFormat), m_ExtXR_mm.ToString("0", nfi.NumberFormat), m_ExtYT_mm.ToString("0", nfi.NumberFormat), m_ExtYB_mm.ToString("0", nfi.NumberFormat))
|
|
writer.WriteLine("AltRif= {0}", m_AltRif.ToString("0.00", nfi.NumberFormat))
|
|
writer.WriteLine("p1Rif= {0} {1} {2} {3}", m_puntoH(0).XSrc, m_puntoH(0).YSrc, m_puntoH(1).XSrc, m_puntoH(1).YSrc)
|
|
writer.WriteLine("p2Rif= {0} {1} {2} {3}", m_puntoH(2).XSrc, m_puntoH(2).YSrc, m_puntoH(3).XSrc, m_puntoH(3).YSrc)
|
|
writer.WriteLine("ZCali= {0}", m_ZCali.ToString("0.00", nfi.NumberFormat))
|
|
m_CalimageWidth = 0
|
|
If m_InputImage IsNot Nothing Then
|
|
m_CalimageWidth = m_InputImage.Width
|
|
End If
|
|
writer.WriteLine("ImageWidth= {0}", m_CalimageWidth.ToString("0"))
|
|
writer.Close()
|
|
CalcolaMatriceCorrezioneProspettiva()
|
|
' Avviso che la configurazione è stata salvata correttamente
|
|
Dim sMsg = String.Format("Salvataggio file di calbrazione '{0}' " & vbCrLf & "avvenuto con succeso!", m_NomeFileCorrezProsp)
|
|
MessageBox.Show(sMsg, "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
|
|
End Sub
|
|
|
|
Public Sub ProcessStop()
|
|
If _thprocess Is Nothing Then Exit Sub
|
|
|
|
If _thprocess.IsAlive Then
|
|
_thprocess.Abort()
|
|
_thprocess = Nothing
|
|
End If
|
|
|
|
|
|
End Sub
|
|
|
|
Public Sub CorrezioneCompletaAsync()
|
|
|
|
ProcessStop()
|
|
|
|
_thprocess = New Thread(Sub()
|
|
CorrezioneCompleta()
|
|
End Sub)
|
|
|
|
_thprocess.Start()
|
|
|
|
End Sub
|
|
|
|
Public Sub SaveBitmap(bitm As Bitmap, fileName As String)
|
|
|
|
|
|
' Encoder parameter for image quality
|
|
Dim qualityParam As New EncoderParameter(Encoder.Quality, m_jpgQuality)
|
|
' Jpeg image codec
|
|
Dim jpegCodec As ImageCodecInfo = GetEncoderInfo("image/jpeg")
|
|
|
|
Dim encoderParams As New EncoderParameters(1)
|
|
encoderParams.Param(0) = qualityParam
|
|
|
|
bitm.Save(fileName, jpegCodec, encoderParams)
|
|
|
|
|
|
End Sub
|
|
|
|
#End Region
|
|
|
|
#Region "Metodi Privati"
|
|
|
|
|
|
Private Function TrovaPuntoInmm4p(ByVal p As clCoppiaPunto) As Boolean
|
|
|
|
p.XTrg = (m_MatInv(0, 0) * p.XSrc + m_MatInv(0, 1) * p.YSrc + m_MatInv(0, 2)) / (m_MatInv(2, 0) * p.XSrc + m_MatInv(2, 1) * p.YSrc + m_MatInv(2, 2))
|
|
p.YTrg = (m_MatInv(1, 0) * p.XSrc + m_MatInv(1, 1) * p.YSrc + m_MatInv(1, 2)) / (m_MatInv(2, 0) * p.XSrc + m_MatInv(2, 1) * p.YSrc + m_MatInv(2, 2))
|
|
TrovaPuntoInmm4p = True
|
|
|
|
End Function
|
|
|
|
Private Function TrovaDatiScalatura() As Boolean
|
|
|
|
' trova il centro di scala e il fattore di scala in altezza, per mm
|
|
|
|
Dim a1, b1, c1, a2, b2, c2 As Double
|
|
Dim denominatore As Double
|
|
|
|
TrovaDatiScalatura = False
|
|
|
|
' posizione in mm
|
|
m_fscalaxmm = 1
|
|
|
|
If (m_AltRif <= 0.1) Then Exit Function
|
|
|
|
If Not TrovaPuntoInmm4p(m_puntoH(0)) Then Exit Function
|
|
If Not TrovaPuntoInmm4p(m_puntoH(1)) Then Exit Function
|
|
If Not TrovaPuntoInmm4p(m_puntoH(2)) Then Exit Function
|
|
If Not TrovaPuntoInmm4p(m_puntoH(3)) Then Exit Function
|
|
|
|
a1 = m_puntoH(0).YTrg - m_puntoH(1).YTrg
|
|
b1 = -(m_puntoH(0).XTrg - m_puntoH(1).XTrg)
|
|
c1 = -m_puntoH(1).XTrg * a1 - m_puntoH(1).YTrg * b1
|
|
|
|
a2 = m_puntoH(2).YTrg - m_puntoH(3).YTrg
|
|
b2 = -(m_puntoH(2).XTrg - m_puntoH(3).XTrg)
|
|
c2 = -m_puntoH(3).XTrg * a2 - m_puntoH(3).YTrg * b2
|
|
|
|
denominatore = a1 * b2 - a2 * b1
|
|
' centro di scala
|
|
If Abs(denominatore) > 0.0001 Then
|
|
m_scale_center.y = (a2 * c1 - a1 * c2) / denominatore
|
|
m_scale_center.x = (b1 * c2 - b2 * c1) / denominatore
|
|
Else
|
|
Exit Function
|
|
End If
|
|
|
|
|
|
Dim distl, disth As Double
|
|
|
|
distl = (m_scale_center.x - m_puntoH(0).XTrg) * (m_scale_center.x - m_puntoH(0).XTrg) + (m_scale_center.y - m_puntoH(0).YTrg) * (m_scale_center.y - m_puntoH(0).YTrg)
|
|
distl = Math.Sqrt(distl)
|
|
|
|
disth = (m_scale_center.x - m_puntoH(1).XTrg) * (m_scale_center.x - m_puntoH(1).XTrg) + (m_scale_center.y - m_puntoH(1).YTrg) * (m_scale_center.y - m_puntoH(1).YTrg)
|
|
disth = Math.Sqrt(disth)
|
|
|
|
m_fscalaxmm = distl / disth
|
|
m_fscalaxmm = Pow(m_fscalaxmm, 1 / m_AltRif)
|
|
|
|
m_scale_centerZ = m_ZCali + m_AltRif / (1 - distl / disth)
|
|
|
|
TrovaDatiScalatura = True
|
|
|
|
End Function
|
|
|
|
Private Function TrovaOffsetPosizione() As Boolean
|
|
Dim pt As New clPuntomm
|
|
Dim pTmp As New clCoppiaPunto
|
|
|
|
Dim offset As New clPuntomm ' calcolato
|
|
Try
|
|
|
|
' trovo come si trasforma in mm (senza offset) il punto di origine in pixel
|
|
pTmp.XSrc = m_punto0.XSrc
|
|
pTmp.YSrc = m_punto0.YSrc
|
|
|
|
If Not TrovaPuntoInmm4p(pTmp) Then Return False
|
|
|
|
' Trovo quindi l'offset dato dal punto di riferimento
|
|
offset.x = m_punto0.XTrg - pTmp.XTrg
|
|
offset.y = m_punto0.YTrg - pTmp.YTrg
|
|
|
|
' Trovo dove si trova il punto in pixel in basso a sin
|
|
m_pmm_bs_lev0.x = m_pmm_bs.x + offset.x
|
|
m_pmm_bs_lev0.y = m_pmm_bs.y + offset.y
|
|
|
|
Catch ex As Exception
|
|
Return False
|
|
End Try
|
|
|
|
Return True
|
|
|
|
End Function
|
|
|
|
#Region "Lettura configurazioni"
|
|
|
|
''' <summary>
|
|
''' Legge il file che contiene i parametri di correzione della lente
|
|
''' </summary>
|
|
''' <param name="NomeFile">Percorso file da leggere</param>
|
|
''' <returns>Ritorna True se la lettura è andata a buon fine</returns>
|
|
Private Function LeggiFileCalibrazioneLenteOCV(NomeFile As String) As Boolean
|
|
|
|
Console.WriteLine("LETTURA OCV: " & MainModule.IndexProc)
|
|
|
|
Dim Linea As String
|
|
Dim split() As String
|
|
Dim reader As StreamReader
|
|
Dim i, j As Integer
|
|
Dim nfi As NumberFormatInfo = New CultureInfo("en-US", False).NumberFormat
|
|
Dim CalibType As Integer = 0
|
|
Dim FileVersion As Integer = 0
|
|
|
|
|
|
If _cameraMatrix Is Nothing Then
|
|
_cameraMatrix = New Matrix(Of Double)(3, 3)
|
|
End If
|
|
If _distCoeffs Is Nothing Then
|
|
_distCoeffs = New Matrix(Of Double)(1, 4)
|
|
End If
|
|
|
|
'CalibType = 1
|
|
'FileVersion = 1
|
|
'rms = 2.912043
|
|
'fx = 4775.944905
|
|
'fy = 4775.944905
|
|
'cx = 3103.561924
|
|
'cy = 2033.648165
|
|
'k1 = -0.153547
|
|
'k2 = 0.127935
|
|
'p1 = -0.00626
|
|
'p2 = -0.000005
|
|
'hfov = 66Deg
|
|
'vfov = 46.1Deg
|
|
|
|
'[fx 0 cx; 0 fy cy; 0 0 1]
|
|
' setto i coefficenti fissi:
|
|
_cameraMatrix.Data(0, 1) = 0
|
|
_cameraMatrix.Data(1, 0) = 0
|
|
_cameraMatrix.Data(2, 0) = 0
|
|
_cameraMatrix.Data(2, 1) = 0
|
|
_cameraMatrix.Data(2, 2) = 1
|
|
|
|
Try
|
|
nfi.NumberDecimalSeparator = "."
|
|
reader = New StreamReader(NomeFile)
|
|
|
|
While (Not reader.EndOfStream)
|
|
Linea = reader.ReadLine()
|
|
split = Linea.Split(" =", 5, StringSplitOptions.RemoveEmptyEntries)
|
|
If split.Length > 0 Then
|
|
|
|
If split(0).Equals("CalibType", StringComparison.InvariantCultureIgnoreCase) Then
|
|
CalibType = CInt(split(1))
|
|
ElseIf split(0).Equals("FileVersion", StringComparison.InvariantCultureIgnoreCase) Then
|
|
FileVersion = CInt(split(1))
|
|
ElseIf (Linea.StartsWith("rms")) Then
|
|
' non carico dato
|
|
|
|
' CAMERA MATRIX
|
|
ElseIf (Linea.StartsWith("fx")) Then
|
|
_cameraMatrix.Data(0, 0) = Convert.ToDouble(split(1), nfi)
|
|
ElseIf (Linea.StartsWith("cx")) Then
|
|
_cameraMatrix.Data(0, 2) = Convert.ToDouble(split(1), nfi)
|
|
ElseIf (Linea.StartsWith("fy")) Then
|
|
_cameraMatrix.Data(1, 1) = Convert.ToDouble(split(1), nfi)
|
|
ElseIf (Linea.StartsWith("cy")) Then
|
|
_cameraMatrix.Data(1, 2) = Convert.ToDouble(split(1), nfi)
|
|
' DISTORSION COEFFICIENT
|
|
ElseIf (Linea.StartsWith("k1")) Then
|
|
_distCoeffs.Data(0, 0) = Convert.ToDouble(split(1), nfi)
|
|
ElseIf (Linea.StartsWith("k2")) Then
|
|
_distCoeffs.Data(0, 1) = Convert.ToDouble(split(1), nfi)
|
|
ElseIf (Linea.StartsWith("p1")) Then
|
|
_distCoeffs.Data(0, 2) = Convert.ToDouble(split(1), nfi)
|
|
ElseIf (Linea.StartsWith("p2")) Then
|
|
_distCoeffs.Data(0, 3) = Convert.ToDouble(split(1), nfi)
|
|
|
|
ElseIf (Linea.StartsWith("hfov")) Then
|
|
' non carico dato
|
|
ElseIf (Linea.StartsWith("vfov")) Then
|
|
' non carico dato
|
|
ElseIf (Linea.StartsWith("ImageWidth")) Then
|
|
' non carico dato
|
|
ElseIf (Linea.StartsWith("ImageHeight")) Then
|
|
' non carico dato
|
|
End If
|
|
End If
|
|
|
|
End While
|
|
|
|
reader.Close()
|
|
reader.Dispose()
|
|
|
|
Console.WriteLine("LETTURA OCV TERMINATA: " & MainModule.IndexProc)
|
|
|
|
If CalibType <> 1 Then
|
|
MsgBox("Calibration Type error in file: " & NomeFile)
|
|
End If
|
|
If FileVersion <> 1 Then
|
|
MsgBox("FileVersion error in file: " & NomeFile)
|
|
End If
|
|
|
|
' alla prima acquisizione immagine si controllerà
|
|
' controllare se le dimensioni dell'immagine usata per la calibrazione coincidono con quelle attuali
|
|
|
|
' ScalaCalibrazione()
|
|
|
|
' If creaMatrice Then
|
|
' CreaMatriceCalibrazione()
|
|
' End If
|
|
|
|
Catch ex As Exception
|
|
MsgBox("Calibration error : " & NomeFile)
|
|
Return False
|
|
End Try
|
|
|
|
Return True
|
|
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Lettura del file per la risoluzione della distorsione prospettica
|
|
''' </summary>
|
|
''' <param name="NomeFile">Percorso del file da leggere</param>
|
|
''' <returns>Ritorna True se la lettura è andata a buon fine</returns>
|
|
Private Function LeggiFileCorrezProsp(ByVal NomeFile As String) As Boolean
|
|
' nome file: Calib.txt
|
|
Dim Linea As String
|
|
Dim delimStr As String
|
|
Dim delimiter(5) As Char
|
|
Dim split() As String
|
|
Dim reader As StreamReader
|
|
Dim i As Integer
|
|
Dim nfi As NumberFormatInfo = New CultureInfo("en-US", False).NumberFormat
|
|
|
|
Try
|
|
m_NomeFileCorrezProsp = NomeFile
|
|
delimStr = " ="
|
|
delimiter = delimStr.ToCharArray()
|
|
nfi.NumberDecimalSeparator = "."
|
|
reader = New StreamReader(NomeFile)
|
|
|
|
' m_nPixOut = 0
|
|
While (Not reader.EndOfStream)
|
|
Linea = reader.ReadLine()
|
|
|
|
If (Linea.StartsWith("ProspPnt")) Then
|
|
For i = 0 To 3
|
|
Linea = reader.ReadLine()
|
|
split = Linea.Split(delimiter, 8, StringSplitOptions.RemoveEmptyEntries)
|
|
m_pworld(i).X = Convert.ToSingle(split(0), nfi)
|
|
m_pworld(i).Y = Convert.ToSingle(split(1), nfi)
|
|
m_psrc(i).X = Convert.ToSingle(split(2), nfi)
|
|
m_psrc(i).Y = Convert.ToSingle(split(3), nfi)
|
|
Next
|
|
|
|
ElseIf (Linea.StartsWith("Extend=")) Then
|
|
split = Linea.Split(delimiter, 8, StringSplitOptions.RemoveEmptyEntries)
|
|
m_ExtXL_mm = Convert.ToSingle(split(1), nfi)
|
|
m_ExtXR_mm = Convert.ToSingle(split(2), nfi)
|
|
m_ExtYT_mm = Convert.ToSingle(split(3), nfi)
|
|
m_ExtYB_mm = Convert.ToSingle(split(4), nfi)
|
|
|
|
ElseIf (Linea.StartsWith("AltRif=")) Then
|
|
split = Linea.Split(delimiter, 5, StringSplitOptions.RemoveEmptyEntries)
|
|
m_AltRif = Convert.ToDouble(split(1), nfi)
|
|
|
|
ElseIf (Linea.StartsWith("p1Rif=")) Then
|
|
split = Linea.Split(delimiter, 8, StringSplitOptions.RemoveEmptyEntries)
|
|
m_puntoH(0).XSrc = Convert.ToDouble(split(1))
|
|
m_puntoH(0).YSrc = Convert.ToDouble(split(2))
|
|
m_puntoH(1).XSrc = Convert.ToDouble(split(3))
|
|
m_puntoH(1).YSrc = Convert.ToDouble(split(4))
|
|
|
|
ElseIf (Linea.StartsWith("p2Rif=")) Then
|
|
split = Linea.Split(delimiter, 8, StringSplitOptions.RemoveEmptyEntries)
|
|
m_puntoH(2).XSrc = Convert.ToDouble(split(1))
|
|
m_puntoH(2).YSrc = Convert.ToDouble(split(2))
|
|
m_puntoH(3).XSrc = Convert.ToDouble(split(3))
|
|
m_puntoH(3).YSrc = Convert.ToDouble(split(4))
|
|
|
|
ElseIf (Linea.StartsWith("ZCali=")) Then
|
|
split = Linea.Split(delimiter, 8, StringSplitOptions.RemoveEmptyEntries)
|
|
m_ZCali = Convert.ToDouble(split(1), nfi)
|
|
|
|
ElseIf (Linea.StartsWith("ImageWidth=")) Then
|
|
split = Linea.Split(delimiter, 8, StringSplitOptions.RemoveEmptyEntries)
|
|
m_CalimageWidth = Convert.ToDouble(split(1), nfi)
|
|
End If
|
|
End While
|
|
reader.Close()
|
|
reader.Dispose()
|
|
Catch ex As Exception
|
|
MsgBox("Missing file : " & NomeFile)
|
|
Return False
|
|
End Try
|
|
|
|
CalcolaDatiCorrezione()
|
|
Return True
|
|
|
|
|
|
End Function
|
|
|
|
#End Region ' Lettura configurazioni
|
|
|
|
Property Corrected() As Boolean
|
|
Get
|
|
Return m_bCorrected
|
|
End Get
|
|
Set(ByVal value As Boolean)
|
|
m_bCorrected = value
|
|
End Set
|
|
End Property
|
|
|
|
ReadOnly Property CorrAltEnabled() As Boolean
|
|
Get
|
|
Return m_bCorrAltezzaEnabled
|
|
End Get
|
|
End Property
|
|
|
|
ReadOnly Property ZCali() As Double
|
|
Get
|
|
Return m_ZCali
|
|
End Get
|
|
End Property
|
|
|
|
Property XHpix(ByVal i As Integer) As Short
|
|
Get
|
|
Return (m_puntoH(i).XSrc)
|
|
End Get
|
|
Set(ByVal value As Short)
|
|
m_puntoH(i).XSrc = value
|
|
End Set
|
|
End Property
|
|
|
|
Property YHpix(ByVal i As Integer) As Short
|
|
Get
|
|
Return (m_puntoH(i).YSrc)
|
|
End Get
|
|
Set(ByVal value As Short)
|
|
m_puntoH(i).YSrc = value
|
|
End Set
|
|
End Property
|
|
|
|
#Region "Caolcolo matrici di correzione prospettica"
|
|
|
|
''' <summary>
|
|
''' Ottine la matrice 'm_MatDir' di correzione prospettica
|
|
''' Viene richiamato il metodo 'CalcolaDatiCorrezioneDiretta'
|
|
''' </summary>
|
|
Private Sub CalcolaDatiCorrezioneDiretta()
|
|
|
|
' L'immagine da rettificare non è un rettangolo
|
|
CalcolaDatiCorrezioneDirettaNoRett()
|
|
' Se ' CalcolaDatiCorrezioneDirettaNoRett' andata a buon fine 'm_ProspCalibrated=true'
|
|
If m_ProspCalibrated Then Exit Sub
|
|
|
|
' -- ALGORITMO ABBANDONATO --
|
|
Dim distmm As Double, distpix As Double, mm2pix As Double
|
|
Dim distXMax As Double, distYMax As Double
|
|
|
|
' prendo i pixel per mm più adeguati per non perdere informazioni
|
|
'lato sopra tl-tr (itl=0, itr=1)
|
|
distmm = Math.Sqrt(Math.Pow(m_pworld(itl).X - m_pworld(itr).X, 2) + Math.Pow(m_pworld(itl).Y - m_pworld(itr).Y, 2))
|
|
distpix = Math.Sqrt(Math.Pow(m_psrc(itl).X - m_psrc(itr).X, 2) + Math.Pow(m_psrc(itl).Y - m_psrc(itr).Y, 2))
|
|
mm2pix = distpix / distmm ' pixel per mm
|
|
distXMax = distmm
|
|
'lato sotto bl-br (ibl=3, ibr=2)
|
|
distmm = Math.Sqrt(Math.Pow(m_pworld(ibl).X - m_pworld(ibr).X, 2) + Math.Pow(m_pworld(ibl).Y - m_pworld(ibr).Y, 2))
|
|
distpix = Math.Sqrt(Math.Pow(m_psrc(ibl).X - m_psrc(ibr).X, 2) + Math.Pow(m_psrc(ibl).Y - m_psrc(ibr).Y, 2))
|
|
If (distpix / distmm > mm2pix) Then mm2pix = distpix / distmm
|
|
If (distmm > distXMax) Then distXMax = distmm
|
|
|
|
'lato sinistro tl-bl (itl=0, ibl=3)
|
|
distmm = Math.Sqrt(Math.Pow(m_pworld(itl).X - m_pworld(ibl).X, 2) + Math.Pow(m_pworld(itl).Y - m_pworld(ibl).Y, 2))
|
|
distpix = Math.Sqrt(Math.Pow(m_psrc(itl).X - m_psrc(ibl).X, 2) + Math.Pow(m_psrc(itl).Y - m_psrc(ibl).Y, 2))
|
|
If (distpix / distmm > mm2pix) Then mm2pix = distpix / distmm
|
|
distYMax = distmm
|
|
'lato destro tr-br (itr=1, ibr=2)
|
|
distmm = Math.Sqrt(Math.Pow(m_pworld(itr).X - m_pworld(ibr).X, 2) + Math.Pow(m_pworld(itr).Y - m_pworld(ibr).Y, 2))
|
|
distpix = Math.Sqrt(Math.Pow(m_psrc(itr).X - m_psrc(ibr).X, 2) + Math.Pow(m_psrc(itr).Y - m_psrc(ibr).Y, 2))
|
|
If (distpix / distmm > mm2pix) Then mm2pix = distpix / distmm
|
|
If (distmm > distYMax) Then distYMax = distmm
|
|
|
|
' -- verifico che l'immagine non sia troppo grande
|
|
Dim widthImagePix As Double = (distXMax + m_ExtXL_mm + m_ExtXR_mm) * mm2pix
|
|
If widthImagePix > m_widthImagePixMax Then
|
|
mm2pix = mm2pix * CDbl(m_widthImagePixMax) / widthImagePix
|
|
End If
|
|
|
|
' allora la nostra nuova bitmap sarà:
|
|
m_dim_XProsp = Convert.ToInt16(distXMax * mm2pix)
|
|
m_dim_YProsp = Convert.ToInt16(distYMax * mm2pix)
|
|
|
|
m_mm2PixelProspZ0 = mm2pix
|
|
|
|
m_ExtXL_pix = Convert.ToInt16(m_ExtXL_mm * m_mm2PixelProspZ0)
|
|
m_ExtXR_pix = Convert.ToInt16(m_ExtXR_mm * m_mm2PixelProspZ0)
|
|
m_ExtYT_pix = Convert.ToInt16(m_ExtYT_mm * m_mm2PixelProspZ0)
|
|
m_ExtYB_pix = Convert.ToInt16(m_ExtYB_mm * m_mm2PixelProspZ0)
|
|
|
|
' -- ALGORITMO DEPRECATO --
|
|
' perchè considera la figura perfettamente rettangolo con i lati paralleli all'immagine
|
|
m_pdst(itl).X = 0 : m_pdst(itl).Y = 0
|
|
m_pdst(itr).X = m_dim_XProsp : m_pdst(itr).Y = 0
|
|
m_pdst(ibl).X = 0 : m_pdst(ibl).Y = m_dim_YProsp
|
|
m_pdst(ibr).X = m_dim_XProsp : m_pdst(ibr).Y = m_dim_YProsp
|
|
|
|
#If WinXP Then
|
|
m_MatDir = Emgu.CV.CameraCalibration.GetPerspectiveTransform(m_pdst, m_psrc) 'scambio dest e source!
|
|
#Else
|
|
_perspMatDir = CvInvoke.GetPerspectiveTransform(m_pdst, m_psrc)
|
|
|
|
' unico modo che ho trovato per passare a mia matrice
|
|
Dim hh(8) As Double
|
|
_perspMatDir.CopyTo(Of Double)(hh)
|
|
For i = 0 To 2
|
|
For j = 0 To 2
|
|
m_MatDir(i, j) = hh(i * 3 + j)
|
|
Next
|
|
Next
|
|
#End If
|
|
|
|
m_Pos_x_z0_mm = m_pworld(ibl).X - m_ExtXL_mm
|
|
m_Pos_y_z0_mm = m_pworld(ibl).Y - m_ExtYB_mm
|
|
m_ProspCalibrated = True
|
|
|
|
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' Ottiene la matrice 'm_MatDir' per la correzione prospettica nel piano Z=0
|
|
''' </summary>
|
|
Private Sub CalcolaDatiCorrezioneDirettaNoRett()
|
|
|
|
Dim distmm As Double, distpix As Double, mm2pix As Double
|
|
Dim distXMax As Double, distYMax As Double
|
|
|
|
If m_ProspCalibrated Then Exit Sub
|
|
|
|
' prendo i pixel per mm più adeguati per non perdere informazioni
|
|
'lato sopra tl-tr
|
|
distmm = Math.Sqrt(Math.Pow(m_pworld(itl).X - m_pworld(itr).X, 2) + Math.Pow(m_pworld(itl).Y - m_pworld(itr).Y, 2))
|
|
distXMax = distmm
|
|
distpix = Math.Sqrt(Math.Pow(m_psrc(itl).X - m_psrc(itr).X, 2) + Math.Pow(m_psrc(itl).Y - m_psrc(itr).Y, 2))
|
|
mm2pix = distpix / distmm ' pixel per mm
|
|
|
|
'lato sotto bl-br
|
|
distmm = Math.Sqrt(Math.Pow(m_pworld(ibl).X - m_pworld(ibr).X, 2) + Math.Pow(m_pworld(ibl).Y - m_pworld(ibr).Y, 2))
|
|
distpix = Math.Sqrt(Math.Pow(m_psrc(ibl).X - m_psrc(ibr).X, 2) + Math.Pow(m_psrc(ibl).Y - m_psrc(ibr).Y, 2))
|
|
If (distpix / distmm > mm2pix) Then mm2pix = distpix / distmm
|
|
If (distmm > distXMax) Then distXMax = distmm
|
|
'lato sinistro tl-bl
|
|
distmm = Math.Sqrt(Math.Pow(m_pworld(itl).X - m_pworld(ibl).X, 2) + Math.Pow(m_pworld(itl).Y - m_pworld(ibl).Y, 2))
|
|
distpix = Math.Sqrt(Math.Pow(m_psrc(itl).X - m_psrc(ibl).X, 2) + Math.Pow(m_psrc(itl).Y - m_psrc(ibl).Y, 2))
|
|
If (distpix / distmm > mm2pix) Then mm2pix = distpix / distmm
|
|
distYMax = distmm
|
|
'lato destro tr-br
|
|
distmm = Math.Sqrt(Math.Pow(m_pworld(itr).X - m_pworld(ibr).X, 2) + Math.Pow(m_pworld(itr).Y - m_pworld(ibr).Y, 2))
|
|
distpix = Math.Sqrt(Math.Pow(m_psrc(itr).X - m_psrc(ibr).X, 2) + Math.Pow(m_psrc(itr).Y - m_psrc(ibr).Y, 2))
|
|
If (distpix / distmm > mm2pix) Then mm2pix = distpix / distmm
|
|
If (distmm > distYMax) Then distYMax = distmm
|
|
|
|
' -- verifico che l'immagine non sia troppo grande
|
|
Dim widthImagePix As Double = (distXMax + m_ExtXL_mm + m_ExtXR_mm) * mm2pix
|
|
If widthImagePix > m_widthImagePixMax Then
|
|
' ???
|
|
mm2pix = mm2pix * CDbl(m_widthImagePixMax) / widthImagePix
|
|
End If
|
|
|
|
' allora la nostra nuova bitmap sarà:
|
|
m_dim_XProsp = Convert.ToInt16(distXMax * mm2pix)
|
|
m_dim_YProsp = Convert.ToInt16(distYMax * mm2pix)
|
|
|
|
m_mm2PixelProspZ0 = mm2pix
|
|
|
|
' ricavo i valori di estesnione dell'immagine in px
|
|
m_ExtXL_pix = Convert.ToInt16(m_ExtXL_mm * m_mm2PixelProspZ0)
|
|
m_ExtXR_pix = Convert.ToInt16(m_ExtXR_mm * m_mm2PixelProspZ0)
|
|
m_ExtYT_pix = Convert.ToInt16(m_ExtYT_mm * m_mm2PixelProspZ0)
|
|
m_ExtYB_pix = Convert.ToInt16(m_ExtYB_mm * m_mm2PixelProspZ0)
|
|
|
|
' fisso l'origine nel punto in alto a sinistra
|
|
Dim Origmm As PointF = m_pworld(itl)
|
|
|
|
' distanza punto_1 (top-right) da Origine in X (itr=1)
|
|
m_pdst(itr).X = (m_pworld(itr).X - m_pworld(itl).X) * m_mm2PixelProspZ0
|
|
' distanza punto_1 da Origine in Y (itr=1)
|
|
m_pdst(itr).Y = -(m_pworld(itr).Y - m_pworld(itl).Y) * m_mm2PixelProspZ0
|
|
|
|
' distanza punto_3 (bottom-left) da Origine in X (ibl=3)
|
|
m_pdst(ibl).X = (m_pworld(ibl).X - m_pworld(itl).X) * m_mm2PixelProspZ0
|
|
' distanza punto_3 da Origine in Y (ibl=3)
|
|
m_pdst(ibl).Y = -(m_pworld(ibl).Y - m_pworld(itl).Y) * m_mm2PixelProspZ0
|
|
|
|
' distanza punto_2 (bottom-right) da Origine in X (ibl=3)
|
|
m_pdst(ibr).X = (m_pworld(ibr).X - m_pworld(itl).X) * m_mm2PixelProspZ0
|
|
' distanza punto_2 (bottom-right) da Origine in Y (ibl=3)
|
|
m_pdst(ibr).Y = -(m_pworld(ibr).Y - m_pworld(itl).Y) * m_mm2PixelProspZ0
|
|
|
|
' distanza punto_0 (top-left) da Origine in X (itr=0), per definizione è l'origine stessa
|
|
m_pdst(itl).X = 0
|
|
' distanza punto_0 (top-left) da Origine in Y (itr=0), per definizione è l'origine stessa
|
|
m_pdst(itl).Y = 0
|
|
|
|
#If WinXP Then
|
|
m_MatDir = Emgu.CV.CameraCalibration.GetPerspectiveTransform(m_pdst, m_psrc) 'scambio dest e source!
|
|
#Else
|
|
' ottengo la matrice di correzione prospettica (di tipo EmguCV.Mat)
|
|
_perspMatDir = CvInvoke.GetPerspectiveTransform(m_pdst, m_psrc)
|
|
|
|
' unico modo che ho trovato per passare a mia matrice
|
|
Dim hh(8) As Double
|
|
_perspMatDir.CopyTo(Of Double)(hh)
|
|
For i = 0 To 2
|
|
For j = 0 To 2
|
|
m_MatDir(i, j) = hh(i * 3 + j)
|
|
Next
|
|
Next
|
|
#End If
|
|
|
|
m_Pos_x_z0_mm = m_pworld(ibl).X - m_ExtXL_mm
|
|
m_Pos_y_z0_mm = m_pworld(ibl).Y - m_ExtYB_mm
|
|
m_ProspCalibrated = True
|
|
|
|
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' Ottiene la matrice 'm_MatInv' per la correzione prospettica nel piano Z=0
|
|
''' </summary>
|
|
Private Sub CalcolaDatiCorrezioneInversa()
|
|
|
|
Dim i As Integer
|
|
|
|
For i = 0 To 3
|
|
m_pdst(i) = m_pworld(i)
|
|
Next
|
|
|
|
#If WinXP Then
|
|
m_MatInv = Emgu.CV.CameraCalibration.GetPerspectiveTransform(m_psrc, m_pdst)
|
|
#Else
|
|
Dim l_MatInv As New Emgu.CV.Mat(2, 3, CvEnum.DepthType.Cv64F, 1)
|
|
l_MatInv = CvInvoke.GetPerspectiveTransform(m_psrc, m_pdst)
|
|
|
|
' unico modo che ho trovato per passare a mia matrice
|
|
Dim hh(8) As Double
|
|
l_MatInv.CopyTo(Of Double)(hh)
|
|
For i = 0 To 2
|
|
For j As Integer = 0 To 2
|
|
m_MatInv(i, j) = hh(i * 3 + j)
|
|
Next
|
|
Next
|
|
#End If
|
|
|
|
End Sub
|
|
|
|
#End Region ' Calcolo matrici di correzione prospettica
|
|
|
|
' Crea file FinalImage.txt
|
|
Private Sub SaveDataImage(NomeFile As String)
|
|
CalcolaCorrezioniAltezza()
|
|
Dim writer As New StreamWriter(NomeFile)
|
|
|
|
writer.WriteLine("X = {0}", m_Pos_x_mm.ToString("F9", CultureInfo.InvariantCulture))
|
|
writer.WriteLine("Y = {0}", m_Pos_y_mm.ToString("F9", CultureInfo.InvariantCulture))
|
|
writer.WriteLine("X_ScaleCenter = {0}", m_scale_center.x.ToString("F9", CultureInfo.InvariantCulture))
|
|
writer.WriteLine("Y_ScaleCenter = {0}", m_scale_center.y.ToString("F9", CultureInfo.InvariantCulture))
|
|
writer.WriteLine("Pixelxmm = {0}", m_mm2PixelProspFinal.ToString("F9", CultureInfo.InvariantCulture))
|
|
writer.WriteLine("Z_Lastra = {0}", m_SpessLastra.ToString("F9", CultureInfo.InvariantCulture))
|
|
writer.WriteLine("Z_scalexmm = {0}", m_fscalaxmm.ToString("F14", CultureInfo.InvariantCulture))
|
|
writer.WriteLine("Z_ScaleCenter = {0}", m_scale_centerZ.ToString("F9", CultureInfo.InvariantCulture))
|
|
writer.WriteLine("Z_Cali = {0}", m_ZCali.ToString("F9", CultureInfo.InvariantCulture))
|
|
|
|
writer.Close()
|
|
End Sub
|
|
|
|
Public Sub CorrezioneCompleta(Optional rEvents As Boolean = True)
|
|
Try
|
|
|
|
m_UndistImage = Nothing
|
|
|
|
Console.WriteLine("RICHIESTA CORREZIONE DISTORSIONE: " & MainModule.IndexProc)
|
|
|
|
' Correzione distorsione
|
|
Correggi()
|
|
|
|
If rEvents Then RaiseEvent FineCorrezioneLente()
|
|
|
|
Console.WriteLine("RICHIESTA CORREZIONE PROSPETTICA: " & MainModule.IndexProc)
|
|
|
|
CorreggiProspettiva(SpessLastra)
|
|
|
|
If rEvents Then RaiseEvent FineCorrezioneProspettiva()
|
|
|
|
Catch ex As Exception
|
|
RaiseEvent ProcessAborted(-1)
|
|
End Try
|
|
|
|
End Sub
|
|
|
|
Private Sub CalcolaMatriceCorrezioneProspettiva()
|
|
|
|
Dim ix As Integer, iy As Integer
|
|
Dim px As Single, py As Single
|
|
Dim m00 As Double, m01 As Double, m02 As Double
|
|
Dim m10 As Double, m11 As Double, m12 As Double
|
|
Dim m20 As Double, m21 As Double, m22 As Double
|
|
Dim m01iy As Double, m11iy As Double, m21iy As Double
|
|
|
|
Try
|
|
|
|
|
|
If m_UndistImage Is Nothing Then Return
|
|
m_dimx = m_UndistImage.Width
|
|
m_dimy = m_UndistImage.Height
|
|
|
|
CalcolaDatiCorrezioneDiretta()
|
|
|
|
m_SpessLastra = SpessLastra
|
|
|
|
' correggo calcolando i pixel (con funzione opencv non riesco a estendere)
|
|
|
|
m00 = m_MatDir(0, 0) : m01 = m_MatDir(0, 1) : m02 = m_MatDir(0, 2)
|
|
m10 = m_MatDir(1, 0) : m11 = m_MatDir(1, 1) : m12 = m_MatDir(1, 2)
|
|
m20 = m_MatDir(2, 0) : m21 = m_MatDir(2, 1) : m22 = m_MatDir(2, 2)
|
|
|
|
|
|
m_dim_XProspExt = m_dim_XProsp + m_ExtXL_pix + m_ExtXR_pix
|
|
m_dim_YProspExt = m_dim_YProsp + m_ExtYT_pix + m_ExtYB_pix
|
|
|
|
ReDim MatConvP(m_dim_XProspExt, m_dim_YProspExt)
|
|
|
|
For iy = 0 To m_dim_YProspExt - 1
|
|
Dim iy2 As Integer = iy - m_ExtYT_pix
|
|
m01iy = m01 * iy2
|
|
m11iy = m11 * iy2
|
|
m21iy = m21 * iy2
|
|
|
|
For ix = 0 To m_dim_XProspExt - 1
|
|
|
|
Dim ix2 As Short = ix - m_ExtXL_pix
|
|
px = (m00 * ix2 + m01iy + m02) / (m20 * ix2 + m21iy + m22)
|
|
py = (m10 * ix2 + m11iy + m12) / (m20 * ix2 + m21iy + m22)
|
|
MatConvP(ix, iy) = New clPuntoPix
|
|
|
|
If px >= 0 And px < m_dimx And py >= 0 AndAlso py < m_dimy Then
|
|
MatConvP(ix, iy).X = px
|
|
MatConvP(ix, iy).Y = py
|
|
Else
|
|
MatConvP(ix, iy).X = -1
|
|
MatConvP(ix, iy).Y = -1
|
|
End If
|
|
|
|
|
|
Next
|
|
Next
|
|
m_bMatProspOk = True
|
|
|
|
|
|
Catch ex As Exception
|
|
m_bMatProspOk = False
|
|
Throw New Exception(ex.Message)
|
|
End Try
|
|
|
|
|
|
End Sub
|
|
|
|
Private Sub CorreggiProspettivaDaMatriceOCV(spessLastra As Double)
|
|
|
|
Console.WriteLine("INIZIO CREAZIONE IMMAGINE CON CORREZIONE OCV: " & MainModule.IndexProc)
|
|
|
|
Dim flags As Integer = Emgu.CV.CvEnum.Inter.Linear
|
|
Dim fillVal As New MCvScalar(0, 0, 0, 0)
|
|
Dim dstImage As New Image(Of Emgu.CV.Structure.Rgb, Byte)(m_dim_XProspExt, m_dim_YProspExt)
|
|
|
|
Emgu.CV.CvInvoke.Remap(New Image(Of Emgu.CV.Structure.Rgb, Byte)(m_UndistImage), dstImage, _ocvMapx, _ocvMapy, flags, BorderType.Default)
|
|
m_FinalImage = dstImage.Bitmap
|
|
|
|
SaveBitmap(m_FinalImage, SaveDir & "FinalImage.jpg")
|
|
|
|
Console.WriteLine("FINE CREAZIONE IMMAGINE CON CORREZIONE OCV: " & MainModule.IndexProc)
|
|
|
|
SaveDataImage(SaveDir & "FinalImage.txt")
|
|
End Sub
|
|
|
|
Private Shared Function GetEncoderInfo(ByVal mimeType As String) As ImageCodecInfo
|
|
' Get image codecs for all image formats
|
|
Dim codecs As ImageCodecInfo() = ImageCodecInfo.GetImageEncoders()
|
|
|
|
' Find the correct image codec
|
|
For i As Integer = 0 To codecs.Length - 1
|
|
If (codecs(i).MimeType = mimeType) Then
|
|
Return codecs(i)
|
|
End If
|
|
Next i
|
|
|
|
Return Nothing
|
|
End Function
|
|
|
|
Private Sub CalcolaMatriceOCV()
|
|
|
|
Dim ix As Integer, iy As Integer
|
|
_ocvMapx = New Matrix(Of Single)(m_dim_YProspExt, m_dim_XProspExt)
|
|
_ocvMapy = New Matrix(Of Single)(m_dim_YProspExt, m_dim_XProspExt)
|
|
|
|
|
|
For iy = 0 To m_dim_YProspExt - 1
|
|
For ix = 0 To (m_dim_XProspExt - 1)
|
|
_ocvMapx(iy, ix) = MatConvP(ix, iy).X
|
|
_ocvMapy(iy, ix) = MatConvP(ix, iy).Y
|
|
Next
|
|
Next
|
|
|
|
|
|
End Sub
|
|
|
|
Private Sub CalcolaCorrezioniAltezza()
|
|
' fattore di scala data la nuova altezza
|
|
Dim fattScala As Double
|
|
m_SpessCorr = m_SpessLastra - m_ZCali
|
|
|
|
fattScala = Pow(m_fscalaxmm, m_SpessCorr)
|
|
m_mm2PixelProspFinal = m_mm2PixelProspZ0 / fattScala
|
|
|
|
m_Pos_x_mm = m_Pos_x_z0_mm - m_scale_center.x
|
|
m_Pos_y_mm = m_Pos_y_z0_mm - m_scale_center.y
|
|
m_Pos_x_mm = m_Pos_x_mm * fattScala
|
|
m_Pos_y_mm = m_Pos_y_mm * fattScala
|
|
m_Pos_x_mm = m_Pos_x_mm + m_scale_center.x
|
|
m_Pos_y_mm = m_Pos_y_mm + m_scale_center.y
|
|
|
|
End Sub
|
|
|
|
Public Sub SaveClickMsg(numerr As Integer)
|
|
Dim NomeFile As String
|
|
|
|
Dim nf As Integer
|
|
NomeFile = SaveDir & "click.txt"
|
|
nf = FreeFile()
|
|
FileOpen(nf, NomeFile, OpenMode.Output)
|
|
Print(nf, "Err=" & numerr.ToString)
|
|
FileClose(nf)
|
|
|
|
End Sub
|
|
|
|
' questa è la correzione inversa a quello che mi serve...
|
|
Public Function CorreggiPunto(p As Point) As Point
|
|
Dim po As Point
|
|
po.X = MatConvP(p.X, p.Y).X
|
|
po.Y = MatConvP(p.X, p.Y).Y
|
|
Return po
|
|
End Function
|
|
|
|
#End Region
|
|
|
|
Public Sub FreeImages()
|
|
If m_UndistImage IsNot Nothing Then m_UndistImage.Dispose()
|
|
m_UndistImage = Nothing
|
|
If m_FinalImage IsNot Nothing Then m_FinalImage.Dispose()
|
|
m_FinalImage = Nothing
|
|
If m_InputImage IsNot Nothing Then m_InputImage.Dispose()
|
|
m_InputImage = Nothing
|
|
End Sub
|
|
|
|
#Region "Conversioni da mm a pixel e viceversa su Img già raddrizzata"
|
|
|
|
Public Sub MM2PixOnUndist(pmm As PointF, ByRef ppx As PointF)
|
|
If _thprocess IsNot Nothing AndAlso _thprocess.IsAlive Then Return
|
|
CalcolaCorrezioniAltezza()
|
|
ppx.X = (pmm.X - m_Pos_x_mm) * m_mm2PixelProspFinal
|
|
ppx.Y = m_FinalImage.Height - (pmm.Y - m_Pos_y_mm) * m_mm2PixelProspFinal
|
|
|
|
End Sub
|
|
|
|
Public Sub Pix2MMOnUndist(ppx As PointF, ByRef pmm As PointF)
|
|
If _thprocess IsNot Nothing AndAlso _thprocess.IsAlive Then Return
|
|
CalcolaCorrezioniAltezza()
|
|
pmm.X = ppx.X / m_mm2PixelProspFinal + m_Pos_x_mm
|
|
If m_FinalImage IsNot Nothing Then
|
|
pmm.Y = (m_FinalImage.Height - ppx.Y) / m_mm2PixelProspFinal + m_Pos_y_mm
|
|
End If
|
|
End Sub
|
|
|
|
Public Function SaveModelFromRectangle(FileName As String, xLeft As Double, yTop As Double, xRight As Double, yBottom As Double)
|
|
Try
|
|
If FinalImage Is Nothing Then Return False
|
|
|
|
|
|
Dim cvimage As New Image(Of Emgu.CV.Structure.Bgr, Byte)(FinalImage)
|
|
|
|
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)
|
|
|
|
Dim rmodel As New Rectangle(x1, y1, w, h)
|
|
cvimage.ROI = rmodel
|
|
cvimage.Save(FileName)
|
|
|
|
|
|
Return True
|
|
Catch ex As Exception
|
|
Return False
|
|
End Try
|
|
|
|
End Function
|
|
|
|
|
|
#End Region
|
|
|
|
End Class
|
|
|
|
|
|
|