C# Kinect v2红外传感器的校准&;RGB图像始终略微关闭
我使用官方的Kinect SDK 2.0和Emgu CV来识别魔方的颜色 首先,我在红外相机上使用Canny边缘提取,因为它比RGB相机更好地处理不同的闪电条件,并且更适合检测轮廓 然后我用这个代码把红外传感器的坐标转换成RGB摄像机的坐标。 正如你在图片中看到的,他们仍然远离我所寻找的。因为我已经使用了官方的C# Kinect v2红外传感器的校准&;RGB图像始终略微关闭,c#,opencv,image-processing,kinect,emgucv,C#,Opencv,Image Processing,Kinect,Emgucv,我使用官方的Kinect SDK 2.0和Emgu CV来识别魔方的颜色 首先,我在红外相机上使用Canny边缘提取,因为它比RGB相机更好地处理不同的闪电条件,并且更适合检测轮廓 然后我用这个代码把红外传感器的坐标转换成RGB摄像机的坐标。 正如你在图片中看到的,他们仍然远离我所寻找的。因为我已经使用了官方的KinectSensor.CoordinateMapper.MapDepthFrameToColorSpace我不知道还有什么办法可以改善这种情况 using (var colorFra
KinectSensor.CoordinateMapper.MapDepthFrameToColorSpace
我不知道还有什么办法可以改善这种情况
using (var colorFrame = reference.ColorFrameReference.AcquireFrame())
using (var irFrame = reference.InfraredFrameReference.AcquireFrame())
{
if (colorFrame == null || irFrame == null)
return;
// initialize depth frame data
FrameDescription depthDesc = irFrame.FrameDescription;
if (_depthData == null)
{
uint depthSize = depthDesc.LengthInPixels;
_depthData = new ushort[depthSize];
_colorSpacePoints = new ColorSpacePoint[depthSize];
// fill Array with max value so all pixels can be mapped
for (int i = 0; i < _depthData.Length; i++)
{
_depthData[i] = UInt16.MaxValue;
}
// didn't work so well with the actual depth-data
//depthFrame.CopyFrameDataToArray(_depthData);
_sensor.CoordinateMapper.MapDepthFrameToColorSpace(_depthData, _colorSpacePoints);
}
}
使用(var colorFrame=reference.ColorFrameReference.AcquireFrame())
使用(var irFrame=reference.InfraredFrameReference.AcquireFrame())
{
if(colorFrame==null | | irFrame==null)
回来
//初始化深度帧数据
FrameDescription depthDesc=irFrame.FrameDescription;
如果(_depthData==null)
{
单位深度尺寸=深度描述长度像素;
_depthData=新的ushort[depthSize];
_colorSpacePoints=新的ColorSpacePoint[depthSize];
//使用最大值填充数组,以便可以映射所有像素
对于(int i=0;i<\u depthData.Length;i++)
{
_depthData[i]=UInt16.MaxValue;
}
//与实际深度数据不太匹配
//depthFrame.CopyFrameDataToArray(_depthData);
_sensor.CoordinateMapper.MapDepthFrameToColorSpace(_depthData,_colorSpacePoints);
}
}
这是我创建的一个辅助函数,用于将红外空间中的点阵列转换为颜色空间
public static System.Drawing.Point[] DepthPointsToColorSpace(System.Drawing.Point[] depthPoints, ColorSpacePoint[] colorSpace){
for (int i = 0; i < depthPoints.Length; i++)
{
// 512 is the width of the depth/infrared image
int index = 512 * depthPoints[i].Y + depthPoints[i].X;
depthPoints[i].X = (int)Math.Floor(colorSpace[index].X + 0.5);
depthPoints[i].Y = (int)Math.Floor(colorSpace[index].Y + 0.5);
}
return depthPoints;
}
public static System.Drawing.Point[]DepthPointsToColorSpace(System.Drawing.Point[]depthPoints,colorSpace[]colorSpace){
for(int i=0;i
这是因为它与检索深度数据的相机和检索颜色数据的相机不同。
因此,应该应用校正因子来置换深度数据。
这是一个几乎不变的因子,但它与距离有关。
我没有给你的代码,但是你可以自己计算。这是因为它不是同一台相机——检索深度数据的相机和检索颜色数据的相机。 因此,应该应用校正因子来置换深度数据。 这是一个几乎不变的因子,但它与距离有关。
我没有你的代码,但你可以自己计算。我们可以通过使用2个四边形映射将红外图像坐标转换为彩色图像坐标来解决这个问题 类似地,红外图像中的四边形
Q(x1,y1,x2,y2,x3,y3,x4,y4)
,
它在相应的彩色图像中映射四边形Q'(x1',y1',x2',y2',x3',y3',x4',y4')
我们可以将上述映射以方程的形式写成如下:
x1=173; y1=98; x2=387; y2=93; x3=395; y3=262; x4=172; y4=264;
x1p=787; y1p=235; x2p=1407; y2p=215; x3p=1435; y3p=705; x4p=795; y4p=715;
tx=(x1p-x2p+x3p-x4p)*(y4p-y3p)-(y1p-y2p+y3p-y4p)*(x4p-x3p);
ty=(x2p-x3p)*(y4p-y3p)-(x4p-x3p)*(y2p-y3p);
a31=tx/ty;
tx=(y1p-y2p+y3p-y4p)*(x2p-x3p)-(x1p-x2p+x3p-x4p)*(y2p-y3p);
ty=(x2p-x3p)*(y4p-y3p)-(x4p-x3p)*(y2p-y3p);
a32=tx/ty;
a11=x2p-x1p+a31*x2p;
a12=x4p-x1p+a32*x4p;
a13=x1p;
a21=y2p-y1p+a31*y2p;
a22=y4p-y1p+a32*y4p;
a23=y1p;
a33=1.0;
Q'=Q*A
式中,A是系数为a11、a12、a13、a21、…、a33的3 X 3矩阵
获得系数的公式如下所示:
x1=173; y1=98; x2=387; y2=93; x3=395; y3=262; x4=172; y4=264;
x1p=787; y1p=235; x2p=1407; y2p=215; x3p=1435; y3p=705; x4p=795; y4p=715;
tx=(x1p-x2p+x3p-x4p)*(y4p-y3p)-(y1p-y2p+y3p-y4p)*(x4p-x3p);
ty=(x2p-x3p)*(y4p-y3p)-(x4p-x3p)*(y2p-y3p);
a31=tx/ty;
tx=(y1p-y2p+y3p-y4p)*(x2p-x3p)-(x1p-x2p+x3p-x4p)*(y2p-y3p);
ty=(x2p-x3p)*(y4p-y3p)-(x4p-x3p)*(y2p-y3p);
a32=tx/ty;
a11=x2p-x1p+a31*x2p;
a12=x4p-x1p+a32*x4p;
a13=x1p;
a21=y2p-y1p+a31*y2p;
a22=y4p-y1p+a32*y4p;
a23=y1p;
a33=1.0;
我们可以通过2个四边形映射将红外图像坐标转换为彩色图像坐标来解决这个问题 类似地,红外图像中的四边形
Q(x1,y1,x2,y2,x3,y3,x4,y4)
,
它在相应的彩色图像中映射四边形Q'(x1',y1',x2',y2',x3',y3',x4',y4')
我们可以将上述映射以方程的形式写成如下:
x1=173; y1=98; x2=387; y2=93; x3=395; y3=262; x4=172; y4=264;
x1p=787; y1p=235; x2p=1407; y2p=215; x3p=1435; y3p=705; x4p=795; y4p=715;
tx=(x1p-x2p+x3p-x4p)*(y4p-y3p)-(y1p-y2p+y3p-y4p)*(x4p-x3p);
ty=(x2p-x3p)*(y4p-y3p)-(x4p-x3p)*(y2p-y3p);
a31=tx/ty;
tx=(y1p-y2p+y3p-y4p)*(x2p-x3p)-(x1p-x2p+x3p-x4p)*(y2p-y3p);
ty=(x2p-x3p)*(y4p-y3p)-(x4p-x3p)*(y2p-y3p);
a32=tx/ty;
a11=x2p-x1p+a31*x2p;
a12=x4p-x1p+a32*x4p;
a13=x1p;
a21=y2p-y1p+a31*y2p;
a22=y4p-y1p+a32*y4p;
a23=y1p;
a33=1.0;
Q'=Q*A
式中,A是系数为a11、a12、a13、a21、…、a33的3 X 3矩阵
获得系数的公式如下所示:
x1=173; y1=98; x2=387; y2=93; x3=395; y3=262; x4=172; y4=264;
x1p=787; y1p=235; x2p=1407; y2p=215; x3p=1435; y3p=705; x4p=795; y4p=715;
tx=(x1p-x2p+x3p-x4p)*(y4p-y3p)-(y1p-y2p+y3p-y4p)*(x4p-x3p);
ty=(x2p-x3p)*(y4p-y3p)-(x4p-x3p)*(y2p-y3p);
a31=tx/ty;
tx=(y1p-y2p+y3p-y4p)*(x2p-x3p)-(x1p-x2p+x3p-x4p)*(y2p-y3p);
ty=(x2p-x3p)*(y4p-y3p)-(x4p-x3p)*(y2p-y3p);
a32=tx/ty;
a11=x2p-x1p+a31*x2p;
a12=x4p-x1p+a32*x4p;
a13=x1p;
a21=y2p-y1p+a31*y2p;
a22=y4p-y1p+a32*y4p;
a23=y1p;
a33=1.0;
这两张照片真的一样吗?在红外传感器中,我们可以看到你左边还有很多空间,而你是RGB图像的左边。不,它们不一样。一个来自RGB摄像头(1920 x 1080),另一个来自其旁边的红外传感器(512 x 424)。对于Kinect v2,它们具有不同的分辨率和视角。这就是为什么我必须使用Kinect v2 SDK中的
CoordinateMapper
。我不熟悉Kinect,但您可能缺少一些偏移量!这两张照片真的一样吗?在红外传感器中,我们可以看到你左边还有很多空间,而你是RGB图像的左边。不,它们不一样。一个来自RGB摄像头(1920 x 1080),另一个来自其旁边的红外传感器(512 x 424)。对于Kinect v2,它们具有不同的分辨率和视角。这就是为什么我必须使用Kinect v2 SDK中的CoordinateMapper
。我不熟悉Kinect,但您可能缺少一些偏移量!