逐行填充cv :: Mat调用函数?

时间:2017-01-21 10:47:19

标签: c++ opencv

我有这个方法:

//codeSize previously defined
void generateRow(cv::Mat1f &row){
  if(row.cols != codeSize || !row.isContinous() || row.rows!=1)
    return;
  //fill row somehow
}

我想这样称呼它:

cv::Mat1f mat(rows,cols);
for(size_t i=0; i<rows; i++)
  generateRow(mat.row(i));

但我收到此错误消息:

../EncoderManager.cpp:100:37: error: invalid initialization of non-const reference of type ‘cv::Mat1f& {aka cv::Mat_<float>&}’ from an rvalue of type ‘cv::Mat_<float>’

我该如何解决这个问题?

可能的解决方案:

for(size_t i=0; i<rows; i++){
  cv::Mat1f row(1,cols);
  generateRow(row);
  row.row(1).copyTo(mat.row(i));
}

这是唯一的解决方案吗?如果是这样,如果rows很大,这将是超级低效的!

原始代码:

调用方法:

encoder->encode(imgDesc,code);

该方法称为:

void Encoder::encode(cv::Mat1f &descriptors, cv::Mat1f &code){
    if(!checkCode(code) || !checkRows(code,1) || !checkDescriptors(descriptors)){
        throw std::runtime_error("wrong descriptors");
        return;
    }
    encode_(descriptors, code);
}

错误:

../EncoderManager.cpp: In member function ‘void EncoderManager::GenerateSampledCodes(cv::Mat1f&, int, const string&, const string&, const string&)’:
../EncoderManager.cpp:104:37: error: invalid initialization of non-const reference of type ‘cv::Mat1f& {aka cv::Mat_<float>&}’ from an rvalue of type ‘cv::Mat_<float>’
    encoder->encode(imgDesc,codes.row(i));
                                     ^
In file included from ../EncoderManager.hpp:11:0,
                 from ../EncoderManager.cpp:10:
../Encoder.hpp:21:7: note:   initializing argument 2 of ‘void Encoder::encode(cv::Mat1f&, cv::Mat1f&)’
  void encode(cv::Mat1f &descriptors, cv::Mat1f &code);

2 个答案:

答案 0 :(得分:1)

如果您想避免由于副本导致的开销,您可以在generateRow()内传递已分配的矩阵并在那里初始化(并可能将其重命名为initRow()以使其目的更清晰)。

然后您的代码可能如下所示:

void initRow(cv::Mat1f &mat, const size_t rowIdx){
  if(mat.cols != codeSize || !code.isContinous() || mat.rows <= rowIdx)
      return;

  //fill row somehow
}

...

cv::Mat1f mat(rows,cols);

for(size_t i=0; i<rows; i++)
  initRow(mat, i);

答案 1 :(得分:-1)

如果您不介意丢失cv::Mat1f界面,可以直接通过指针访问该行。这样您就不需要为行创建cv::Mat1f包装器了:

void generateRow(float * const row){
  // fill row[0], row[1], etc
}

generateRow(mat.ptr<float>(row_number));

另外,您是否尝试通过generateRow(cv::Mat1f(mat.row(i)))调用原始函数?我不认为它会复制任何数据,只需为行矩阵创建一个新的标题。