简体   繁体   中英

Bad pointers by blurring Mat from std::vector<int>: cv::Exception

I am new to openCV and have experimented for several hours but without success so I hope you can give me some advice. I am trying to detect circle centers in images as described here: https://solarianprogrammer.com/2015/05/08/detect-red-circles-image-using-opencv/

I am using C++ in Visual Studio 10 on Windows XP and OpenCV 2.2.0.

My images come in std::shared_ptr<CImg<double>> format showing black dots on white background. Then I convert them to std::vector<int> vecImagePx of length 65536 (256 rows/columns) with data values between 0 and 255. I have verified that everything is ok.

Next, I convert the vector to a Mat, which is done correctly. I know this from looking at the jpg-file, also pointers to datastart and dataend and data are not shown to be bad pointers according to Visual Studio 2010 but seem to have valid adresses. Also, the Mat is not empty:

//[...]
#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"

As soon, as I apply any filter or threshold, I get errors:

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

Error Message: Unhandled exception at 0x7c812fd3 in ModulatedImaging.exe: Microsoft C++ exception: cv::Exception at memory location 0x0011bc14.. Additionally, the pointers to data, dataend etc. are now 0.0000 <Bad ptr.> according to Visual Studio.

However, creating a Mat from random values, using the same methods, works pretty fine. Nevertheless, assigning tmpImage to R2 gives the same error as described above:

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

I have also eg tried the following conversion from std::vector<int> to Mat , but there the jpg.-image results in wrong stripes and the filters do not work as well:

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

What can I do to avoid the error messages?

In the meantime, I found the solution: The data type of Mat tmpImage is not correct for using the described filters! Using int type=tmpImage.type(); and the table below I found out that the type of tmpImage mat is CV_8UC3 . However, the type of R2 is CV_8U1 .

Converting the data type of tmpImage to CV_8U1 using tmpImage.convertTo(tmpImage,CV_8UC1); solved all problems!

This is the table I used to assign the type integer to a certain data type:

*+--------+----+----+----+----+------+------+------+------+
|        | 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 |
+--------+----+----+----+----+------+------+------+------+

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM