从 byte[] 创建图像时 C#/EmguCv 参数超出范围异常
C# / EmguCv Argument Out of Range exception when creating images from byte[]
我尝试在 edgeimages 上使用 MatchTemplate 来查找图像中的教学对象。作为图像源,我使用 kinect2。我首先教一个边缘图像并在后来捕获的图像中搜索教过的模板。用 canny 计算边缘图像效果很好。我将边保存为 byte[] with
byte[] bytes = cannyFrame.GetData();
稍后我尝试使用给定的数据创建图像。不幸的是,有时创建图像会在 ArgumentOutOfRange-Exception 中运行并声称数组太大。有时会发生异常,有时不会发生。创建当前图像以及创建教学图像时都可能发生异常(请参阅我的代码中的注释)。谁能告诉我,为什么会出现这个异常?
Bitmap bmp;
//bmp is filled with the image from the kinect
int width;
int height;
byte[] currentEdges = EdgeDetector.CalculateEdges(bmp, referenceImage.BorderOne, referenceImage.BorderTwo, out width, out height);
try
{
Console.WriteLine("ref width: {0}, height: {1}, byte[]length: {2}", referenceImage.Width_px, referenceImage.Height_px, referenceImage.Edges.Length);
//Here happens the exception sometimes:
Image<Gray, byte> templateImage = new Image<Gray, byte>(referenceImage.Width_px, referenceImage.Height_px);
templateImage.Bytes = referenceImage.Edges;
Console.WriteLine("current image width: {0}, height: {1}, byte[]length: {2}", width, height, currentEdges.Length);
//Here happens the exception sometimes:
Image<Gray, byte> searchImage = new Image<Gray, byte>(width, height);
searchImage.Bytes = currentEdges;
Console.WriteLine("");
Image<Gray, float> imgMatch = searchImage.MatchTemplate(templateImage, TemplateMatchingType.CcoeffNormed);
}
catch (Exception)
{
Console.WriteLine(ex.ToString());
}
internal class EdgeDetector
{
internal static byte[] CalculateEdges(Bitmap bmp, int borderOne, int borderTwo, out int width, out int height)
{
try
{
Image<Bgr, byte> img = new Image<Bgr, byte>(bmp);
Mat smallGrayFrame = new Mat();
Mat smoothedGrayFrame = new Mat();
Mat cannyFrame = new Mat();
CvInvoke.PyrDown(img, smallGrayFrame);
CvInvoke.PyrUp(smallGrayFrame, smoothedGrayFrame);
CvInvoke.Canny(smoothedGrayFrame, cannyFrame, borderOne, borderTwo);
byte[] bytes = cannyFrame.GetData();
width = cannyFrame.Width;
height = cannyFrame.Height;
return bytes;
}
catch (Exception ex)
{
width = 0;
height = 0;
return null;
}
}
示例输出:
参考宽度:46,高度:44,字节[]长度:2024
System.ArgumentOutOfRangeException:请求的范围超出了结尾
大批。
在 System.Runtime.InteropServices.Marshal.CopyToNative(对象源,Int32 s
tartIndex、IntPtr 目标、Int32 长度)
在 Emgu.CV.CvArray`1.set_Bytes(字节 [] 值)
在 AlgorithmsHelper.SearchEdgeImage(AssistentEdgeImageOpenCv referenceImage, Image currentImage)
感谢任何帮助。
我仍然不知道为什么会出现异常,但我已经找到了一个解决方案作为解决方案。就像 http://www.emgu.com/wiki/index.php/Working_with_Images 建议我创建一个垫子,用字节填充它并从垫子创建图像 工作正常。
Mat currentMat;
using (MemoryStream memoryStream = new MemoryStream(currentEdges))
{
byte[] rawData = new byte[memoryStream.Length];
memoryStream.Read(rawData, 0, (int)memoryStream.Length);
GCHandle rawDataHandle = GCHandle.Alloc(rawData, GCHandleType.Pinned);
IntPtr address = rawDataHandle.AddrOfPinnedObject();
currentMat = new Mat(new System.Drawing.Size(width, height), DepthType.Cv8U, 1, address, width);
rawDataHandle.Free();
}
Image<Gray, byte> currentImage = currentMat.ToImage<Gray, byte>();
Mat templateMat;
using (MemoryStream memoryStream = new MemoryStream(referenceImage.Edges))
{
byte[] rawData = new byte[memoryStream.Length];
memoryStream.Read(rawData, 0, (int)memoryStream.Length);
GCHandle rawDataHandle = GCHandle.Alloc(rawData, GCHandleType.Pinned);
IntPtr address = rawDataHandle.AddrOfPinnedObject();
templateMat = new Mat(new System.Drawing.Size(referenceImage.Width_px, referenceImage.Height_px), DepthType.Cv8U, 1, address, referenceImage.Width_px);
rawDataHandle.Free();
}
Image<Gray, byte> templateImage = templateMat.ToImage<Gray, byte>();
Image<Gray, float> imgMatch = currentImage.MatchTemplate(templateImage, TemplateMatchingType.CcoeffNormed);
我尝试在 edgeimages 上使用 MatchTemplate 来查找图像中的教学对象。作为图像源,我使用 kinect2。我首先教一个边缘图像并在后来捕获的图像中搜索教过的模板。用 canny 计算边缘图像效果很好。我将边保存为 byte[] with
byte[] bytes = cannyFrame.GetData();
稍后我尝试使用给定的数据创建图像。不幸的是,有时创建图像会在 ArgumentOutOfRange-Exception 中运行并声称数组太大。有时会发生异常,有时不会发生。创建当前图像以及创建教学图像时都可能发生异常(请参阅我的代码中的注释)。谁能告诉我,为什么会出现这个异常?
Bitmap bmp;
//bmp is filled with the image from the kinect
int width;
int height;
byte[] currentEdges = EdgeDetector.CalculateEdges(bmp, referenceImage.BorderOne, referenceImage.BorderTwo, out width, out height);
try
{
Console.WriteLine("ref width: {0}, height: {1}, byte[]length: {2}", referenceImage.Width_px, referenceImage.Height_px, referenceImage.Edges.Length);
//Here happens the exception sometimes:
Image<Gray, byte> templateImage = new Image<Gray, byte>(referenceImage.Width_px, referenceImage.Height_px);
templateImage.Bytes = referenceImage.Edges;
Console.WriteLine("current image width: {0}, height: {1}, byte[]length: {2}", width, height, currentEdges.Length);
//Here happens the exception sometimes:
Image<Gray, byte> searchImage = new Image<Gray, byte>(width, height);
searchImage.Bytes = currentEdges;
Console.WriteLine("");
Image<Gray, float> imgMatch = searchImage.MatchTemplate(templateImage, TemplateMatchingType.CcoeffNormed);
}
catch (Exception)
{
Console.WriteLine(ex.ToString());
}
internal class EdgeDetector
{
internal static byte[] CalculateEdges(Bitmap bmp, int borderOne, int borderTwo, out int width, out int height)
{
try
{
Image<Bgr, byte> img = new Image<Bgr, byte>(bmp);
Mat smallGrayFrame = new Mat();
Mat smoothedGrayFrame = new Mat();
Mat cannyFrame = new Mat();
CvInvoke.PyrDown(img, smallGrayFrame);
CvInvoke.PyrUp(smallGrayFrame, smoothedGrayFrame);
CvInvoke.Canny(smoothedGrayFrame, cannyFrame, borderOne, borderTwo);
byte[] bytes = cannyFrame.GetData();
width = cannyFrame.Width;
height = cannyFrame.Height;
return bytes;
}
catch (Exception ex)
{
width = 0;
height = 0;
return null;
}
}
示例输出: 参考宽度:46,高度:44,字节[]长度:2024 System.ArgumentOutOfRangeException:请求的范围超出了结尾 大批。 在 System.Runtime.InteropServices.Marshal.CopyToNative(对象源,Int32 s tartIndex、IntPtr 目标、Int32 长度) 在 Emgu.CV.CvArray`1.set_Bytes(字节 [] 值) 在 AlgorithmsHelper.SearchEdgeImage(AssistentEdgeImageOpenCv referenceImage, Image currentImage)
感谢任何帮助。
我仍然不知道为什么会出现异常,但我已经找到了一个解决方案作为解决方案。就像 http://www.emgu.com/wiki/index.php/Working_with_Images 建议我创建一个垫子,用字节填充它并从垫子创建图像 工作正常。
Mat currentMat;
using (MemoryStream memoryStream = new MemoryStream(currentEdges))
{
byte[] rawData = new byte[memoryStream.Length];
memoryStream.Read(rawData, 0, (int)memoryStream.Length);
GCHandle rawDataHandle = GCHandle.Alloc(rawData, GCHandleType.Pinned);
IntPtr address = rawDataHandle.AddrOfPinnedObject();
currentMat = new Mat(new System.Drawing.Size(width, height), DepthType.Cv8U, 1, address, width);
rawDataHandle.Free();
}
Image<Gray, byte> currentImage = currentMat.ToImage<Gray, byte>();
Mat templateMat;
using (MemoryStream memoryStream = new MemoryStream(referenceImage.Edges))
{
byte[] rawData = new byte[memoryStream.Length];
memoryStream.Read(rawData, 0, (int)memoryStream.Length);
GCHandle rawDataHandle = GCHandle.Alloc(rawData, GCHandleType.Pinned);
IntPtr address = rawDataHandle.AddrOfPinnedObject();
templateMat = new Mat(new System.Drawing.Size(referenceImage.Width_px, referenceImage.Height_px), DepthType.Cv8U, 1, address, referenceImage.Width_px);
rawDataHandle.Free();
}
Image<Gray, byte> templateImage = templateMat.ToImage<Gray, byte>();
Image<Gray, float> imgMatch = currentImage.MatchTemplate(templateImage, TemplateMatchingType.CcoeffNormed);