Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.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#/EmguCv参数超出范围异常_C#_Opencv_Emgucv - Fatal编程技术网

从字节[]创建图像时,C#/EmguCv参数超出范围异常

从字节[]创建图像时,C#/EmguCv参数超出范围异常,c#,opencv,emgucv,C#,Opencv,Emgucv,我尝试使用EdgeImage上的MatchTemplate在图像中查找教学对象。作为图像源,我使用kinect2。我首先设定一个边缘图像,然后在随后捕获的图像中搜索设定的模板。使用canny计算边缘图像效果非常好。我将边保存为字节[],并使用 byte[] bytes = cannyFrame.GetData(); 稍后,我尝试使用给定的数据创建图像。不幸的是,有时创建映像会在ArgumentOutOfRange异常中运行,并声称数组太大。有时发生异常,有时不发生异常。创建当前图像时,以及创建

我尝试使用EdgeImage上的MatchTemplate在图像中查找教学对象。作为图像源,我使用kinect2。我首先设定一个边缘图像,然后在随后捕获的图像中搜索设定的模板。使用canny计算边缘图像效果非常好。我将边保存为字节[],并使用

byte[] bytes = cannyFrame.GetData();
稍后,我尝试使用给定的数据创建图像。不幸的是,有时创建映像会在ArgumentOutOfRange异常中运行,并声称数组太大。有时发生异常,有时不发生异常。创建当前图像时,以及创建教学图像时,都可能发生异常(请参见代码中的注释)。谁能告诉我,为什么会发生这种异常

        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;
            }
        }
bmp位图;
//bmp由kinect中的图像填充
整数宽度;
内部高度;
字节[]CurrentEdge=EdgeDetector.CalculateEdge(bmp,referenceImage.BorderOne,referenceImage.BorderTwo,输出宽度,输出高度);
尝试
{
WriteLine(“ref-width:{0},height:{1},byte[]length:{2}”,referenceImage.width_-px,referenceImage.height_-px,referenceImage.Edges.length);
//有时会出现例外情况:
Image templateImage=新图像(referenceImage.Width\u px,referenceImage.Height\u px);
templateImage.Bytes=referenceImage.Edges;
WriteLine(“当前图像宽度:{0},高度:{1},字节[]长度:{2}”,宽度,高度,CurrentEdge.length);
//有时会出现例外情况:
图像搜索图像=新图像(宽度、高度);
searchImage.Bytes=CurrentEdge;
控制台。写线(“”);
Image imgMatch=searchImage.MatchTemplate(templateImage,TemplateMatchingType.CcoeffNormed);
}
捕获(例外)
{                
Console.WriteLine(例如ToString());
}
内部类边缘检测器
{
内部静态字节[]CalculatedGes(位图bmp、int-borderOne、int-borderTwo、out-int-width、out-int-height)
{
尝试
{
图像img=新图像(bmp);
Mat smallGrayFrame=新Mat();
Mat SmoothdGrayFrame=新Mat();
垫筒框架=新垫();
CvInvoke.PyrDown(img,smallGrayFrame);
CvInvoke.PyrUp(smallGrayFrame、SmoothdGrayFrame);
CvInvoke.Canny(SmoothdGrayFrame、cannyFrame、borderOne、borderTwo);
byte[]bytes=cannyFrame.GetData();
宽度=罐头框架。宽度;
高度=罐头框架高度;
返回字节;
}
捕获(例外情况除外)
{
宽度=0;
高度=0;
返回null;
}
}
输出示例: 参考宽度:46,高度:44,字节[]长度:2024 System.ArgumentOutOfRangeException:请求的范围超出了 数组。 在System.Runtime.InteropServices.Marshal.CopyToNative(对象源,Int32 s tartIndex,IntPtr目的地,Int32长度) 在Emgu.CV.CvArray`1.set_字节(字节[]值) 在AlgorithmsHelper.SearchEdgeImage(辅助EdgeImageOpenCV参考图像,图像当前图像)


非常感谢您的帮助。

我仍然不知道为什么会出现异常,但我已经找到了一个解决方案作为演练。就像建议的那样,我创建一个垫子,用字节填充它,然后从垫子创建一个图像,效果很好

            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);
Mat-currentMat;
使用(MemoryStream MemoryStream=新的MemoryStream(CurrentEdge))
{
字节[]rawData=新字节[memoryStream.Length];
memoryStream.Read(rawData,0,(int)memoryStream.Length);
GCHandle rawDataHandle=GCHandle.Alloc(rawData,GCHandleType.pinted);
IntPtr address=rawDataHandle.AddrOfPinnedObject();
currentMat=新Mat(新系统图纸尺寸(宽度、高度)、DepthType.Cv8U、1、地址、宽度);
rawDataHandle.Free();
}
Image currentImage=currentMat.ToImage();
垫模板垫;
使用(MemoryStream MemoryStream=新的MemoryStream(参考图像边缘))
{
字节[]rawData=新字节[memoryStream.Length];
memoryStream.Read(rawData,0,(int)memoryStream.Length);
GCHandle rawDataHandle=GCHandle.Alloc(rawData,GCHandleType.pinted);
IntPtr address=rawDataHandle.AddrOfPinnedObject();
templateMat=新Mat(新系统图纸尺寸(参考图像宽度,参考图像高度),DepthType.Cv8U,1,地址,参考图像宽度);
rawDataHandle.Free();
}
Image templateImage=templateMat.ToImage();
Image imgMatch=currentImage.MatchTemplate(templateImage,TemplateMatchingType.CcoeffNormed);