emgucv.坑01

ZC:∵ ROI的Mat使用的是原来的Mat的内存空间,∴内存访问的时候会造成困扰或麻烦,还是将ROI的Mat再clone一下比较保险。如果追求速度 不clone的话,使用时就要非常注意。

ZC:  举例:单通道的ROI使用 类似pb[r*cols+c]来访问内存的话,很可能就进到了非roi的内存区域

 

 

1、知识点:

 1.1、Mat 的 raw数据的指针,是使用 Mat::DataPointer属性来获取的(这是 本Mat图片的 首个raw数据的地址)

 1.2、Mat::Step 属性,参考 C#中 Bitmap的相应属性含义(与  C++/Delphi等中的含义不一样),应该就是指 每row元素的字节数(多通道的话 该值等于 Mat的列数*通道数)

 1.3、坑:在下面的 调试截图中可以看到,mat2 & mat3 的step 和 mat1中的是一样的,也就是说 它们使用的是同一片内存空间。简单验证一下:mat1的 Datapointer为 0x0b240040,mat & mat3 的 Datapointer 为 0x0b28b298,0x0b28b298 - 0x0b240040 = 0x4B258(十进制:307800),mat2 的开始位置是 第100行200列处,3072 * 100(行) + 3(通道)* 200(列) 值正好等于 307800 。

  (1)于是,基本可得结论:mat1 & mat2 & mat3 使用的是同一片内存空间,只是 DataPointer的指向不同而已。

  (2)但是,我之前 以为 “Mat mat2 = new Mat(mat1, new System.Drawing.Rectangle(200, 100, 200, 200));”会是 另外开辟空间,于是导致 程序怎么调试 得到的结果图片画面 总是不对...

  (3)使用 Mat:Clone() 之后,就是另外的地址空间了。原图 大小是:宽 1024像素,高 680像素 ,占用像素空间大小是  十进制3072*680=2088960(字节)(0x1FE000)

    可以看到 mat1的地址空间范围是 0x0b240040 ~ 0x0b240040+0x1FE000 ==>  0x0b240040 ~ 0x0B43E040。

   取的 小图的 大小是 200行*600(step)= 120000(0x1D4C0)小图的地址范围就是:0x08b8aac0 ~ 0x08BA7F80

   两者 明显没有交集

2、代码:

        private void Click_imshow(object sender, RoutedEventArgs e)
        {
            string str = @"C: \Users\Administrator\Desktop\AAA.jpg";
            Mat mat1 = CvInvoke.Imread(str);
            CvInvoke.Imshow("1", mat1);

            Mat mat2 = new Mat(mat1, new System.Drawing.Rectangle(200, 100, 200, 200));
            CvInvoke.Imshow("2", mat2);

            Mat mat3 = mat2;
            CvInvoke.Imshow("3", mat3);

            Mat mat4 = mat2.Clone();
            CvInvoke.Imshow("4", mat4);
        }

 2.1、emgucv:vs2017 的 “管理 NuGet 程序包”安装的:(选择安装了 Emgucv4.1.1 之后,它自动安装了下图中的 ZedGraph)

  

 

 

3、调试 截图:

  

 

 

4、代码执行效果图:

  

 

 4.1、原图

  

5、

 

posted @ 2019-11-08 13:08  csskill  阅读(346)  评论(0编辑  收藏  举报