从 std::vector<int> 模糊 Mat 导致的错误指针:cv::Exception

Posted

技术标签:

【中文标题】从 std::vector<int> 模糊 Mat 导致的错误指针:cv::Exception【英文标题】:Bad pointers by blurring Mat from std::vector<int>: cv::Exception 【发布时间】:2016-11-10 16:08:42 【问题描述】:

我是openCV的新手,已经尝试了几个小时但没有成功,所以我希望你能给我一些建议。我正在尝试检测图像中的圆心,如下所述: https://solarianprogrammer.com/2015/05/08/detect-red-circles-image-using-opencv/

我在 Windows XP 和 OpenCV 2.2.0 上的 Visual Studio 10 中使用 C++。

我的图片采用std::shared_ptr&lt;CImg&lt;double&gt;&gt; 格式,在白色背景上显示黑点。然后我将它们转换为长度为 65536(256 行/列)的std::vector&lt;int&gt; vecImagePx,数据值在 0 到 255 之间。我已验证一切正常。

接下来,我将向量转换为 Mat,这是正确的。我通过查看 jpg 文件知道这一点,根据 Visual Studio 2010,指向 datastart 和 dataend 的指针和数据并未显示为错误指针,但似乎具有有效地址。另外,Mat 不是空的:

//[...]
#include <opencv2\opencv.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\core\core.hpp>
//[...]
using namespace cv;
[...]

Mat tmpImage= Mat(vecImagePx, false).reshape(1, 256);
imwrite( "Image_0.jpg", tmpImage ); // Works fine
bool emptyImg=tmpImage.empty(); // Returns "false"

一旦应用任何过滤器或阈值,我就会收到错误:

medianBlur(tmpImage, tmpImage, 3); // Would give error
threshold(tmpImage, tmpImage, 128, 255, THRESH_BINARY); // Would give error

错误信息: ModulatedImaging.exe 中 0x7c812fd3 处未处理的异常:Microsoft C++ 异常:内存位置 0x0011bc14 处的 cv::Exception.. 此外,根据 Visual Studio,指向 data、dataend 等的指针现在是 0.0000 &lt;Bad ptr.&gt;

但是,使用相同的方法从随机值创建一个 Mat 效果很好。尽管如此,将tmpImage 分配给R2 会产生与上述相同的错误:

Mat R2 = Mat(256, 256, CV_8UC1);
randu(R2, Scalar::all(0), Scalar::all(255));
medianBlur(R2, R2, 3); // Works fine
threshold(R2, R2, 128, 255, THRESH_BINARY); // Works fine

Mat tmpImage= Mat(vecImagePx, false).reshape(1, 256); // Works fine
imwrite( "Image_0.jpg", tmpImage ); // Works fine
R2=tmpImage; // Works fine
medianBlur(R2, R2, 3); // Gives error
threshold(R2, R2, 128, 255, THRESH_BINARY); // Gives error

我也有例如尝试了从std::vector&lt;int&gt;Mat 的以下转换,但是 jpg.-image 导致错误的条纹并且过滤器也无法正常工作:

cv::Mat tmpImage(256,256,CV_8UC1,&vecImagePx.front()); // results in wrong stripes

我可以做些什么来避免错误消息?

【问题讨论】:

【参考方案1】:

与此同时,我找到了解决方案:Mat tmpImage数据类型 不适合使用所描述的过滤器!使用int type=tmpImage.type(); 和下表我发现tmpImage mat 的类型是CV_8UC3。但是,R2 的类型是 CV_8U1

使用tmpImage.convertTo(tmpImage,CV_8UC1);tmpImage的数据类型转换为CV_8U1解决了所有问题!

这是我用来将类型整数分配给某种数据类型的表:

*+--------+----+----+----+----+------+------+------+------+
|        | C1 | C2 | C3 | C4 | C(5) | C(6) | C(7) | C(8) |
+--------+----+----+----+----+------+------+------+------+
| CV_8U  |  0 |  8 | 16 | 24 |   32 |   40 |   48 |   56 |
| CV_8S  |  1 |  9 | 17 | 25 |   33 |   41 |   49 |   57 |
| CV_16U |  2 | 10 | 18 | 26 |   34 |   42 |   50 |   58 |
| CV_16S |  3 | 11 | 19 | 27 |   35 |   43 |   51 |   59 |
| CV_32S |  4 | 12 | 20 | 28 |   36 |   44 |   52 |   60 |
| CV_32F |  5 | 13 | 21 | 29 |   37 |   45 |   53 |   61 |
| CV_64F |  6 | 14 | 22 | 30 |   38 |   46 |   54 |   62 |
+--------+----+----+----+----+------+------+------+------+

【讨论】:

以上是关于从 std::vector<int> 模糊 Mat 导致的错误指针:cv::Exception的主要内容,如果未能解决你的问题,请参考以下文章

对“std::vector<int, std::allocator<int>>”类型空指针的引用绑定

运行时错误:引用绑定到“std::vector<int, std::allocator<int>>”类型的空指针 (stl_vector.h)

运行时错误:引用绑定到“std::vector<int, std::allocator<int> >”类型的空指针 (stl_vector.h)

如何将std :: vector的大小作为int?

创建 boost::tuple<std::string, std::string, int> 和 std::vector<int> 的映射

std::vector<QString,int*> 的奇怪行为