OpenCV C++正弦图案生成报错:Params类型转换问题求助
解决OpenCV SinusoidalPattern创建时的类型转换错误
我刚碰到过类似的问题,这是因为OpenCV的SinusoidalPattern::create方法需要的是一个智能指针类型的参数,而不是直接传栈上的Params实例。让我来帮你搞定这个问题:
问题原因
编译器报错的核心是:SinusoidalPattern::create方法的参数类型是cv::Ptr<cv::structured_light::SinusoidalPattern::Params>,但你传递的是一个普通的cv::structured_light::SinusoidalPattern::Params对象,编译器找不到这两种类型之间的自动转换,所以抛出了错误。
解决方案
有两种简单的方式可以解决这个类型不匹配的问题:
方式1:将已配置的Params包装成智能指针
先像你原来那样配置好Params实例,然后用cv::makePtr把它包装成Ptr<Params>,再传给create方法:
structured_light::SinusoidalPattern::Params params; params.width = 1080; params.height = 700; params.nbrOfPeriods = 5; params.setMarkers = true; params.horizontal = false; params.methodId = 2; params.shiftValue = static_cast<float>(2 * CV_PI / 3); params.nbrOfPixelsBetweenMarkers = 70; // 把params包装成智能指针 auto paramsPtr = cv::makePtr<structured_light::SinusoidalPattern::Params>(params); // 现在可以正常调用create了 Ptr<structured_light::SinusoidalPattern> sinus = structured_light::SinusoidalPattern::create(paramsPtr);
方式2:直接创建智能指针类型的Params
从一开始就用cv::makePtr创建Ptr<Params>,然后通过箭头操作符访问成员变量:
// 直接创建智能指针类型的Params auto params = cv::makePtr<structured_light::SinusoidalPattern::Params>(); params->width = 1080; params->height = 700; params->nbrOfPeriods = 5; params->setMarkers = true; params->horizontal = false; params->methodId = 2; params->shiftValue = static_cast<float>(2 * CV_PI / 3); params->nbrOfPixelsBetweenMarkers = 70; // 直接传params给create Ptr<structured_light::SinusoidalPattern> sinus = structured_light::SinusoidalPattern::create(params);
修改后的完整代码示例
这里是整合了方式2的完整代码,你可以直接替换原来的main函数部分:
#include <opencv2/highgui.hpp> #include <vector> #include <iostream> #include <fstream> #include <opencv2/core.hpp> #include <opencv2/core/utility.hpp> #include <opencv2/imgproc.hpp> #include <opencv2/calib3d.hpp> #include <opencv2/structured_light.hpp> #include <opencv2/phase_unwrapping.hpp> using namespace cv; using namespace std; int main(int argc, char **argv) { // 直接创建智能指针类型的Params auto params = makePtr<structured_light::SinusoidalPattern::Params>(); params->width = 1080; params->height = 700; params->nbrOfPeriods = 5; params->setMarkers = true; params->horizontal = false; params->methodId = 2; params->shiftValue = static_cast<float>(2 * CV_PI / 3); params->nbrOfPixelsBetweenMarkers = 70; String outputPatternPath = "C:/Users/ianco/Desktop/CPlusPlus_Programming"; String outputWrappedPhasePath = "C:/Users/ianco/Desktop/CPlusPlus_Programming"; String outputUnwrappedPhasePath = "C:/Users/ianco/Desktop/CPlusPlus_Programming"; Ptr<structured_light::SinusoidalPattern> sinus = structured_light::SinusoidalPattern::create(params); // Storage for patterns vector<Mat> patterns; //Generate sinusoidal patterns sinus->generate(patterns); cv::Mat blue, green, red; std::vector<cv::Mat> images(3); // OpenCV works natively with BGR ordering images.at(0) = patterns[0]; images.at(1) = patterns[1]; images.at(2) = patterns[2]; cv::Mat color; cv::merge(images, color); namedWindow("pattern", WINDOW_NORMAL); setWindowProperty("pattern", WND_PROP_FULLSCREEN, WINDOW_FULLSCREEN); imshow("pattern", color); waitKey(3000); }
额外说明
OpenCV的很多模块都使用Ptr智能指针来管理对象和配置参数,这样可以避免手动内存管理,同时支持多态特性。以后碰到类似的“no suitable user-defined conversion”错误,首先检查是否需要把普通对象包装成Ptr类型,通常用cv::makePtr就能解决。
内容的提问来源于stack exchange,提问作者Ian Coghill
相关产品推荐
相关产品推荐

