1715 lines
53 KiB
VB.net
1715 lines
53 KiB
VB.net
Option Strict Off
|
|
Option Explicit On
|
|
Imports System.IO
|
|
Imports System.IO.Path
|
|
Imports System.Runtime.InteropServices
|
|
Imports System.Windows.Forms
|
|
Imports System.Drawing
|
|
Imports Emgu.CV
|
|
Imports Emgu.Util
|
|
Imports System.Text
|
|
Imports System.Globalization
|
|
|
|
Public Class FrmMain
|
|
'Implements Observer
|
|
|
|
Private Enum en_status
|
|
NoImage
|
|
ImageFromCamera
|
|
Calibration
|
|
ImgCorrected
|
|
DefAree
|
|
DefTexp
|
|
DefStone
|
|
DefVentosa
|
|
End Enum
|
|
Private m_Image As System.Drawing.Image
|
|
Private m_ZoomFactor As Double
|
|
' Permette di aggiornare la pagina principale del programma 'SetFormStatus()'
|
|
Private status As en_status
|
|
Private frmSce As New FrmScelta
|
|
Private WithEvents ImageMng As New clsImageMng
|
|
Public WithEvents Camera As New clsCamera
|
|
Private _visione As New clsVisione(ImageMng)
|
|
Private _ActTh As Integer = 70
|
|
Private _numImage As Integer = -1
|
|
Private _maxImage As Integer = 0
|
|
Private _npProspSel As Integer = -1
|
|
Private _borderType As Integer
|
|
Private WithEvents _search As New clsRicerca(ImageMng)
|
|
Private Event _waitingCmd()
|
|
|
|
Private Sub BtnTakeFoto_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnTakeFoto.Click
|
|
|
|
CorrezioneAutomatica = False
|
|
|
|
EseguiScatto()
|
|
|
|
End Sub
|
|
Protected Overrides Sub Finalize()
|
|
If (Camera.Connected) Then
|
|
Camera.Disconnect()
|
|
End If
|
|
MyBase.Finalize()
|
|
End Sub
|
|
|
|
Private Sub BtnCfg_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnCfg.Click
|
|
'CfgForm.LbDeviceDescription.Text = Camera.cameraModelFactory
|
|
CfgForm.LbDeviceStatus.Text = If(Camera.Connected, "Connected", "Disconnected")
|
|
' assegnato solo dall'evento connessione, perciò lo ribadisco
|
|
CfgForm.LbCameraID.Text = Camera.CameraID
|
|
CfgForm.ShowDialog()
|
|
End Sub
|
|
|
|
Private Sub BtnEnd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnEnd.Click
|
|
Me.Close()
|
|
End Sub
|
|
|
|
Private Sub BtnLoad_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
|
|
|
|
OpenFileDialog1.InitialDirectory = SaveDir
|
|
OpenFileDialog1.FileName = ""
|
|
OpenFileDialog1.Filter = "JPEG Format (*.JPG)|*.jpg|BMP Format (*.BMP) |*.bmp"
|
|
OpenFileDialog1.CheckFileExists = True
|
|
OpenFileDialog1.ShowDialog()
|
|
ImageMng.Corrected = False
|
|
ImageControl1.Image = Nothing
|
|
GC.Collect()
|
|
If Len(OpenFileDialog1.FileName) > 0 Then
|
|
m_Image = Nothing
|
|
m_Image = New Bitmap(OpenFileDialog1.FileName)
|
|
ImageControl1.Image = m_Image
|
|
ImageControl1.fittoscreen()
|
|
LeggiExif(OpenFileDialog1.FileName)
|
|
status = en_status.ImageFromCamera
|
|
End If
|
|
SetFormStatus()
|
|
End Sub
|
|
|
|
Private Sub BtnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnSave.Click
|
|
|
|
' recupero l'immagine che avevo già salvato
|
|
Dim objBmp As New Drawing.Bitmap(SaveDir & "FinalImage.jpg")
|
|
|
|
Dim NomeFile, NomeFile2, NomeSou As String
|
|
Dim nf As Integer
|
|
Dim xyDpi As Single
|
|
|
|
KeyBoard.Text = Format(Now, "yyMMdd_HHmmss") ' la stringa di uscita
|
|
KeyBoard.ShowDialog()
|
|
|
|
' Sistemare !!!!
|
|
If Len(KeyBoard.Text) > 0 Then
|
|
|
|
' nel file jpeg non so se questo settaggio viene salvato
|
|
NomeFile = SaveDir & KeyBoard.Text & ".jpg"
|
|
xyDpi = 25.4 * ImageMng.mm2pixelAtZ ' se calibrazione distorsione lente, non serve
|
|
objBmp.SetResolution(xyDpi, xyDpi)
|
|
Try
|
|
objBmp.Save(NomeFile, System.Drawing.Imaging.ImageFormat.Jpeg)
|
|
NomeFile2 = SaveDir & "click.txt"
|
|
nf = FreeFile()
|
|
FileOpen(nf, NomeFile2, OpenMode.Output)
|
|
Print(nf, "Err=0")
|
|
FileClose(nf)
|
|
Catch
|
|
MsgBox("File Save Error")
|
|
End Try
|
|
Try
|
|
NomeSou = SaveDir & "FinalImage.txt"
|
|
NomeFile2 = SaveDir & KeyBoard.Text & ".txt"
|
|
File.Copy(NomeSou, NomeFile2, True)
|
|
Catch ex As Exception
|
|
MsgBox("File Aux Save Error")
|
|
End Try
|
|
End If
|
|
objBmp.Dispose()
|
|
objBmp = Nothing
|
|
status = en_status.NoImage
|
|
End Sub
|
|
|
|
Private Sub SetFormStatus()
|
|
|
|
If Camera.Connected Then
|
|
BtnTakeFoto.ImageIndex = 0
|
|
TStatus.Text = "CameraID = " & Camera.CameraID
|
|
Else
|
|
BtnTakeFoto.ImageIndex = 1
|
|
TStatus.Text = "--"
|
|
End If
|
|
|
|
BtnCfg.Visible = bExtended
|
|
BtnCorrProsp.Visible = False 'bExtended
|
|
|
|
BtnVentosa.Visible = VacuumCheckEnable
|
|
btnSearch.Visible = VacuumCheckEnable
|
|
|
|
Select Case status
|
|
Case en_status.NoImage
|
|
GBCalibration.Visible = False
|
|
GBCorrected.Visible = False
|
|
GBImgFromCam.Visible = False
|
|
BtnLoad.Visible = bBtnLoad
|
|
BtnTakeFoto.Visible = True
|
|
GBDefAree.Visible = False
|
|
|
|
Case en_status.ImageFromCamera
|
|
GBCalibration.Visible = False
|
|
GBCorrected.Visible = False
|
|
GBImgFromCam.Visible = True
|
|
BtnLoad.Visible = bBtnLoad
|
|
BtnTakeFoto.Visible = True
|
|
GBDefAree.Visible = False
|
|
|
|
Case en_status.Calibration
|
|
GBCalibration.Visible = True
|
|
GBCorrected.Visible = False
|
|
GBImgFromCam.Visible = False
|
|
BtnLoad.Visible = False
|
|
BtnTakeFoto.Visible = False
|
|
GBDefAree.Visible = False
|
|
|
|
Case en_status.ImgCorrected
|
|
GBCalibration.Visible = False
|
|
GBCorrected.Visible = True
|
|
GBImgFromCam.Visible = False
|
|
BtnLoad.Visible = bBtnLoad
|
|
BtnTakeFoto.Visible = True
|
|
GBDefAree.Visible = False
|
|
|
|
Case en_status.DefAree
|
|
GBCalibration.Visible = False
|
|
GBCorrected.Visible = False
|
|
GBImgFromCam.Visible = False
|
|
BtnLoad.Visible = False
|
|
BtnTakeFoto.Visible = False
|
|
GBDefAree.Visible = True
|
|
BtnExpT.Visible = True
|
|
BtnStone.Visible = True
|
|
BtnVentosa.Visible = VacuumCheckEnable
|
|
BtnSaveAree.Visible = False
|
|
BtnExpT.Enabled = _visione.ExpCorrType <> clsVisione.eExpCorrMode.none
|
|
BtnAbortDefAree.Text = "Close"
|
|
|
|
Case en_status.DefTexp, en_status.DefStone, en_status.DefVentosa
|
|
GBCalibration.Visible = False
|
|
GBCorrected.Visible = False
|
|
GBImgFromCam.Visible = False
|
|
BtnLoad.Visible = False
|
|
BtnTakeFoto.Visible = False
|
|
GBDefAree.Visible = True
|
|
BtnExpT.Visible = False
|
|
BtnStone.Visible = False
|
|
BtnVentosa.Visible = False
|
|
BtnSaveAree.Visible = True
|
|
BtnExpT.Enabled = _visione.ExpCorrType <> clsVisione.eExpCorrMode.none
|
|
BtnAbortDefAree.Text = "Abort"
|
|
|
|
End Select
|
|
|
|
PosizionaControlli()
|
|
End Sub
|
|
|
|
Public Sub Inizializza()
|
|
' non visualizzo pagina programma
|
|
If Not ModalitaNascosta Then FrmStart.Show()
|
|
|
|
Application.DoEvents()
|
|
|
|
SpessLastra = 0
|
|
|
|
LeggiFileConfigurazione()
|
|
|
|
AggiornaPulsantiVIsibili()
|
|
MostraStato()
|
|
|
|
If Not ImageMng.SetFileCalibrazione(FileLensCalib, FileCalibProsp) Then
|
|
StatoGenerale = statoGenEnum.ErroreCalibrazione
|
|
TStatus.Text = "Error in Calibration Files"
|
|
End If
|
|
|
|
Camera.LbImageStatus = LbImageStatus
|
|
|
|
ProgressBar.Minimum = 0
|
|
ProgressBar.Maximum = 100
|
|
ProgressBar.Value = 0
|
|
|
|
SetFormStatus()
|
|
' connessione automatica
|
|
Camera.Connect(Camera.CameraID)
|
|
Console.WriteLine("RICHIESTA CONNESSIONE: " & Camera.CameraID)
|
|
MessageBox.Show(Camera.CameraID)
|
|
'Me.Text = "ID Camera = " & Camera.CameraID
|
|
status = en_status.NoImage
|
|
SetFormStatus()
|
|
SpessLastra = ImageMng.ZCali
|
|
FrmStart.Close()
|
|
|
|
If Camera.Connected And RichiestaFoto Then
|
|
Camera.TakeFoto()
|
|
RichiestaFoto = False
|
|
End If
|
|
|
|
If VacuumCheckEnable Then
|
|
TimerMain.Enabled = True
|
|
End If
|
|
|
|
End Sub
|
|
|
|
Public Sub WaitingForInstruction() Handles Me._waitingCmd
|
|
Dim sNewReadLine As String = Console.ReadLine
|
|
If Not String.IsNullOrEmpty(sNewReadLine) Then
|
|
While sNewReadLine <> "CLOSE"
|
|
Select Case sNewReadLine
|
|
Case "0"
|
|
ModalitaNascosta = True
|
|
Hide()
|
|
LeggiFileConfigurazione()
|
|
Case "1"
|
|
ModalitaNascosta = False
|
|
Visible = True
|
|
Case "2"
|
|
CorrezioneAutomatica = False
|
|
'RichiestaBordi = False
|
|
Console.WriteLine("CAMERA BODY: " & Camera.CameraID)
|
|
RichiestaClick()
|
|
Case "3"
|
|
RichiestaStatoCamera()
|
|
Case "4"
|
|
ScattoBackGround()
|
|
Case "5"
|
|
RichiestaBordi = True
|
|
RichiestaClick()
|
|
Case "6"
|
|
RipetiThreshold()
|
|
Case "7"
|
|
Console.WriteLine("PROCESSO ATTIVO: " & MainModule.IndexProc)
|
|
sNewReadLine = Console.ReadLine
|
|
Continue While
|
|
Case Else
|
|
Console.WriteLine("COMANDO NON DECODIFICATO: " & MainModule.IndexProc)
|
|
sNewReadLine = Console.ReadLine
|
|
Continue While
|
|
End Select
|
|
sNewReadLine = Console.ReadLine
|
|
End While
|
|
End If
|
|
End Sub
|
|
|
|
Private Sub BtnDelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
|
|
'CancelFile(Camera.PhotoFileName)
|
|
CancelDir(DirTmp)
|
|
|
|
End Sub
|
|
|
|
Private Sub FrmMain_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
|
|
Try
|
|
If Camera.Connected Then
|
|
Camera.Disconnect()
|
|
End If
|
|
|
|
Catch ex As Exception
|
|
|
|
End Try
|
|
End
|
|
End Sub
|
|
|
|
Private Sub FrmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
|
|
|
|
Dim strWinXP As String = ""
|
|
|
|
#If WinXp Then
|
|
strWinXP = " (WinXP)"
|
|
#End If
|
|
|
|
Me.Text = "EgalTech Camera Manager" & strWinXP & " v" & System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()
|
|
BtnLoad.Visible = bExtended
|
|
ImageControl1.PanMode = True
|
|
Inizializza()
|
|
TStatus.Text = "Initialized"
|
|
If ModalitaNascosta Then Me.Visible = False
|
|
End Sub
|
|
|
|
Private Sub LeggiExif(ByVal FileName As String)
|
|
' qui potrei vedere se leggo gli exif ...
|
|
Try
|
|
Dim EW As New ExifWorks(FileName)
|
|
LbFocalLenght.Text = EW.FocalLength.ToString("0.0mm")
|
|
|
|
LbFocalLenght.Text = EW.Artist
|
|
|
|
FocalLength = EW.FocalLength
|
|
|
|
|
|
'Console.WriteLine(EW.ToString())
|
|
EW.Dispose()
|
|
Catch ex As Exception
|
|
End Try
|
|
|
|
End Sub
|
|
|
|
Private Sub ImageControl1_NewMousePosImage(pima As System.Drawing.PointF) Handles ImageControl1.NewMousePosImage
|
|
|
|
lbMousePosmm.Text = "px: X" & pima.X.ToString("0.00") & " Y" & pima.Y.ToString("0.00")
|
|
|
|
If ImageMng.Corrected Then
|
|
Try
|
|
Dim pmm As PointF
|
|
ImageMng.Pix2MMOnUndist(pima, pmm)
|
|
lbMousePosmm.Text = lbMousePosmm.Text & " mm: X" & pmm.X.ToString("0.00") & " Y" & pmm.Y.ToString("0.00")
|
|
Catch ex As Exception
|
|
|
|
End Try
|
|
End If
|
|
End Sub
|
|
Private Sub ImageControl1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles ImageControl1.Paint
|
|
SetFormStatus()
|
|
End Sub
|
|
Private Sub CaliForm2Data()
|
|
Dim i As Integer
|
|
|
|
For i = 0 To 3
|
|
ImageMng.m_psrc(i).X = ImageControl1.DBoard.GetXCorner(i)
|
|
ImageMng.m_psrc(i).Y = ImageControl1.DBoard.GetYCorner(i)
|
|
ImageMng.XHpix(i) = ImageControl1.DBoard.GetXHpx(i)
|
|
ImageMng.YHpix(i) = ImageControl1.DBoard.GetYHpx(i)
|
|
Next
|
|
ImageMng.CalcolaDatiCorrezione()
|
|
ImageMng.SalvaFileCorrezioneProsp()
|
|
End Sub
|
|
Private Sub CaliData2Form()
|
|
|
|
Dim i As Integer
|
|
For i = 0 To 3
|
|
ImageControl1.DBoard.SetPuntoCorner(i, ImageMng.m_psrc(i).X, ImageMng.m_psrc(i).Y)
|
|
ImageControl1.DBoard.SetPuntoH(i, ImageMng.XHpix(i), ImageMng.YHpix(i))
|
|
Next
|
|
LbAltCali.Text = Format(ImageMng.m_ZCali, "0.00") & " mm"
|
|
LbAltRif.Text = Format(ImageMng.m_AltRif, "0.00") & " mm"
|
|
End Sub
|
|
|
|
' TODO DA sistemare
|
|
Private Sub AreaForm2Data()
|
|
Dim i As Integer
|
|
|
|
For i = 0 To 3
|
|
ImageMng.m_psrc(i).X = ImageControl1.DBoard.GetXCorner(i)
|
|
ImageMng.m_psrc(i).Y = ImageControl1.DBoard.GetYCorner(i)
|
|
Next
|
|
' ImageMng.SalvaDatiArea()
|
|
End Sub
|
|
Private Sub AreaData2Form()
|
|
|
|
Dim i As Integer
|
|
For i = 0 To 3
|
|
ImageControl1.DBoard.SetPuntoCorner(i, ImageMng.m_psrc(i).X, ImageMng.m_psrc(i).Y)
|
|
Next
|
|
End Sub
|
|
|
|
|
|
Private Sub BtnCorrCompleta_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnCorrCompleta.Click
|
|
|
|
frmSce.ShowDialog()
|
|
Refresh()
|
|
Me.Cursor = Cursors.WaitCursor
|
|
CorrezioneCompleta()
|
|
Me.Cursor = Cursors.Default
|
|
End Sub
|
|
Private Sub BtnCorrLens_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnCorrLens.Click
|
|
Try
|
|
|
|
status = en_status.Calibration
|
|
Me.Cursor = Cursors.WaitCursor
|
|
SetFormStatus()
|
|
Refresh()
|
|
ImageMng.Correggi()
|
|
ProgressBar.Value = 0
|
|
ImageControl1.Image = ImageMng.UndistorcedImage
|
|
ImageControl1.fittoscreen()
|
|
GC.Collect()
|
|
CaliData2Form()
|
|
ImageControl1.DBoard.VisPuntiCorner = True
|
|
ImageControl1.DBoard.VisPuntiCaliH = True
|
|
ImageControl1.Refresh()
|
|
Catch ex As Exception
|
|
TStatus.Text = "Process Aborted"
|
|
Finally
|
|
Me.Cursor = Cursors.Default
|
|
End Try
|
|
|
|
End Sub
|
|
|
|
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
|
|
ImageControl1.fittoscreen()
|
|
End Sub
|
|
|
|
Private Sub BtnZoom11_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
|
|
ImageControl1.ZoomFactor = 1
|
|
End Sub
|
|
|
|
Private Sub TimerZoom_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimerZoom.Tick
|
|
If m_ZoomFactor <> 1 And m_ZoomFactor <> 0 Then
|
|
ImageControl1.ZoomFactor = ImageControl1.ZoomFactor * m_ZoomFactor
|
|
Else
|
|
TimerZoom.Enabled = False
|
|
End If
|
|
End Sub
|
|
|
|
Private Sub BtnZoomPiu_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs)
|
|
m_ZoomFactor = 1.05
|
|
ImageControl1.ZoomFactor = ImageControl1.ZoomFactor * m_ZoomFactor
|
|
TimerZoom.Enabled = True
|
|
End Sub
|
|
|
|
Private Sub BtnZoomPiu_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs)
|
|
TimerZoom.Enabled = False
|
|
m_ZoomFactor = 1
|
|
End Sub
|
|
|
|
Private Sub FrmMain_Resize(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Resize
|
|
PosizionaControlli()
|
|
End Sub
|
|
Private Sub PosizionaControlli()
|
|
' Posizione di ancoraggio (in alto a sinistra sullo schermo)
|
|
Dim x As Integer, y As Integer
|
|
Dim Width As Integer, Height As Integer
|
|
Dim XGroupBoxes As Integer
|
|
x = ImageControl1.Location.X
|
|
y = 50
|
|
Width = Me.Size.Width - x - 150
|
|
Height = Me.Size.Height - y - 40 - StatusStrip1.Height
|
|
|
|
ImageControl1.SetBounds(x, y, Width, Height)
|
|
XGroupBoxes = x + Width + 5
|
|
|
|
BtnTakeFoto.SetBounds(XGroupBoxes + 10, BtnTakeFoto.Location.Y, 60, 50)
|
|
BtnEnd.SetBounds(Me.Size.Width - 80, Me.Size.Height - 90 - StatusStrip1.Height, 60, 50)
|
|
' BtnLoad.SetBounds(XGroupBoxes + 10, BtnLoad.Location.Y, 60, 50)
|
|
|
|
y = BtnTakeFoto.Location.Y + BtnTakeFoto.Size.Height + 1
|
|
GBImgFromCam.SetBounds(XGroupBoxes, y, 100, 330)
|
|
GBCalibration.SetBounds(XGroupBoxes, 30, 100, 370)
|
|
GBCorrected.SetBounds(XGroupBoxes, y, 100, 330)
|
|
GBDefAree.SetBounds(XGroupBoxes, y, 100, 330)
|
|
|
|
'ProgressBar1.SetBounds(ImageControl1.Location.X, ImageControl1.Location.Y + ImageControl1.Size.Height / 2, ImageControl1.Size.Width, ProgressBar1.Size.Height)
|
|
|
|
'ProgressBar.Width = StatusStrip1.Size.Width - TStatus.Width
|
|
|
|
End Sub
|
|
|
|
Private Sub BtnSaveCal_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnSaveCal.Click
|
|
FineCalibrazione(True)
|
|
End Sub
|
|
Private Sub BtnAbortCal_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnAbortCal.Click
|
|
FineCalibrazione(False)
|
|
End Sub
|
|
|
|
Private Sub BtnCorrProsp_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnCorrProsp.Click
|
|
ImageMng.CorreggiProspettiva(SpessLastra)
|
|
GC.Collect()
|
|
SetFormStatus()
|
|
End Sub
|
|
|
|
Private Sub BtnZoomPan_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnZoomPan.Click
|
|
ImageControl1.PanMode = Not ImageControl1.PanMode
|
|
End Sub
|
|
Private Sub FineCalibrazione(ByVal bsalva As Boolean)
|
|
If bsalva Then CaliForm2Data()
|
|
|
|
ImageControl1.DBoard.VisPuntiCorner = False
|
|
ImageControl1.DBoard.VisPuntiCaliH = False
|
|
If m_Image IsNot Nothing Then
|
|
m_Image.Dispose()
|
|
m_Image = Nothing
|
|
End If
|
|
status = en_status.NoImage
|
|
ImageControl1.Image = Nothing
|
|
ImageControl1.Refresh()
|
|
SetFormStatus()
|
|
|
|
End Sub
|
|
Private Sub LbAltCali_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LbAltCali.Click
|
|
NumPad.Text = Format(ImageMng.m_ZCali, "0.00") ' la stringa di uscita
|
|
NumPad.ShowDialog()
|
|
ImageMng.m_ZCali = Val(NumPad.Text)
|
|
LbAltCali.Text = Format(ImageMng.m_ZCali, "0.00") & " mm"
|
|
End Sub
|
|
|
|
Private Sub LbAltRif_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LbAltRif.Click
|
|
NumPad.Text = Format(ImageMng.m_AltRif, "0.00") ' la stringa di uscita
|
|
NumPad.ShowDialog()
|
|
ImageMng.m_AltRif = Val(NumPad.Text)
|
|
LbAltRif.Text = Format(ImageMng.m_AltRif, "0.00") & " mm"
|
|
End Sub
|
|
|
|
Private Sub FrmMain_VisibleChanged(sender As Object, e As System.EventArgs) Handles Me.VisibleChanged
|
|
If ModalitaNascosta Then
|
|
Me.Hide()
|
|
RaiseEvent _waitingCmd()
|
|
End If
|
|
End Sub
|
|
|
|
Private Sub LeggiFileConfigurazione()
|
|
Dim NomeFileCfg, TmpString As String
|
|
Dim NomeFileIni, DirToReadCfg As String
|
|
Dim TmpInt As Integer
|
|
Dim TmpDou As Double
|
|
Dim reader As StreamReader
|
|
Dim nfi As NumberFormatInfo = New CultureInfo("en-US", False).NumberFormat
|
|
|
|
' tutto parte dal file DataRoot.ini che deve trovarsi nella stessa
|
|
' cartelle dell'eseguibile
|
|
NomeFileIni = Application.StartupPath & "\DataRoot.ini"
|
|
|
|
DirToReadCfg = ""
|
|
|
|
DirToReadCfg = GetIniValue("Data", "DataRoot", NomeFileIni, DirToReadCfg)
|
|
DirToReadCfg = DirToReadCfg & MainModule.IndexProc.ToString()
|
|
Debug.Assert(DirToReadCfg <> "")
|
|
|
|
NomeFileCfg = DirToReadCfg & "\CameraMng.cfg"
|
|
|
|
' default sovrascritti dalla letture del file cfg
|
|
LensCalibType = 0
|
|
SaveDir = "c:\CameraMng\Data\"
|
|
FileLensCalib = "c:\CameraMng\Clens\Calib.txt"
|
|
DirTmp = "c:\CameraMng\tmp"
|
|
FileCalibProsp = "c:\CameraMng\Calib.txt"
|
|
FileCalibRes = "c:\CameraMng\CaliRes.bin"
|
|
SaveLogDir = ""
|
|
|
|
VacFileStart = ""
|
|
VacFilePos = ""
|
|
VacFileEnd = ""
|
|
VacDirModels = ""
|
|
|
|
bExtended = False
|
|
bBtnLoad = False
|
|
|
|
reader = New StreamReader(NomeFileCfg)
|
|
nfi.NumberDecimalSeparator = "."
|
|
|
|
|
|
TmpString = ""
|
|
Try
|
|
While (Not reader.EndOfStream)
|
|
TmpString = reader.ReadLine()
|
|
If TmpString.StartsWith("FileCali=") Then
|
|
FileLensCalib = Mid(TmpString, 10)
|
|
ElseIf TmpString.StartsWith("LensCalibType=") Then
|
|
LensCalibType = Convert.ToInt16(Mid(TmpString, 15))
|
|
ElseIf TmpString.StartsWith("FileCaliProsp=") Then
|
|
FileCalibProsp = Mid(TmpString, 15)
|
|
ElseIf TmpString.StartsWith("FileCaliRes=") Then
|
|
FileCalibRes = Mid(TmpString, 13)
|
|
ElseIf TmpString.StartsWith("Extended=") Then
|
|
bExtended = CInt(TmpString.Substring(9)) > 0 'lascio vedere tutti i bottoni
|
|
BtnCfg.Visible = bExtended
|
|
BtnCorrProsp.Visible = False 'bExtended
|
|
ElseIf TmpString.StartsWith("BtnLoad=") Then
|
|
bBtnLoad = CInt(TmpString.Substring(8)) > 0 'lascio vedere tutti i bottoni
|
|
BtnLoad.Visible = bExtended
|
|
ElseIf TmpString.StartsWith("SaveDir=") Then
|
|
SaveDir = Mid(TmpString, 9)
|
|
ElseIf TmpString.StartsWith("TmpDir=") Then
|
|
DirTmp = Mid(TmpString, 8)
|
|
ElseIf TmpString.StartsWith("MaxPxWidth=") Then
|
|
TmpInt = Convert.ToInt16(Mid(TmpString, 12))
|
|
If TmpInt > 0 Then ImageMng.MaxPxWidthOutImage = TmpInt
|
|
ElseIf TmpString.StartsWith("BReduction=") Then
|
|
_visione.ReduceImage = CInt(TmpString.Substring(11)) 'pyr_down nel riconoscimento bordi
|
|
ElseIf TmpString.StartsWith("LogDir=") Then
|
|
SaveLogDir = Mid(TmpString, 8)
|
|
ElseIf TmpString.StartsWith("CameraID=") Then
|
|
CameraID = Mid(TmpString, 10)
|
|
CfgForm.LbCfgCameraID.Text = CameraID
|
|
ElseIf TmpString.StartsWith("Border=") Then
|
|
TmpInt = Convert.ToInt16(Mid(TmpString, 8))
|
|
If TmpInt > 0 Then bEnableBorder = True
|
|
_borderType = TmpInt
|
|
ElseIf TmpString.StartsWith("NLogImages=") Then
|
|
TmpInt = Convert.ToInt16(Mid(TmpString, 12))
|
|
_maxImage = TmpInt
|
|
ElseIf TmpString.StartsWith("RectCheckExp=") Then
|
|
|
|
Dim xl, yt, xr, yb As Integer
|
|
Dim split() As String
|
|
split = Mid(TmpString, 14).Split(",", 8, StringSplitOptions.RemoveEmptyEntries)
|
|
xl = Convert.ToInt32(split(0))
|
|
yt = Convert.ToInt32(split(1))
|
|
xr = Convert.ToInt32(split(2))
|
|
yb = Convert.ToInt32(split(3))
|
|
_visione.AddExpRectangle(xl, yt, xr, yb)
|
|
|
|
ElseIf TmpString.StartsWith("ExpCorrection=") Then
|
|
TmpInt = Convert.ToInt16(Mid(TmpString, 15))
|
|
If TmpInt < 0 Or TmpInt > 4 Then TmpInt = 0
|
|
_visione.ExpCorrType = TmpInt
|
|
|
|
ElseIf TmpString.StartsWith("RectCheckStone=") Then
|
|
|
|
Dim xl, yt, xr, yb As Integer
|
|
Dim split() As String
|
|
split = Mid(TmpString, 16).Split(",", 8, StringSplitOptions.RemoveEmptyEntries)
|
|
xl = Convert.ToInt32(split(0))
|
|
yt = Convert.ToInt32(split(1))
|
|
xr = Convert.ToInt32(split(2))
|
|
yb = Convert.ToInt32(split(3))
|
|
_visione.SetStoneRectangle(xl, yt, xr, yb)
|
|
|
|
|
|
ElseIf TmpString.StartsWith("BlackThFactor=") Then
|
|
TmpDou = 0
|
|
TmpDou = Convert.ToDouble(Mid(TmpString, 15), nfi)
|
|
If TmpDou > 0 Then _visione.ThFactorNero = TmpDou
|
|
|
|
|
|
ElseIf TmpString.StartsWith("VacuumCheckEnable=") Then
|
|
TmpInt = Convert.ToInt16(Mid(TmpString, Len("VacuumCheckEnable=") + 1))
|
|
VacuumCheckEnable = TmpInt > 0
|
|
|
|
ElseIf TmpString.StartsWith("VacFileStart=") Then
|
|
VacFileStart = Mid(TmpString, Len("StartVacFile=") + 1)
|
|
|
|
ElseIf TmpString.StartsWith("VacFilePos=") Then
|
|
VacFilePos = Mid(TmpString, Len("VacFilePos=") + 1)
|
|
|
|
ElseIf TmpString.StartsWith("VacFileEnd=") Then
|
|
VacFileEnd = Mid(TmpString, Len("VacFileEnd=") + 1)
|
|
|
|
ElseIf TmpString.StartsWith("VacDirModels=") Then
|
|
VacDirModels = Mid(TmpString, Len("VacDirModels=") + 1)
|
|
|
|
ElseIf TmpString.StartsWith("VacMinScore=") Then
|
|
VacMinScore = Convert.ToDouble(Mid(TmpString, Len("VacMinScore=") + 1), nfi)
|
|
|
|
ElseIf TmpString.StartsWith("VacTolmm=") Then
|
|
VacTolmm = Convert.ToDouble(Mid(TmpString, Len("VacTolmm=") + 1), nfi)
|
|
|
|
End If
|
|
|
|
|
|
End While
|
|
reader.Close()
|
|
reader.Dispose()
|
|
|
|
Catch ex As Exception
|
|
MsgBox("Error in Cfg File " & TmpString)
|
|
End Try
|
|
|
|
' temoraneo
|
|
#If WinXp Then
|
|
_visione.SearchMode = CvEnum.RETR_TYPE.CV_RETR_EXTERNAL
|
|
#Else
|
|
_visione.SearchMode = CvEnum.RetrType.External
|
|
#End If
|
|
|
|
|
|
CreateDefaultDirs()
|
|
|
|
CfgForm.LbFileCali.Text = FileLensCalib
|
|
CfgForm.LbImageDir.Text = SaveDir
|
|
CfgForm.LbTempDir.Text = DirTmp
|
|
Camera.DownloadDir = DirTmp
|
|
AggiornaNumImage()
|
|
|
|
End Sub
|
|
|
|
Public Function CancelFile(ByVal inPath As String) As Boolean
|
|
Dim ret As Boolean
|
|
|
|
Try
|
|
Dim objFile As FileInfo = New FileInfo(inPath)
|
|
objFile.Delete()
|
|
objFile = Nothing
|
|
ret = True 'return true on success
|
|
Catch e As Exception
|
|
ret = False 'return false on error
|
|
End Try
|
|
|
|
Return ret
|
|
|
|
End Function
|
|
Public Function CreateDefaultDirs() As Boolean
|
|
Dim ret As Boolean
|
|
|
|
Dim objDir As New System.IO.DirectoryInfo(DirTmp)
|
|
Try
|
|
If Not objDir.Exists Then
|
|
objDir.Create()
|
|
End If
|
|
Catch e As Exception
|
|
ret = False 'return false on error
|
|
End Try
|
|
objDir = Nothing
|
|
|
|
objDir = New System.IO.DirectoryInfo(SaveDir)
|
|
|
|
Try
|
|
If Not objDir.Exists Then
|
|
objDir.Create()
|
|
End If
|
|
Catch e As Exception
|
|
ret = False 'return false on error
|
|
End Try
|
|
objDir = Nothing
|
|
|
|
|
|
' creo SaveLogDir
|
|
If SaveLogDir.Length > 0 Then
|
|
objDir = New System.IO.DirectoryInfo(SaveLogDir)
|
|
|
|
Try
|
|
If Not objDir.Exists Then
|
|
objDir.Create()
|
|
End If
|
|
Catch e As Exception
|
|
ret = False 'return false on error
|
|
End Try
|
|
objDir = Nothing
|
|
|
|
End If
|
|
|
|
Return ret
|
|
|
|
End Function
|
|
|
|
Private Sub cmdZoomAll_Click(sender As System.Object, e As System.EventArgs) Handles cmdZoomAll.Click
|
|
ImageControl1.fittoscreen()
|
|
End Sub
|
|
|
|
Private Sub BtnZom11_Click(sender As System.Object, e As System.EventArgs) Handles BtnZoom11.Click
|
|
ImageControl1.ZoomFactor = 1
|
|
End Sub
|
|
|
|
Private Sub cmdOpen_Click(sender As System.Object, e As System.EventArgs) Handles BtnLoad.Click
|
|
' OpenFileDialog1.InitialDirectory = SaveDir
|
|
OpenFileDialog1.InitialDirectory = SaveLogDir
|
|
|
|
OpenFileDialog1.FileName = ""
|
|
OpenFileDialog1.Filter = "JPEG Format (*.JPG)|*.jpg|BMP Format (*.BMP) |*.bmp"
|
|
OpenFileDialog1.CheckFileExists = True
|
|
OpenFileDialog1.ShowDialog()
|
|
ImageMng.Corrected = False
|
|
ImageControl1.Image = Nothing
|
|
GC.Collect()
|
|
If Len(OpenFileDialog1.FileName) > 0 Then
|
|
ImageMng.ProcessStop()
|
|
If Not m_Image Is Nothing Then
|
|
m_Image.Dispose()
|
|
End If
|
|
m_Image = Nothing
|
|
m_Image = New Bitmap(OpenFileDialog1.FileName)
|
|
ImageControl1.Image = m_Image
|
|
ImageControl1.fittoscreen()
|
|
LeggiExif(OpenFileDialog1.FileName)
|
|
status = en_status.ImageFromCamera
|
|
ImageMng.InputImage = m_Image
|
|
TStatus.Text = "Image Loaded"
|
|
End If
|
|
SetFormStatus()
|
|
|
|
If CorrezioneAutomatica Then
|
|
Me.Cursor = Cursors.WaitCursor
|
|
CorrezioneCompleta()
|
|
Me.Cursor = Cursors.Default
|
|
End If
|
|
End Sub
|
|
Private Sub CorrezioneCompleta()
|
|
'ImageMng.CorrezioneCompletaAsync()
|
|
ImageMng.CorrezioneCompleta()
|
|
TStatus.Text = "Image Correction"
|
|
End Sub
|
|
|
|
Public Sub RichiestaClick()
|
|
|
|
'If StatoGenerale <> statoGenEnum.StatoOk Then
|
|
' Return
|
|
'End If
|
|
Console.WriteLine("RICHIESTA CLICK: " & MainModule.IndexProc)
|
|
|
|
If Camera.Connected Then
|
|
ImageMng.ProcessStop()
|
|
Camera.TakeFoto()
|
|
TStatus.Text = "Click sent"
|
|
RichiestaFoto = False
|
|
End If
|
|
'CorrezioneAutomatica = True
|
|
|
|
End Sub
|
|
Public Sub SetSpessLastra(spess As Double)
|
|
|
|
End Sub
|
|
|
|
Private Sub ImageMng_AvanzamentoCorrezioneLente(value As Double) Handles ImageMng.AvanzamentoCorrezioneLente
|
|
|
|
If Me.InvokeRequired Then
|
|
Me.Invoke(Sub() ImageMng_AvanzamentoCorrezioneLente(value))
|
|
Return
|
|
End If
|
|
|
|
If (value >= 0 And value <= 100) Then
|
|
ProgressBar.Value = value
|
|
End If
|
|
TStatus.Text = "Image Undistortion..."
|
|
|
|
End Sub
|
|
|
|
Private Sub ImageMng_AvanzamentoCorrezioneProspettiva(value As Double) Handles ImageMng.AvanzamentoCorrezioneProspettiva
|
|
|
|
If Me.InvokeRequired Then
|
|
Me.Invoke(Sub() ImageMng_AvanzamentoCorrezioneProspettiva(value))
|
|
Return
|
|
End If
|
|
|
|
If (value >= 0 And value <= 100) Then
|
|
ProgressBar.Value = value
|
|
End If
|
|
TStatus.Text = "Image Correction..."
|
|
|
|
End Sub
|
|
|
|
Private Sub ImageMng_FineCorrezioneLente() Handles ImageMng.FineCorrezioneLente
|
|
|
|
If Me.InvokeRequired Then
|
|
Me.Invoke(New MethodInvoker(AddressOf ImageMng_FineCorrezioneLente))
|
|
Exit Sub
|
|
End If
|
|
|
|
ProgressBar.Value = 0
|
|
'ImageControl1.Image = ImageMng.UndistorcedImage
|
|
'ImageControl1.fittoscreen()
|
|
TStatus.Text = "Image Undistorced"
|
|
|
|
End Sub
|
|
|
|
Private Sub ImageMng_FineCorrezioneProspettiva() Handles ImageMng.FineCorrezioneProspettiva
|
|
|
|
If Me.InvokeRequired Then
|
|
Me.Invoke(New MethodInvoker(AddressOf ImageMng_FineCorrezioneProspettiva))
|
|
Exit Sub
|
|
End If
|
|
|
|
If Not RichiestaBordi And Not VaacumCheckReq Then
|
|
ImageMng.SaveClickMsg(0)
|
|
End If
|
|
|
|
ProgressBar.Value = 0
|
|
Try
|
|
ImageControl1.Image = ImageMng.FinalImage
|
|
ImageControl1.fittoscreen()
|
|
TStatus.Text = "Image Correction OK"
|
|
|
|
Catch ex As Exception
|
|
TStatus.Text = "Failed showing Image"
|
|
End Try
|
|
|
|
status = en_status.ImgCorrected
|
|
SetFormStatus()
|
|
|
|
End Sub
|
|
|
|
Private Sub Camera_DownloadedCompleted() Handles Camera.DownloadedCompleted
|
|
|
|
ImageMng.DownloadCompletato()
|
|
ImageMng.InputImage = Camera.CameraImage
|
|
TStatus.Text = "Image Downloaded"
|
|
|
|
|
|
LeggiExif(Camera.PhotoFileName)
|
|
status = en_status.ImageFromCamera
|
|
m_Image = Camera.CameraImage
|
|
ImageControl1.Image = Camera.CameraImage
|
|
ImageControl1.fittoscreen()
|
|
SetFormStatus()
|
|
|
|
If RichiestaBackGround Then
|
|
SalvaNuovoBackGround()
|
|
ImageMng.SaveClickMsg(0)
|
|
Return
|
|
End If
|
|
|
|
' potrei salvare solo se richiesta bordi ..
|
|
SalvaImmagineCiclica()
|
|
|
|
If VaacumCheckReq Then
|
|
|
|
VaacumCheckReq = False
|
|
If Len(VacFilePos) > 0 Then
|
|
ImageMng.CorrezioneCompleta()
|
|
_search.GeneraIstruzioniRicerca(VacFilePos, VacMinScore, VacTolmm)
|
|
_search.Ricerca()
|
|
ImageControl1.Image = _search.FinalImage
|
|
End If
|
|
TimerMain.Enabled = True
|
|
End If
|
|
|
|
|
|
If RichiestaBordi Then
|
|
SetThreshold()
|
|
RilevaBordi(m_Image)
|
|
Return
|
|
End If
|
|
|
|
If CorrezioneAutomatica Then
|
|
Me.Cursor = Cursors.WaitCursor
|
|
CorrezioneCompleta()
|
|
Me.Cursor = Cursors.Default
|
|
End If
|
|
|
|
If RichiestaFoto Then
|
|
RichiestaFoto = False
|
|
RichiestaClick()
|
|
Return
|
|
End If
|
|
|
|
End Sub
|
|
|
|
Private Sub ImageMng_ProcessAborted(err As Integer) Handles ImageMng.ProcessAborted
|
|
If Me.InvokeRequired Then
|
|
Me.Invoke(Sub() ImageMng_ProcessAborted(err))
|
|
Return
|
|
End If
|
|
|
|
ProgressBar.Value = 0
|
|
TStatus.Text = "Process Aborted"
|
|
|
|
End Sub
|
|
|
|
Public Sub RichiestaStatoCamera()
|
|
Dim NomeFile As String
|
|
Dim nf As Integer
|
|
|
|
Try
|
|
If Not Camera.Connected Then
|
|
Camera.Connect(CameraID)
|
|
'Me.Text = "ID Camera = " & Camera.CameraID
|
|
End If
|
|
|
|
NomeFile = SaveDir & "click.txt"
|
|
nf = FreeFile()
|
|
FileOpen(nf, NomeFile, OpenMode.Output)
|
|
|
|
If Camera.Connected Then
|
|
Print(nf, "Err=0")
|
|
Else
|
|
Print(nf, "Err=1")
|
|
End If
|
|
FileClose(nf)
|
|
|
|
Catch ex As Exception
|
|
' ?? che faccio?
|
|
|
|
End Try
|
|
|
|
End Sub
|
|
|
|
Private Sub Camera_StatusChanged() Handles Camera.StatusChanged
|
|
If Camera.Connected Then
|
|
BtnTakeFoto.ImageIndex = 0
|
|
CfgForm.LbCameraID.Text = Camera.CameraID
|
|
CfgForm.LbDeviceStatus.Text = "Connected"
|
|
Else
|
|
BtnTakeFoto.ImageIndex = 1
|
|
CfgForm.LbCameraID.Text = ""
|
|
CfgForm.LbDeviceStatus.Text = "Disconnected"
|
|
End If
|
|
|
|
|
|
End Sub
|
|
|
|
Private Sub BtnBackG_Click(sender As System.Object, e As System.EventArgs) Handles BtnBackG.Click
|
|
ScattoBackGround()
|
|
End Sub
|
|
|
|
Private Sub SalvaNuovoBackGround()
|
|
Dim backSaved As Boolean = False
|
|
|
|
Try
|
|
_visione.BackImage = Nothing
|
|
FileCopy(Camera.PhotoFileName, SaveDir & "BackImage.jpg")
|
|
FileCopy(Camera.PhotoFileName, SaveDir & "BackImage" & Format(Now, "yyMMdd_HHmmss") & ".jpg")
|
|
RichiestaBackGround = False
|
|
'TODO qui sarebbe utile salvare i dati di scatto dell'immagine
|
|
backSaved = True
|
|
|
|
Catch ex As Exception
|
|
|
|
End Try
|
|
|
|
Try
|
|
If backSaved Then
|
|
Dim EW As New ExifWorks(SaveDir & "BackImage.jpg")
|
|
Debug.Print("FocalLength Length " & EW.FocalLength.ToString("0.0mm"))
|
|
Debug.Print("Aperture=" & EW.Aperture.ToString("0.0"))
|
|
Debug.Print("ISO=" & EW.ISO.ToString)
|
|
Debug.Print("TimeExp=" & EW.ExposureTime.ToString("0.0"))
|
|
|
|
'Console.WriteLine(EW.ToString())
|
|
EW.Dispose()
|
|
End If
|
|
Catch ex As Exception
|
|
|
|
End Try
|
|
|
|
End Sub
|
|
|
|
Private Sub RilevaBordi(img As Bitmap)
|
|
|
|
_visione.BackImageFile = SaveDir & "BackImage.jpg"
|
|
_visione.Image1 = img
|
|
'_visione.TrovaBordi(2)
|
|
_visione.BorderType = _borderType
|
|
VisualizzaThreshold()
|
|
_visione.TrovaBordiMCh(_ActTh)
|
|
|
|
ImageControl1.Image = _visione.FinalImage
|
|
|
|
|
|
End Sub
|
|
Private Sub MostraStato()
|
|
If StatoGenerale = statoGenEnum.StatoOk Then Return
|
|
If ModalitaNascosta Then Return
|
|
|
|
Select Case StatoGenerale
|
|
Case statoGenEnum.ErroreCalibrazione
|
|
MsgBox("Calibration Error")
|
|
Case statoGenEnum.ErroreCfg
|
|
MsgBox("Cfg Error")
|
|
Case statoGenEnum.ErroreSconosciuto
|
|
MsgBox("Unknown Error")
|
|
|
|
End Select
|
|
|
|
End Sub
|
|
|
|
Private Sub BtnEdgeFinder_Click(sender As System.Object, e As System.EventArgs) Handles BtnEdgeFinder.Click
|
|
_ActTh = 127
|
|
VisualizzaThreshold()
|
|
RilevaBordi(m_Image)
|
|
End Sub
|
|
|
|
Private Sub BtnChangeThreshold_Click(sender As System.Object, e As System.EventArgs) Handles BtnChangeThreshold.Click
|
|
_ActTh = _ActTh - 10
|
|
_ActTh = Math.Max(_ActTh, 1)
|
|
VisualizzaThreshold()
|
|
_visione.ApplicaTreshold(_ActTh)
|
|
ImageControl1.Image = _visione.FinalImage
|
|
End Sub
|
|
|
|
Private Sub BtnIncrTh_Click(sender As System.Object, e As System.EventArgs) Handles BtnIncrTh.Click
|
|
|
|
Dim tm As New Stopwatch
|
|
|
|
Dim t1, t2 As Long
|
|
tm.Start()
|
|
|
|
_ActTh = _ActTh + 10
|
|
_ActTh = Math.Min(_ActTh, 250)
|
|
VisualizzaThreshold()
|
|
_visione.ApplicaTreshold(_ActTh)
|
|
t1 = tm.ElapsedMilliseconds
|
|
ImageControl1.Image = _visione.FinalImage
|
|
t2 = tm.ElapsedMilliseconds
|
|
|
|
End Sub
|
|
|
|
Private Sub EseguiScatto()
|
|
' Take Picture
|
|
If Not Camera.Connected Then
|
|
Camera.Connect(CameraID)
|
|
'Me.Text = "ID Camera = " & Camera.CameraID
|
|
End If
|
|
|
|
RichiestaFoto = False
|
|
|
|
RichiestaClick()
|
|
|
|
SetFormStatus()
|
|
|
|
End Sub
|
|
|
|
Public Sub ScattoBackGround()
|
|
RichiestaBackGround = True
|
|
EseguiScatto()
|
|
End Sub
|
|
Private Sub SetThreshold()
|
|
_ActTh = SogliaPercentuale * 2.55
|
|
_ActTh = Math.Min(_ActTh, 255)
|
|
VisualizzaThreshold()
|
|
End Sub
|
|
Public Sub RipetiThreshold()
|
|
SetThreshold()
|
|
VisualizzaThreshold()
|
|
_visione.ApplicaTreshold(_ActTh)
|
|
ImageControl1.Image = _visione.FinalImage
|
|
End Sub
|
|
|
|
Private Sub SalvaImmagineCiclica()
|
|
|
|
If _maxImage <= 0 Then Return
|
|
If SaveLogDir.Length = 0 Then Return
|
|
|
|
Try
|
|
AggiornaNumImage()
|
|
FileCopy(Camera.PhotoFileName, SaveLogDir & "Image" & _numImage.ToString("000") & ".jpg")
|
|
'FileCopy(Camera.PhotoFileName, SaveDir & "BackImage" & Format(Now, "yyMMdd_HHmmss") & ".jpg")
|
|
' RichiestaBackGround = False
|
|
|
|
Catch ex As Exception
|
|
|
|
End Try
|
|
|
|
|
|
End Sub
|
|
Private Sub AggiornaNumImage()
|
|
|
|
|
|
If _maxImage <= 0 Then Return
|
|
If SaveLogDir.Length = 0 Then Return
|
|
|
|
|
|
If _numImage >= 0 Then
|
|
_numImage = _numImage + 1
|
|
If _numImage > _maxImage Then
|
|
_numImage = 1
|
|
End If
|
|
Return
|
|
End If
|
|
|
|
Dim NomiFiles() As String
|
|
' devo capire dove ero arrivato
|
|
NomiFiles = Directory.GetFiles(SaveLogDir, "Image???.jpg")
|
|
Dim i As Integer
|
|
Dim maxDateIndex As Integer = -1
|
|
Dim ActualDate, MaxDate As Date
|
|
Dim ActualNumber, MaxNumber As Integer
|
|
|
|
If NomiFiles.Length = 0 Then
|
|
_numImage = 0
|
|
Return
|
|
End If
|
|
|
|
MaxDate = Directory.GetLastWriteTime(NomiFiles(0))
|
|
MaxNumber = CInt(NomiFiles(0).Substring(NomiFiles(0).Length - 7, 3))
|
|
For i = 1 To NomiFiles.Length - 1
|
|
ActualDate = Directory.GetLastWriteTime(NomiFiles(i))
|
|
ActualNumber = CInt(NomiFiles(i).Substring(NomiFiles(i).Length - 7, 3))
|
|
If ActualNumber > MaxNumber Then
|
|
MaxNumber = ActualNumber
|
|
End If
|
|
If ActualDate > MaxDate Then
|
|
MaxDate = ActualDate
|
|
maxDateIndex = i
|
|
End If
|
|
Next
|
|
|
|
' se ho ancora numeri disponibili
|
|
If MaxNumber < _maxImage Then
|
|
_numImage = MaxNumber + 1
|
|
' altrimenti sovrascrivo quello con la data più grande
|
|
ElseIf maxDateIndex > -1 Then
|
|
_numImage = CInt(NomiFiles(maxDateIndex).Substring(NomiFiles(maxDateIndex).Length - 7, 3)) + 1
|
|
End If
|
|
|
|
End Sub
|
|
Public Sub SetSearchMode(smode As Integer)
|
|
If smode >= 0 AndAlso smode <= 3 Then
|
|
_visione.SearchMode = smode
|
|
Else
|
|
#If WinXp Then
|
|
_visione.SearchMode = CvEnum.RETR_TYPE.CV_RETR_EXTERNAL
|
|
#Else
|
|
_visione.SearchMode = CvEnum.RetrType.External
|
|
#End If
|
|
End If
|
|
End Sub
|
|
|
|
<DllImport("kernel32")>
|
|
Private Shared Function GetPrivateProfileString(ByVal section As String, ByVal key As String, ByVal def As String, ByVal retVal As StringBuilder, ByVal size As Integer, ByVal filePath As String) As Integer
|
|
End Function
|
|
|
|
Public Function GetIniValue(section As String, key As String, filename As String, Optional defaultValue As String = "") As String
|
|
Dim sb As New StringBuilder(500)
|
|
If GetPrivateProfileString(section, key, defaultValue, sb, sb.Capacity, filename) > 0 Then
|
|
Return sb.ToString
|
|
Else
|
|
Return defaultValue
|
|
End If
|
|
End Function
|
|
|
|
|
|
Public Sub SetDefaultCamera(Optional resetID As Boolean = False)
|
|
Dim NomeFileCfg, TmpString As String
|
|
Dim NomeFileTempCfg, DirToReadCfg As String
|
|
Dim SaveFileCfg As String
|
|
Dim NomeFileIni As String
|
|
Dim nf As Integer
|
|
Dim writer As StreamWriter
|
|
|
|
|
|
|
|
|
|
'#If DEBUG Then
|
|
' NomeFileIni = "c:\CameraMng\DataRoot.ini"
|
|
' DefaultNomeFileCfg = "c:\CameraMng\CameraMng.Cfg"
|
|
' 'DirExe = "c:\CameraMng"
|
|
'#Else
|
|
NomeFileIni = Application.StartupPath & "\DataRoot.ini"
|
|
DirToReadCfg = Application.StartupPath
|
|
'DirExe = Application.StartupPath
|
|
'#End If
|
|
|
|
Try
|
|
DirToReadCfg = GetIniValue("Data", "DataRoot", NomeFileIni, DirToReadCfg)
|
|
' aggiungiamo indici processo corrente
|
|
DirToReadCfg = DirToReadCfg & MainModule.IndexProc.ToString()
|
|
NomeFileCfg = DirToReadCfg & "\CameraMng.cfg"
|
|
NomeFileTempCfg = DirToReadCfg & "\CameraMngTmp.cfg"
|
|
SaveFileCfg = DirToReadCfg & "\CameraMng" & Format(Now, "yyyyMMddhhmmss") & ".cfg"
|
|
If (File.Exists(NomeFileTempCfg)) Then
|
|
File.Delete(NomeFileTempCfg)
|
|
End If
|
|
|
|
|
|
nf = FreeFile()
|
|
FileOpen(nf, NomeFileCfg, OpenMode.Input)
|
|
writer = New StreamWriter(NomeFileTempCfg)
|
|
|
|
TmpString = ""
|
|
While Not EOF(nf)
|
|
TmpString = LineInput(nf)
|
|
If Not TmpString.StartsWith("CameraID=") Then
|
|
writer.WriteLine(TmpString, CultureInfo.InvariantCulture)
|
|
End If
|
|
End While
|
|
If Not resetID Then
|
|
writer.WriteLine("CameraID=" & Camera.CameraID, CultureInfo.InvariantCulture)
|
|
End If
|
|
FileClose(nf)
|
|
writer.Close()
|
|
|
|
|
|
File.Copy(NomeFileCfg, SaveFileCfg)
|
|
If (File.Exists(NomeFileCfg)) Then
|
|
File.Delete(NomeFileCfg)
|
|
End If
|
|
|
|
File.Copy(NomeFileTempCfg, NomeFileCfg)
|
|
File.Delete(NomeFileTempCfg)
|
|
|
|
' lo faccio qui se tutto è andato bene
|
|
If resetID Then
|
|
CameraID = ""
|
|
CfgForm.LbCfgCameraID.Text = CameraID
|
|
MsgBox("ID Reset OK")
|
|
Else
|
|
MsgBox("New ID written on cfg")
|
|
CfgForm.LbCfgCameraID.Text = Camera.CameraID
|
|
End If
|
|
|
|
Catch ex As Exception
|
|
MsgBox("Error in Writing Cfg File " & ex.Message)
|
|
End Try
|
|
|
|
End Sub
|
|
Private Sub AggiornaPulsantiVIsibili()
|
|
BtnCfg.Visible = bExtended
|
|
BtnCorrProsp.Visible = False 'bExtended
|
|
BtnBackG.Visible = bEnableBorder
|
|
BtnEdgeFinder.Visible = bEnableBorder
|
|
BtnChangeThreshold.Visible = bEnableBorder
|
|
BtnIncrTh.Visible = bEnableBorder
|
|
End Sub
|
|
|
|
Private Sub ImageControl1_PointSelected(n As Integer) Handles ImageControl1.PointSelected
|
|
|
|
lbXmm.Text = ImageMng.m_pworld(n).X.ToString("0.00")
|
|
lbYmm.Text = ImageMng.m_pworld(n).Y.ToString("0.00")
|
|
_npProspSel = n
|
|
'lbXmm.Text = (n + 1).ToString
|
|
End Sub
|
|
|
|
Private Sub ImageControl1_PointUnselected() Handles ImageControl1.PointUnselected
|
|
lbXmm.Text = ""
|
|
lbYmm.Text = ""
|
|
_npProspSel = -1
|
|
End Sub
|
|
|
|
Private Sub lbXmm_Click(sender As System.Object, e As System.EventArgs) Handles lbXmm.Click
|
|
If _npProspSel < 0 Then Return
|
|
NumPad.Text = CDbl(lbXmm.Text).ToString("0.00")
|
|
NumPad.ShowDialog()
|
|
ImageMng.m_pworld(_npProspSel).X = CDbl(NumPad.Text)
|
|
lbXmm.Text = ImageMng.m_pworld(_npProspSel).X.ToString("0.00")
|
|
End Sub
|
|
|
|
Private Sub lbYmm_Click(sender As System.Object, e As System.EventArgs) Handles lbYmm.Click
|
|
If _npProspSel < 0 Then Return
|
|
NumPad.Text = lbYmm.Text
|
|
NumPad.ShowDialog()
|
|
ImageMng.m_pworld(_npProspSel).Y = CDbl(NumPad.Text)
|
|
lbYmm.Text = ImageMng.m_pworld(_npProspSel).Y.ToString("0.00")
|
|
End Sub
|
|
|
|
Private Sub ImageControl1_Load(sender As System.Object, e As System.EventArgs) Handles ImageControl1.Load
|
|
|
|
End Sub
|
|
|
|
Private Sub btnSearch_Click(sender As System.Object, e As System.EventArgs) Handles btnSearch.Click
|
|
|
|
Try
|
|
If ImageMng.InputImage Is Nothing Then Return
|
|
|
|
If Len(VacFilePos) > 0 Then
|
|
ImageMng.CorrezioneCompleta()
|
|
_search.GeneraIstruzioniRicerca(VacFilePos, VacMinScore, VacTolmm)
|
|
_search.Ricerca()
|
|
ImageControl1.Image = _search.FinalImage
|
|
ImageControl1.fittoscreen()
|
|
End If
|
|
|
|
Catch ex As Exception
|
|
|
|
End Try
|
|
|
|
End Sub
|
|
|
|
Private Sub _search_LogMessage(msg As String) Handles _search.LogMessage
|
|
MsgBox(msg)
|
|
End Sub
|
|
|
|
Private Sub TimerMain_Tick(sender As System.Object, e As System.EventArgs) Handles TimerMain.Tick
|
|
|
|
If Not VacuumCheckEnable Then
|
|
TimerMain.Enabled = False
|
|
Return
|
|
End If
|
|
|
|
TimerMain.Enabled = False
|
|
|
|
' Check esistenza file
|
|
If (File.Exists(VacFileStart)) Then
|
|
Dim ok As Boolean = False
|
|
For i As Integer = 1 To 20
|
|
Try
|
|
File.Delete(VacFileStart)
|
|
ok = True
|
|
Catch ex As Exception
|
|
Threading.Thread.Sleep(100)
|
|
End Try
|
|
Next
|
|
If Not ok Then
|
|
MsgBox("Error on deleting File" & VacFileStart)
|
|
Return
|
|
End If
|
|
|
|
VaacumCheckReq = True
|
|
RichiestaClick()
|
|
Else
|
|
TimerMain.Enabled = True
|
|
End If
|
|
|
|
|
|
End Sub
|
|
|
|
Private Sub BtnDefAree_Click(sender As System.Object, e As System.EventArgs) Handles BtnDefAree.Click
|
|
Try
|
|
|
|
status = en_status.DefAree
|
|
Me.Cursor = Cursors.WaitCursor
|
|
SetFormStatus()
|
|
Refresh()
|
|
|
|
ImageMng.ProcessStop()
|
|
ImageMng.CorrezioneCompleta(False)
|
|
|
|
ProgressBar.Value = 0
|
|
ImageControl1.Image = ImageMng.FinalImage
|
|
ImageControl1.fittoscreen()
|
|
GC.Collect()
|
|
ImageControl1.Refresh()
|
|
Catch ex As Exception
|
|
TStatus.Text = "Process Aborted"
|
|
Finally
|
|
Me.Cursor = Cursors.Default
|
|
End Try
|
|
|
|
End Sub
|
|
|
|
|
|
|
|
Private Sub BtnAbortDefAree_Click(sender As System.Object, e As System.EventArgs) Handles BtnAbortDefAree.Click
|
|
|
|
Select Case status
|
|
|
|
Case en_status.DefAree
|
|
status = en_status.ImgCorrected
|
|
Case en_status.DefTexp, en_status.DefStone, en_status.DefVentosa
|
|
status = en_status.DefAree
|
|
End Select
|
|
|
|
ImageControl1.DBoard.VisAreaGen = False
|
|
ImageControl1.Refresh()
|
|
SetFormStatus()
|
|
End Sub
|
|
|
|
Private Sub BtnSaveAree_Click(sender As System.Object, e As System.EventArgs) Handles BtnSaveAree.Click
|
|
|
|
' TODO fare i salvataggi opportuni
|
|
Dim x1, y1, x2, y2 As Double
|
|
ImageControl1.DBoard.GetArea(x1, y1, x2, y2)
|
|
|
|
Select Case status
|
|
|
|
Case en_status.DefTexp
|
|
_visione.SetExpRectangle(x1, y1, x2, y2)
|
|
Case en_status.DefStone
|
|
_visione.SetStoneRectangle(x1, y1, x2, y2)
|
|
|
|
Case en_status.DefVentosa
|
|
|
|
Dim NomeFile As String
|
|
|
|
NumPad.Text = "1"
|
|
NumPad.ShowDialog()
|
|
|
|
If Len(NumPad.Text) > 0 Then
|
|
' nel file jpeg non so se questo settaggio viene salvato
|
|
NomeFile = VacDirModels & NumPad.Text & ".png"
|
|
ImageMng.SaveModelFromRectangle(NomeFile, x1, y1, x2, y2)
|
|
End If
|
|
|
|
End Select
|
|
|
|
status = en_status.DefAree
|
|
ImageControl1.DBoard.VisAreaGen = False
|
|
ImageControl1.Refresh()
|
|
SetFormStatus()
|
|
SaveDefAree()
|
|
|
|
End Sub
|
|
|
|
Private Sub BtnExpT_Click(sender As System.Object, e As System.EventArgs) Handles BtnExpT.Click
|
|
' Prendo i valori attuali del rettangolo 0
|
|
Dim x1, y1, x2, y2 As Double
|
|
|
|
_visione.GetExpRectangle(x1, y1, x2, y2)
|
|
ImageControl1.DBoard.SetArea(x1, y1, x2, y2)
|
|
status = en_status.DefTexp
|
|
SetFormStatus()
|
|
ImageControl1.DBoard.VisAreaGen = True
|
|
ImageControl1.Refresh()
|
|
|
|
End Sub
|
|
|
|
Private Sub BtnStone_Click(sender As Object, e As System.EventArgs) Handles BtnStone.Click
|
|
|
|
' Prendo i valori attuali del rettangolo 0
|
|
Dim x1, y1, x2, y2 As Double
|
|
|
|
_visione.GetStoneRectangle(x1, y1, x2, y2)
|
|
ImageControl1.DBoard.SetArea(x1, y1, x2, y2)
|
|
status = en_status.DefStone
|
|
SetFormStatus()
|
|
ImageControl1.DBoard.VisAreaGen = True
|
|
ImageControl1.Refresh()
|
|
|
|
End Sub
|
|
|
|
' salva l'area in cui si verifica l'esposizione
|
|
Private Sub SaveDefAree()
|
|
|
|
Dim NomeFileCfg, TmpString As String
|
|
Dim NomeFileTempCfg, DirToReadCfg As String
|
|
Dim SaveFileCfg As String
|
|
Dim NomeFileIni As String
|
|
Dim nf As Integer
|
|
Dim writer As StreamWriter
|
|
|
|
'#If DEBUG Then
|
|
' NomeFileIni = "c:\CameraMng\DataRoot.ini"
|
|
' DefaultNomeFileCfg = "c:\CameraMng\CameraMng.Cfg"
|
|
' DirExe = "c:\CameraMng"
|
|
'#Else
|
|
NomeFileIni = Application.StartupPath & "\DataRoot.ini"
|
|
DirToReadCfg = Application.StartupPath
|
|
'DirExe = Application.StartupPath
|
|
'#End If
|
|
|
|
|
|
Dim ExpEnableSet As Boolean = False
|
|
Dim AreaExpSet As Boolean = False
|
|
Dim AreaStoneSet As Boolean = False
|
|
Dim x1, y1, x2, y2 As Integer
|
|
|
|
|
|
|
|
Try
|
|
DirToReadCfg = GetIniValue("Data", "DataRoot", NomeFileIni, DirToReadCfg)
|
|
NomeFileCfg = DirToReadCfg & "\CameraMng.cfg"
|
|
NomeFileTempCfg = DirToReadCfg & "\CameraMngTmp.cfg"
|
|
SaveFileCfg = DirToReadCfg & "\CameraMng" & Format(Now, "yyyyMMddhhmmss") & ".cfg"
|
|
If (File.Exists(NomeFileTempCfg)) Then
|
|
File.Delete(NomeFileTempCfg)
|
|
End If
|
|
|
|
|
|
nf = FreeFile()
|
|
FileOpen(nf, NomeFileCfg, OpenMode.Input)
|
|
writer = New StreamWriter(NomeFileTempCfg)
|
|
|
|
TmpString = ""
|
|
While Not EOF(nf)
|
|
TmpString = LineInput(nf)
|
|
|
|
If TmpString.StartsWith("RectCheckExp=") AndAlso _visione.ExpCorrType <> clsVisione.eExpCorrMode.none Then
|
|
_visione.GetExpRectangle(x1, y1, x2, y2)
|
|
writer.WriteLine("RectCheckExp={0},{1},{2},{3}", x1.ToString, y1.ToString, x2.ToString, y2.ToString,
|
|
CultureInfo.InvariantCulture)
|
|
AreaExpSet = True
|
|
ElseIf TmpString.StartsWith("RectCheckStone=") Then
|
|
_visione.GetStoneRectangle(x1, y1, x2, y2)
|
|
writer.WriteLine("RectCheckStone={0},{1},{2},{3}", x1.ToString, y1.ToString, x2.ToString, y2.ToString,
|
|
CultureInfo.InvariantCulture)
|
|
AreaStoneSet = True
|
|
Else
|
|
writer.WriteLine(TmpString, CultureInfo.InvariantCulture)
|
|
End If
|
|
|
|
|
|
End While
|
|
|
|
'If Not ExpEnableSet Then
|
|
' writer.WriteLine("ExpCorrection=1")
|
|
'End If
|
|
|
|
If Not AreaExpSet AndAlso _visione.ExpCorrType <> clsVisione.eExpCorrMode.none Then
|
|
_visione.GetExpRectangle(x1, y1, x2, y2)
|
|
writer.WriteLine("RectCheckExp={0},{1},{2},{3}", x1.ToString, y1.ToString, x2.ToString, y2.ToString,
|
|
CultureInfo.InvariantCulture)
|
|
End If
|
|
|
|
If Not AreaStoneSet Then
|
|
_visione.GetStoneRectangle(x1, y1, x2, y2)
|
|
writer.WriteLine("RectCheckStone={0},{1},{2},{3}", x1.ToString, y1.ToString, x2.ToString, y2.ToString,
|
|
CultureInfo.InvariantCulture)
|
|
End If
|
|
|
|
|
|
FileClose(nf)
|
|
writer.Close()
|
|
|
|
|
|
File.Copy(NomeFileCfg, SaveFileCfg)
|
|
If (File.Exists(NomeFileCfg)) Then
|
|
File.Delete(NomeFileCfg)
|
|
End If
|
|
|
|
File.Copy(NomeFileTempCfg, NomeFileCfg)
|
|
File.Delete(NomeFileTempCfg)
|
|
|
|
|
|
Catch ex As Exception
|
|
MsgBox("Error in Writing Cfg File " & ex.Message)
|
|
End Try
|
|
|
|
End Sub
|
|
|
|
Private Sub BtnVentosa_Click(sender As System.Object, e As System.EventArgs) Handles BtnVentosa.Click
|
|
|
|
ImageControl1.DBoard.SetArea(1000, 1000, 1800, 1600)
|
|
status = en_status.DefVentosa
|
|
SetFormStatus()
|
|
ImageControl1.DBoard.VisAreaGen = True
|
|
ImageControl1.Refresh()
|
|
|
|
End Sub
|
|
Private Sub VisualizzaThreshold()
|
|
Dim thPerc As Double = (CDbl(_ActTh) / 255) * 100
|
|
lbThreshold.Text = _ActTh.ToString & " (" & thPerc.ToString("0.0") & "%)"
|
|
End Sub
|
|
|
|
|
|
Private Sub TestRaddrizzamento()
|
|
Dim _bmp As Bitmap = New Bitmap("c:\Temp\Test.jpg")
|
|
|
|
|
|
|
|
Dim cameraMatrix As New Matrix(Of Double)(3, 3)
|
|
'[fx 0 cx; 0 fy cy; 0 0 1]
|
|
cameraMatrix.Data(0, 0) = _bmp.Width / 2
|
|
cameraMatrix.Data(0, 1) = 0
|
|
cameraMatrix.Data(0, 2) = _bmp.Width / 2
|
|
cameraMatrix.Data(1, 0) = 0
|
|
cameraMatrix.Data(1, 1) = _bmp.Height / 2
|
|
cameraMatrix.Data(1, 2) = _bmp.Height / 2
|
|
cameraMatrix.Data(2, 0) = 0
|
|
cameraMatrix.Data(2, 1) = 0
|
|
cameraMatrix.Data(2, 2) = 1
|
|
|
|
Dim distCoeffs As New Matrix(Of Double)(1, 4)
|
|
'[k1, k2, p1, p2]
|
|
distCoeffs.Data(0, 0) = 0.17352
|
|
distCoeffs.Data(0, 1) = -0.484226
|
|
distCoeffs.Data(0, 2) = 0.00075256
|
|
distCoeffs.Data(0, 3) = -0.000269617
|
|
|
|
' rms = 2.729067
|
|
' fx = 4609.251961
|
|
' fy = 4609.251961
|
|
' cx = 3076.747294
|
|
' cy = 2073.815575
|
|
' k1 = -0.160129
|
|
' k2 = 0.167262
|
|
' p1 = -0.00901
|
|
' p2 = -0.000612
|
|
|
|
' hfov = 67.4Deg
|
|
'vfov = 48.4Deg
|
|
|
|
|
|
'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]
|
|
cameraMatrix.Data(0, 0) = 4775.944905
|
|
cameraMatrix.Data(0, 1) = 0
|
|
cameraMatrix.Data(0, 2) = 3103.561924
|
|
cameraMatrix.Data(1, 0) = 0
|
|
cameraMatrix.Data(1, 1) = 4775.944905
|
|
cameraMatrix.Data(1, 2) = 2033.648165
|
|
cameraMatrix.Data(2, 0) = 0
|
|
cameraMatrix.Data(2, 1) = 0
|
|
cameraMatrix.Data(2, 2) = 1
|
|
|
|
'[k1, k2, p1, p2]
|
|
distCoeffs.Data(0, 0) = -0.153547
|
|
distCoeffs.Data(0, 1) = 0.127935
|
|
distCoeffs.Data(0, 2) = -0.00626
|
|
distCoeffs.Data(0, 3) = -0.000005
|
|
|
|
Dim outFrame As New Image(Of Emgu.CV.Structure.Rgb, Byte)(_bmp.Width, _bmp.Height)
|
|
Dim newIntrinsecMatrix As IInputArray
|
|
CvInvoke.Undistort(New Image(Of Emgu.CV.Structure.Rgb, Byte)(_bmp), outFrame, cameraMatrix, distCoeffs, newIntrinsecMatrix)
|
|
|
|
_bmp = outFrame.Bitmap
|
|
|
|
_bmp.Save("c:\temp\Testu.png", System.Drawing.Imaging.ImageFormat.Png)
|
|
|
|
|
|
End Sub
|
|
|
|
End Class
|