微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

vb.net – 从单应性中提取变换和旋转矩阵?

我有一个来自相机的2个连续图像,我想估计相机姿势的变化:

我计算光流量:

Const MAXFEATURES As Integer = 100
imgA = New Image(Of [Structure].Bgr,Byte)("pic1.bmp")
imgB = New Image(Of [Structure].Bgr,Byte)("pic2.bmp")
grayA = imgA.Convert(Of Gray,Byte)()
grayB = imgB.Convert(Of Gray,Byte)()
imagesize = cvGetSize(grayA)
pyrBufferA = New Emgu.CV.Image(Of Emgu.CV.Structure.Gray,Byte) _
    (imagesize.Width + 8,imagesize.Height / 3)
pyrBufferB = New Emgu.CV.Image(Of Emgu.CV.Structure.Gray,imagesize.Height / 3)
features = MAXFEATURES
featuresA = grayA.GoodFeaturesToTrack(features,0.01,25,3)
grayA.FindCornerSubPix(featuresA,New System.Drawing.Size(10,10),New System.Drawing.Size(-1,-1),New Emgu.CV.Structure.MCvTermCriteria(20,0.03))
features = featuresA(0).Length
Emgu.CV.OpticalFlow.PyrLK(grayA,grayB,pyrBufferA,pyrBufferB,_
                          featuresA(0),New Size(25,25),3,_
                          New Emgu.CV.Structure.MCvTermCriteria(20,0.03D),flags,featuresB(0),status,errors)
pointsA = New Matrix(Of Single)(features,2)
pointsB = New Matrix(Of Single)(features,2)
For i As Integer = 0 To features - 1
    pointsA(i,0) = featuresA(0)(i).X
    pointsA(i,1) = featuresA(0)(i).Y
    pointsB(i,0) = featuresB(0)(i).X
    pointsB(i,1) = featuresB(0)(i).Y
Next
Dim Homography As New Matrix(Of Double)(3,3)
cvFindHomography(pointsA.Ptr,pointsB.Ptr,Homography,HOmogRAPHY_METHOD.RANSAC,1,0)

它看起来正确,相机向左和向上移动:

现在我想知道相机移动和旋转了多少.如果我宣布我的相机位置及其所看到的内容

' Create camera location at origin and lookat (straight ahead,1 in the Z axis)
Location = New Matrix(Of Double)(2,3)
location(0,0) = 0 ' X location
location(0,1) = 0 ' Y location
location(0,2) = 0 ' Z location
location(1,0) = 0 ' X lookat
location(1,1) = 0 ' Y lookat
location(1,2) = 1 ' Z lookat

如何计算新位置和外观?

如果我这样做是错的或者有更好的方法,那么任何建议都会非常受欢迎,谢谢!

那么你所看到的就是一个简单的术语: Pythagorean theorem problem a ^ 2 b ^ 2 = c ^ 2.然而,当涉及到基于相机的应用程序时,事情并不是很容易准确确定.您已找到“a”所需的一半细节,但发现“b”或“c”要困难得多.

简答

基本上它不能用一台摄像机完成.但它可以用两个相机完成.

冗长的答案(我想更深入地解释,没有双关语意)

我会试着解释一下,说我们在图像中选择两个点并向左移动相机.我们知道每个点B1的相机距离为20mm,B2点为40mm.现在让我们假设我们处理图像,我们的测量结果是A1是(0,2)而A2是(0,4)它们分别与B1和B2有关.现在A1和A2不是测量值;它们是运动的像素.

我们现在要做的是将A1和A2的变化乘以计算的常数,该常数将是B1和B2的实际世界距离.注意:根据测量B *,每个都不同.这一切都涉及Angle of view或更多通常称为不同距离摄影的视野.如果您知道相机CCD上每个像素的大小和相机内部镜头的f数,则可以精确计算常数.

我希望情况并非如此,所以在不同的距离你必须放置一个你知道长度的物体,看看它占用了多少像素.关闭你可以使用标尺使事情变得更容易.通过这些测量.您获取此数据并形成一条最佳拟合线的曲线.如果X轴是物体的距离,Y轴将是像素与距离比的常数,你必须乘以你的运动.

那么我们如何应用这条曲线.嗯,这是猜测的工作.理论上,运动A *的测量越大,物体越接近相机.在我们的例子中,我们的A1的比率> A2分别表示5mm和3mm,我们现在知道B1点移动了10mm(2x5mm),B2移动了6mm(2x6mm).但是让我们面对它 – 我们永远不会知道B,我们永远无法分辨移动的距离是否是一个物体的20个像素,近距离没有移动很远,或者一个物体远远移动了很远的距离.这就是为什么像XBox Kinect这样的东西使用额外的传感器来获取可以绑定到图像中的对象的深度信息.

您可以尝试使用两台摄像机尝试这些摄像机,因为已知这些摄像机之间的距离可以更精确地计算运动(有效地不使用深度传感器).这背后的数学是非常复杂的,我建议查阅一些关于这个主题的期刊论文.如果你想让我解释这个理论,我可以尝试.

我的所有经验来自为我的PHD设计高速视频采集和图像处理所以相信我,不能用一台相机完成,对不起.我希望其中一些有所帮助.

干杯

克里斯

[编辑]

我打算添加评论,但由于大量信息,这更容易:

因为它是Kinect,我会假设你有一些与每个点相关的深度信息,否则你需要弄清楚如何得到它.

您需要开始使用的等式是视场(FOV):

o / d = i / f

哪里:

f等于镜头的焦距,通常以mm为单位(即18 28 30 50为标准示例)

d是从kinect数据收集的镜头的物距

o是物体尺寸(或垂直于光轴并由光轴平分的“视场”).

i是图像尺寸(或垂直于光轴并由光轴对分的“场光阑”).

我们需要计算i,其中o是我们未知的因此对于i(这是一个对角线测量),

我们将需要ccd上像素的大小,这将以微米或μm为单位,您将需要找到这些信息,因为我们知道我们将其视为14um,这是中档区域扫描相机的标准.

所以首先我们需要计算出水平尺寸(ih),它是相机宽度的像素数量乘以ccd像素的尺寸(我们将使用640 x 320)

所以:ih = 640 * 14um = 8960um

= 8960/1000 = 8.96mm

现在我们需要垂直尺寸(iv)相同的过程但高度

所以:iv =(320 * 14um)/ 1000 = 4.48mm

现在我发现毕达哥拉斯定理毕达哥拉斯定理a ^ 2 b ^ 2 = c ^ 2

所以:i = sqrt(ih ^ 2 _ iv ^ 2)

= 10.02 mm

现在我们假设我们有一个28毫米镜头.同样,必须找到这个确切的值.所以我们的等式重新排列,给我们o是:

o =(i * d)/ f

记住o将是对角线(我们假设物体或点距离是50mm):

o =(10.02mm * 50mm)/ 28mm

17.89mm

现在我们需要计算水平尺寸(哦)和垂直尺寸(ov),因为这将给出物体移动的每个像素的距离.现在,当FOVαCCD或i与o成正比时,我们将计算出比率k

k = i / o

= 10.02 / 17.89 

= 0.56

所以:

o水平尺寸(哦):

哦= ih / k

= 8.96mm / 0.56 =每像素16mm

o垂直尺寸(ov):

ov = iv / k

= 4.48mm / 0.56 =每像素8mm

现在我们有了我们需要的常量,让我们在一个例子中使用它.如果我们50mm处的物体从位置(0,0)移动到(2,4)那么现实生活中的测量值是:

(2 * 16mm,4 * 8mm)=(32mm,32mm)

毕竟,毕达哥拉斯定理:a ^ 2 b ^ 2 = c ^ 2

总距离= sqrt(32 ^ 2 32 ^ 2)

= 45.25mm

复杂我知道,但是一旦你在一个程序中有这个,它就会更容易.因此,对于每一点,您将不得不重复至少一半的过程,因为d将会改变,因此o对于您的检查的每个点.

希望这能帮到你的路上,

干杯克里斯

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Format[$] ( expr [ , fmt ] ) format 返回变体型 format$ 强制返回为文本 -------------------------------- 数字类型的格式化 --------------------------------     固定格式参数:     General Number 普通数字,如可以用来去掉千位分隔号     format$("100,1
VB6或者ASP 格式化时间为 MM/dd/yyyy 格式,竟然没有好的办法, Format 或者FormatDateTime 竟然结果和系统设置的区域语言的日期和时间格式相关。意思是尽管你用诸如 Format(Now, "MM/dd/yyyy"),如果系统的设置格式区域语言的日期和时间格式分隔符是"-",那他还会显示为 MM-dd-yyyy     只有拼凑: <%response.write
在项目中添加如下代码:新建窗口来显示异常信息。 Namespace My ‘全局错误处理,新的解决方案直接添加本ApplicationEvents.vb 到工程即可 ‘添加后还需要一个From用来显示错误。如果到这步还不会则需要先打好基础啦 ‘======================================================== ‘以下事件
转了这一篇文章,原来一直想用C#做k3的插件开发,vb没有C#用的爽呀,这篇文章写与2011年,看来我以前没有认真去找这个方法呀。 https://blog.csdn.net/chzjxgd/article/details/6176325 金蝶K3 BOS的插件官方是用VB6编写的,如果  能用.Net下的语言工具开发BOS插件是一件很愉快的事情,其中缘由不言而喻,而本文则是个人首创,实现在了用V
Sub 分列() ‘以空格为分隔符,连续空格只算1个。对所选中的单元格进行处理 Dim m As Range, tmpStr As String, s As String Dim x As Integer, y As Integer, subStr As String If MsgBox("确定要分列处理吗?请确定分列的数据会覆盖它后面的单元格!", _
  窗体代码 1 Private Sub Text1_OLEDragDrop(Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, X As Single, Y As Single) 2 Dim path As String, hash As String 3 For Each fil
  Imports MySql.Data.MySqlClient Public Class Form1 ‘ GLOBAL DECLARATIONS Dim conString As String = "Server=localhost;Database=net2;Uid=root;Pwd=123456;" Dim con As New MySqlConnection
‘導入命名空間 Imports ADODB Imports Microsoft.Office.Interop   Private Sub A1() Dim Sql As String Dim Cnn As New ADODB.Connection Dim Rs As New ADODB.Recordset Dim S As String   S = "Provider=OraOLEDB.Oracl
Imports System.IO Imports System.Threading Imports System.Diagnostics Public Class Form1 Dim A(254) As String    Function ping(ByVal IP As Integer) As String Dim IPAddress As String IPAddress = "10.0.
VB运行EXE程序,并等待其运行结束 参考:https://blog.csdn.net/useway/article/details/5494084 Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long Pr