Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# EMGU CV、Visual Basic CameraCalibration.CalibleCamera导致非常高的错误_C#_Wpf_Vb.net_Emgucv_Camera Calibration - Fatal编程技术网

C# EMGU CV、Visual Basic CameraCalibration.CalibleCamera导致非常高的错误

C# EMGU CV、Visual Basic CameraCalibration.CalibleCamera导致非常高的错误,c#,wpf,vb.net,emgucv,camera-calibration,C#,Wpf,Vb.net,Emgucv,Camera Calibration,我已经阅读了许多不同的资源,试图找到有关VB摄像机校准的信息 到目前为止,我最幸运的是阅读了C站点上的示例# 我已将尽可能多的代码从C#转换为VB,并尝试为其他所有内容找到尽可能多的工作代码。到目前为止,我的MainWindow.vb代码是: Imports System.Drawing Imports System.Threading Imports Emgu.CV Imports Emgu.CV.Util Imports Emgu.CV.Structure Class MainWi

我已经阅读了许多不同的资源,试图找到有关VB摄像机校准的信息

到目前为止,我最幸运的是阅读了C站点上的示例#

我已将尽可能多的代码从C#转换为VB,并尝试为其他所有内容找到尽可能多的工作代码。到目前为止,我的MainWindow.vb代码是:

Imports System.Drawing
Imports System.Threading

Imports Emgu.CV
Imports Emgu.CV.Util
Imports Emgu.CV.Structure



Class MainWindow
'Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) _
'       Handles Me.Loaded
'    Dim capturez As Capture = New Capture

'End Sub
#Region "Class Variables"
Declare Sub Sleep Lib "kernel32.dll" (ByRef Milliseconds As Integer)
Dim capturez As Capture = New Capture
Dim Start_Flag As Boolean = False

Dim BoxUnitHeight As Integer = 9 'EDIT THESE VALUES BASED ON THE BOARD PATTERN
Dim BoxUnitWidth As Integer = 6

Dim Frame_array_buffer As Image(Of Gray, [Byte])() = New Image(Of Gray, Byte)(99) {}
Dim BufferSavePoint As Integer = 0
Dim Corner_Object_List As MCvPoint3D32f()() = New     MCvPoint3D32f(Frame_array_buffer.Length - 1)() {}
Dim Corner_Points_List As PointF()() = New PointF(Frame_array_buffer.Length - 1)() {}
Dim IC As New IntrinsicCameraParameters()
Dim EX_Param As ExtrinsicCameraParameters() = New ExtrinsicCameraParameters() {}

Dim patternSize As Size = New Size(BoxUnitHeight, BoxUnitWidth)

Dim Gray_Frame As Image(Of Gray, Byte) = capturez.QueryGrayFrame
Dim BGR_Frame As Image(Of Bgr, Byte) = capturez.RetrieveBgrFrame
Dim calImage As Image(Of Gray, Byte) = New Image(Of Gray, Byte)    ("C:\Users\\\\\\Image_Correction_Test_V2\OpenCV_Chessboard.png")

Dim corners As PointF() = New PointF() {}
Dim newCornerz As PointF() = New PointF() {}

Dim difError As Double
Dim termCriteria As New MCvTermCriteria


Public Enum Mode
    SavingFrames
    Caluculating_Intrinsics
    Calibrated
End Enum
#End Region
Private currentMode As Mode = Mode.SavingFrames

Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) _
    Handles Me.Loaded
    termCriteria.max_iter = 1
    termCriteria.epsilon = 0.0
    termCriteria.type = CvEnum.TERMCRIT.CV_TERMCRIT_ITER

End Sub
' Sink the "Exit MenuItem" click event
Private Sub mnuExit_Click(ByVal sender As Object, ByVal e As     System.Windows.RoutedEventArgs) _
        Handles mnuExit.Click
    Application.Current.Shutdown()
End Sub

Private Sub Button_Click(ByVal sender As Object, ByVal e As     System.Windows.RoutedEventArgs) _
    Handles Button.Click
    Start_Flag = True
End Sub

' Sink the "Exit MenuItem" click event
Private Sub mnuFix_Click(ByVal sender As Object, ByVal e As     System.Windows.RoutedEventArgs) _
        Handles mnuFix.Click
    Gray_Frame = capturez.RetrieveGrayFrame
    newCornerz = CameraCalibration.FindChessboardCorners(calImage, patternSize,      Emgu.CV.CvEnum.CALIB_CB_TYPE.ADAPTIVE_THRESH Or Emgu.CV.CvEnum.CALIB_CB_TYPE.FILTER_QUADS)

    corners = CameraCalibration.FindChessboardCorners(Gray_Frame, patternSize,     Emgu.CV.CvEnum.CALIB_CB_TYPE.ADAPTIVE_THRESH Or Emgu.CV.CvEnum.CALIB_CB_TYPE.FILTER_QUADS)

    If corners IsNot Nothing Then
        Dim perM As HomographyMatrix
        perM = CameraCalibration.FindHomography(corners, newCornerz,     CvEnum.HOMOGRAPHY_METHOD.DEFAULT, 1)
        Dim Test As Image(Of Gray, Byte) = Gray_Frame.WarpPerspective(perM,     CvEnum.INTER.CV_INTER_NN, CvEnum.WARP.CV_WARP_DEFAULT, New Gray)
        Cal1.Source = ToBitmapSource(Test)
    End If

End Sub


Public Sub StartTimer(ByVal o As Object, ByVal sender As RoutedEventArgs)
    Dim myDispatcherTimer As System.Windows.Threading.DispatcherTimer = New     System.Windows.Threading.DispatcherTimer
    myDispatcherTimer.Interval = New TimeSpan(0, 0, 0, 0, 30)
    ' 100 Milliseconds 
    AddHandler myDispatcherTimer.Tick, AddressOf Me.Each_Tick
    myDispatcherTimer.Start()
End Sub

' Raised every 100 miliseconds while the DispatcherTimer is active.
Public Sub Each_Tick(ByVal o As Object, ByVal sender As EventArgs)

    Dim imagez As Image(Of Bgr, Byte) = capturez.QueryFrame() 'Instead of QueryFrame, you may need to do RetrieveBgrFrame depending on the version of EmguCV you download.
    Stream.Source = ToBitmapSource(imagez)

    BGR_Frame = capturez.RetrieveBgrFrame
    Gray_Frame = BGR_Frame.Convert(Of Gray, Byte)()

    If currentMode = Mode.SavingFrames Then

        corners = CameraCalibration.FindChessboardCorners(Gray_Frame, patternSize, Emgu.CV.CvEnum.CALIB_CB_TYPE.ADAPTIVE_THRESH Or Emgu.CV.CvEnum.CALIB_CB_TYPE.FILTER_QUADS)

        If corners IsNot Nothing Then
            'Debug.Print("Filling Array Buffer")

            'The Find chessboardCorners will try to find them, but if it doesn't it still runs. If it fails DrawChessboard will fail and crash the program.

            If Start_Flag Then
                Gray_Frame.FindCornerSubPix(New PointF(0)() {corners}, New Size(11, 11), New Size(-1, -1), New MCvTermCriteria(30, 0.1))
                Frame_array_buffer(BufferSavePoint) = Gray_Frame.Copy
                BufferSavePoint = BufferSavePoint + 1
                If BufferSavePoint = Frame_array_buffer.Length Then currentMode = Mode.Caluculating_Intrinsics 'Buffer has been filled
            End If


            'Draw the reults

            CameraCalibration.DrawChessboardCorners(Gray_Frame, patternSize, corners)
            Cal2.Source = ToBitmapSource(Gray_Frame)
            Thread.Sleep(100)

        End If
        corners = Nothing
    End If

    If currentMode = Mode.Caluculating_Intrinsics Then
        'Debug.Print("Filling Object and Point Arrays")
        For k As Integer = 0 To Frame_array_buffer.Length - 1

            Corner_Points_List(k) = CameraCalibration.FindChessboardCorners(Frame_array_buffer(k), patternSize, Emgu.CV.CvEnum.CALIB_CB_TYPE.ADAPTIVE_THRESH)
            'for accuracy
            Gray_Frame.FindCornerSubPix(Corner_Points_List, New Size(11, 11), New Size(-1, -1), New MCvTermCriteria(30, 0.1))

            'Fill our objects list with the real world mesurments for the intrinsic calculations
            Dim object_list As New List(Of MCvPoint3D32f)()
            For i As Integer = 0 To BoxUnitHeight - 1
                For j As Integer = 0 To BoxUnitWidth - 1
                    object_list.Add(New MCvPoint3D32f(j * 20.0F, i * 20.0F, 0.0F))
                Next
            Next
            Corner_Object_List(k) = object_list.ToArray()
        Next
        Debug.Print("Reached Calibration")

        'our error should be as close to 0 as possible

        difError = CameraCalibration.CalibrateCamera(Corner_Object_List, Corner_Points_List, Gray_Frame.Size, IC, Emgu.CV.CvEnum.CALIB_TYPE.CV_CALIB_RATIONAL_MODEL, termCriteria, EX_Param)
        'If Emgu.CV.CvEnum.CALIB_TYPE == CV_CALIB_USE_INTRINSIC_GUESS and/or CV_CALIB_FIX_ASPECT_RATIO are specified, some or all of fx, fy, cx, cy must be initialized before calling the function
        'if you use FIX_ASPECT_RATIO and FIX_FOCAL_LEGNTH options, these values needs to be set in the intrinsic parameters before the CalibrateCamera function is called. Otherwise 0 values are used as default.
        'display the results to the user
        MsgBox("Your calibration error is:" & difError)
        currentMode = Mode.Calibrated
    End If

    If currentMode = Mode.Calibrated Then
        'Debug.Print("Attempting Picture fix")


        'calculate the camera intrinsics
        Dim Map1 As Matrix(Of Single), Map2 As Matrix(Of Single)
        IC.InitUndistortMap(BGR_Frame.Width, BGR_Frame.Height, Map1, Map2)

        'remap the image to the particular intrinsics
        'In the current version of EMGU any pixel that is not corrected is set to transparent allowing the original image to be displayed if the same
        'image is mapped backed, in the future this should be controllable through the flag '0'
        Dim temp As Image(Of Bgr, [Byte]) = BGR_Frame.CopyBlank()
        CvInvoke.cvRemap(BGR_Frame, temp, Map1, Map2, 0, New MCvScalar(0))
        BGR_Frame = temp.Copy


        Imgz.Source = ToBitmapSource(BGR_Frame)
        Start_Flag = False
    End If

    Debug.Print(currentMode)
End Sub

''' <summary>
''' Delete a GDI object
''' </summary>
''' <param name="o">The poniter to the GDI object to be deleted</param>
''' <returns></returns>
<DllImport("gdi32")> _
Private Shared Function DeleteObject(o As IntPtr) As Integer
End Function

''' <summary>
''' Convert an IImage to a WPF BitmapSource. The result can be used in the Set Property of Image.Source
''' </summary>
''' <param name="image">The Emgu CV Image</param>
''' <returns>The equivalent BitmapSource</returns>
Public Shared Function ToBitmapSource(image As IImage) As BitmapSource
    Using source As System.Drawing.Bitmap = image.Bitmap
        Dim ptr As IntPtr = source.GetHbitmap()
        'obtain the Hbitmap
        Dim bs As BitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(ptr, IntPtr.Zero, Int32Rect.Empty, System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions())

        DeleteObject(ptr)
        'release the HBitmap
        Return bs
    End Using
End Function

End Class
导入系统图形
导入系统线程
进口Emgu.CV
导入Emgu.CV.Util
导入Emgu.CV.Structure
类主窗口
'已加载专用子主窗口(发送方作为对象,e作为路由EventArgs)_
“我能应付,上膛了
'Dim capturez As Capture=新捕获
'末端接头
#区域“类变量”
声明子睡眠库“kernel32.dll”(ByRef毫秒为整数)
作为捕获的Dim capturez=新捕获
Dim Start_标志为布尔值=False
Dim BoxUnitHeight As Integer=9'根据线路板图案编辑这些值
Dim BOXUNITWITH为整数=6
Dim Frame_array_buffer As Image(灰度,[字节])()=新图像(灰度,字节)(99){
Dim BufferSavePoint为整数=0
Dim Corner_Object_列表为MCvPoint3D32f()()=新的MCvPoint3D32f(Frame_array_buffer.Length-1)({}
Dim Corner_Points_List As PointF()=新的PointF(Frame_array_buffer.Length-1)({}
Dim IC作为新的内置摄像头参数()
Dim EX_参数作为ExterinsicCameraParameters()=新ExterinsicCameraParameters(){}
将图案尺寸标注为尺寸=新尺寸(BoxUnitHeight,BoxUnitWidth)
暗淡的灰色帧作为图像(灰色,字节)=capturez.QueryGrayFrame
将BGR_帧作为图像(BGR的字节)=capturez.RetrieveBgrFrame
Dim calImage As Image(灰度,字节)=新图像(灰度,字节)(“C:\Users\Image\u Correction\u Test\u V2\OpenCV\u Chessboard.png”)
将角点变暗为PointF()=新的PointF(){}
Dim newCornerz作为PointF()=新的PointF(){}
Dim Diferor为双色
Dim TERM标准作为新的MCVTERM标准
公共枚举模式
储蓄框架
计算本质
校准
结束枚举
#末端区域
Private currentMode As Mode=Mode.SavingFrames
已加载专用子主窗口(发送方作为对象,e作为路由EventTargets)_
对付我,上膛了
termCriteria.max_iter=1
termCriteria.epsilon=0.0
termCriteria.type=CvEnum.TERMCRIT.CV\u TERMCRIT\u ITER
端接头
'接收“退出菜单项”单击事件
私有子mnuExit_单击(ByVal sender作为对象,ByVal e作为System.Windows.RoutedEventArgs)_
处理mnuExit。单击
Application.Current.Shutdown()
端接头
私有子按钮\单击(ByVal sender作为对象,ByVal e作为System.Windows.RoutedEventArgs)_
“句柄”按钮。单击
开始标志=真
端接头
'接收“退出菜单项”单击事件
私有子mnuFix_单击(ByVal sender作为对象,ByVal e作为System.Windows.RoutedEventArgs)_
处理mnuFix。单击
灰色框架=capturez.RetrieveGrayFrame
newCornerz=CameraCalibration.FindChessboardCorners(校准图像、图案大小、Emgu.CvEnum.CALIB_CB_类型、自适应阈值或Emgu.CvEnum.CALIB_CB_类型、过滤器四元)
角点=摄影机校准。FindChessboardCorners(灰色框架、图案大小、Emgu.CvEnum.CALIB\u CB\u类型、自适应阈值或Emgu.CvEnum.CALIB\u CB\u类型、过滤器四元)
如果角不是什么,那么
模糊perM作为同形矩阵
perM=CameraCalibration.FindHomography(corners,newCornerz,CvEnum.HOMOGRAPHY_METHOD.DEFAULT,1)
作为图像(灰度,字节)=灰度帧。扭曲透视图(perM,CvEnum.INTER.CV\u INTER\u NN,CvEnum.WARP.CV\u WARP\u默认值,新灰度)
Cal1.Source=ToBitmapSource(测试)
如果结束
端接头
公共子StartTimer(ByVal o作为对象,ByVal发送方作为RoutedEventTargets)
将MyDispatchermer设置为System.Windows.Threading.Dispatchermer=新建System.Windows.Threading.Dispatchermer
myDispatcherTimer.Interval=新的时间跨度(0,0,0,0,30)
'100毫秒
AddHandler myDispatcherTimer.Tick,AddressOf Me.Each_Tick
myDispatcherTimer.Start()
端接头
'在Dispatcher处于活动状态时每100毫秒升高一次。
每个勾号的公共子对象(ByVal o作为对象,ByVal sender作为事件参数)
Dim imagez As Image(Of Bgr,Byte)=capturez.QueryFrame()'而不是QueryFrame,您可能需要执行RetrieveBgrFrame,具体取决于您下载的EmguCV版本。
Stream.Source=ToBitmapSource(imagez)
BGR_Frame=capturez.RetrieveBgrFrame
Gray_Frame=BGR_Frame.Convert(灰度,字节)()
如果currentMode=Mode.SavingFrames,则
角点=摄影机校准。FindChessboardCorners(灰色框架、图案大小、Emgu.CvEnum.CALIB\u CB\u类型、自适应阈值或Emgu.CvEnum.CALIB\u CB\u类型、过滤器四元)
如果角不是什么,那么
'Debug.Print(“填充数组缓冲区”)
“Find chessboardCorners将尝试找到它们,但如果找不到,它仍会运行。如果失败,DrawChessboard将失败并使程序崩溃。
如果是Start_标志,则
Gray_Frame.FindCornerSubPix(新的PointF(0)({corners}),新的大小(11,11),新的大小(-1,-1),新的MCvTermCriteria(30,0.1))
帧\数组\缓冲区(缓冲保存点)=灰色\帧.Copy
BufferSavePoint=BufferSavePoint+1
如果BufferSavePoint=Frame\u array\u buffer.Length,则currentMode=Mode.Caluculating\u Intrinsics的缓冲区已填充
如果结束
“画罗尔斯
照相机校准.绘图棋盘角(灰色框架,图案尺寸,角)
Cal2.Source=ToBitmapSource(灰色框架)
线程。睡眠(100)
如果结束
角=零
如果结束
如果currentMode=Mode.Caluculating\u Intrinsics,则
'Debug.Print(“填充对象和点阵列”)
对于k,整数=0到帧\数组\缓冲区长度-1
角点列表(k)=摄影机校准。FindChessboardCorners(帧数组缓冲区(k)、图案大小、Emgu.CvEnum.CALIB\u CB\u类型、自适应阈值)
“为了准确
灰色框架。FindCornerSubPix(角点列表,新尺寸(11,1