该情况出现场景:使用了一个第三方库文件(有源码),调用其中一个接口时出现该错误,查看代码发现其内部使用的CV_32FC1,查找相关资料https://blog.csdn.net/ricky90/article/details/52936646,根据该博主的经历,更改第三方库源码的CV_32FC1为CV_64FC1,重新编译库文件,调用该库文件的程序运行通过。
后续考虑不想更改第三方库源码,遂查找传入参数的问题,传入的是通过 cv::FileStorage读取到的yaml文件中的内参矩阵,后发现在程序运行系统中该函数获取的矩阵类型为CV_64FC1,而在库函数中将该值与库函数中定义的类型为CV_32FC1的变量相乘,所以报错。
通过convertTo函数转换数据类型解决,代码如下:
cv::FileStorage fs(_choose_file, cv::FileStorage::READ); if (!fs.isOpened()){ ROS_ERROR("[%s] Cannot open file calibration file '%s'", "calibration_tool", _choose_file.c_str()); } else{ fs["CameraExtrinsicMat"] >> CameraExtrinsicMat; fs["CameraMat"] >> camera_instrinsics_; fs["DistCoeff"] >> distortion_coefficients_; fs["ImageSize"] >> image_size_; fs["DistModel"] >> DistModel; //it's type is CV_32FC1 in .so lib, so make a convert camera_instrinsics_.convertTo(camera_instrinsics_, CV_32FC1); distortion_coefficients_.convertTo(distortion_coefficients_, CV_32FC1); }以下内容来自:https://docs.opencv.org/3.2.0/d1/dfb/intro.html
### Fixed Pixel Types. Limited Use of Templates Templates is a great feature of C++ that enables implementation of very powerful, efficient and yet safe data structures and algorithms. However, the extensive use of templates may dramatically increase compilation time and code size. Besides, it is difficult to separate an interface and implementation when templates are used exclusively. This could be fine for basic algorithms but not good for computer vision libraries where a single algorithm may span thousands lines of code. Because of this and also to simplify development of bindings for other languages, like Python, Java, Matlab that do not have templates at all or have limited template capabilities, the current OpenCV implementation is based on polymorphism and runtime dispatching over templates. In those places where runtime dispatching would be too slow (like pixel access operators), impossible (generic Ptr<> implementation), or just very inconvenient (saturate_cast<>()) the current implementation introduces small template classes, methods, and functions. Anywhere else in the current OpenCV version the use of templates is limited. Consequently, there is a limited fixed set of primitive data types the library can operate on. That is, array elements should have one of the following types: - 8-bit unsigned integer (uchar) - 8-bit signed integer (schar) - 16-bit unsigned integer (ushort) - 16-bit signed integer (short) - 32-bit signed integer (int) - 32-bit floating-point number (float) - 64-bit floating-point number (double) - a tuple of several elements where all elements have the same type (one of the above). An array whose elements are such tuples, are called multi-channel arrays, as opposite to the single-channel arrays, whose elements are scalar values. The maximum possible number of channels is defined by the CV_CN_MAX constant, which is currently set to 512. For these basic types, the following enumeration is applied: enum { CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6 }; Multi-channel (n-channel) types can be specified using the following options: - CV_8UC1 ... CV_64FC4 constants (for a number of channels from 1 to 4) - CV_8UC(n) ... CV_64FC(n) or CV_MAKETYPE(CV_8U, n) ... CV_MAKETYPE(CV_64F, n) macros when the number of channels is more than 4 or unknown at the compilation time.