在垫子读取期间发生 Segerror ,直到使用 ostream

Segerror occures during mat reading until ostream is used

本文关键字:ostream Segerror 读取      更新时间:2023-10-16

我有两个CV_32FC1垫flow[0]flow[1]这样生成的

 95         cv::gpu::BroxOpticalFlow bof(alpha, gamma, scale_factor, inner_iteratoins, outter_iterations, solver_iterations);
 96         bof(gpuFrame[0], gpuFrame[1], gpuFlow[0], gpuFlow[1]);
 97
 98         cv::Mat flow[2];
 99         for(int i=0; i<2; ++i) {
100                 gpuFlow[i].download(flow[i]);
101         }

仅当同时注释 115 行和 116 行时,才会在第 117 行发生分段错误。

105         cv::Size flow_size = flow[0].size();
106
107         std::size_t vertices_count = flow_size.width * flow_size.height;
108
109         std::list< int > vertices;
110         for(int j=0; j<flow_size.height; ++j) {
111                 const double * x_flow = flow[0].ptr<double>(j);
112                 const double * y_flow = flow[1].ptr<double>(j);
113
114                 for(int i=0; i<flow_size.width; ++i, ++x_flow, ++y_flow) {
115                         //std::cout << i << ' ' << j << std::endl;
116                         //std::cout << "|" << std::endl;
117                         if(norm(*x_flow, *y_flow) > eps) {
118                                 vertices.push_back(i + j*flow_size.width);
119                         }
120                 }
121         }

如果从命令行调用代码,则不返回任何内容。但是,当程序在 gdb 中执行时,会返回段错误代码。当 115 或 116 未注释时,一切都很好。

G++ 版本是 4.9.2。OpenCV 2.4.9 使用 CUDA 编译。使用 C++11 标志。

CV_32FC1float,而不是double

改变

const double * x_flow = flow[0].ptr<double>(j);
const double * y_flow = flow[1].ptr<double>(j);

const float * x_flow = flow[0].ptr<float>(j);
const float * y_flow = flow[1].ptr<float>(j);

将浮点内存解释为双倍内存意味着您正在读取每个像素的 2 倍内存块数。因此,如果下一个内存块不属于您的程序,您将走出图像内存并出现段错误。

您正在访问*x_flow, *y_flow 上的第 117 行中的元素。

如果你没有得到段错误,那么你"意外"访问了你自己程序的内存,但无论如何你不会从一开始就读取你想要读取的值。