Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 填充cv::Mat是否逐行调用函数?_C++_Opencv - Fatal编程技术网

C++ 填充cv::Mat是否逐行调用函数?

C++ 填充cv::Mat是否逐行调用函数?,c++,opencv,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++) gener

我有这个方法:

//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));
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);
该方法称为:

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);
。/encodermanger.cpp:在成员函数“void encodermanger::GenerateSampledCodes(cv::Mat1f&,int,const string&,const string&,const string&)”中:
../encodermanger.cpp:104:37:错误:从“cv::Mat1f&{aka cv::Mat&}类型的右值初始化“cv::Mat&}”类型的非常量引用无效
编码器->编码(imgDesc,codes.row(i));
^
在../encodermanger.hpp:11:0中包含的文件中,
来自../encodermager.cpp:10:
../Encoder.hpp:21:7:注意:初始化'void Encoder::encode(cv::Mat1f&,cv::Mat1f&')的参数2
无效编码(cv::Mat1f和描述符,cv::Mat1f和代码);

如果您想避免由于复制而产生的开销,您可以将分配的矩阵传递到
generateRow()
中并在那里初始化它(并且可能将其重命名为
initRow()
,以使其用途更清楚)

那么您的代码可能如下所示:

cv::Mat1f mat(rows,cols);
for(size_t i=0; i<rows; i++)
  generateRow(mat.row(i));
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);
void initRow(cv::Mat1f和mat,const size\u t rowIdx){

如果(mat.cols!=codeSize | | |!code.iscontinuous()| | mat.rows如果您不介意丢失
cv::Mat1f
接口,您可以通过指针直接访问该行。这样,您就不需要为行创建
cv::Mat1f
包装器:

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

generateRow(mat.ptr<float>(row_number));
void generateRow(浮点*常量行){
//填充第[0]行、第[1]行等
}
发电机(材料ptr(排号));

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

您可以将指向
cv::Mat1f mat
的指针或引用以及行索引传递到
generateRow
,以避免不必要的复制。@alexisrozhkov您能写一个答案吗?我不确定我是否理解您的解决方案我尝试了您的代码,并且t对我来说是正确的。你能发布一个吗?哪里定义了
code
?它是一个全局变量吗?很抱歉@Miki,我刚刚发布了这一小部分代码,因为其余部分非常复杂,我不明白它怎么可能编译并对你有效。顺便问一下,你同意我们不能用abo代码逐行填充矩阵吗ve?事实上,我正在试图理解你如何无法填充矩阵,因为这应该可以正常工作;)我不明白这会有什么帮助。在
initRow
内部,副本将涉及
//以某种方式填充行
。阅读更多信息您可能应该以某种方式提供
填充行的实现,因为这似乎与您的问题有关。但我现在认为它不一定涉及副本-您可以直接写入
mat
条目,而无需创建临时行。如前所述,使用
at
并直接逐个元素填充效率极低。首先,这超出了您的问题范围,即逐行填充CV mat。其次-现在您可以在分配临时行之间进行选择每一次,都会复制或复制到完整矩阵的相应行中,或者按照我建议的方式进行元素填充。考虑到分配的开销,我会惊讶地发现创建临时结构会更快。如果应用程序中的性能至关重要,您可以始终直接使用矩阵数据,但这并不清楚从原来的问题开始。谢谢你的回答。首先,我刚刚将所有内容从
cv::Mat
迁移到
cv::Mat1f
,所以不,我不能将其更改回
cv::Mat
:D。此外,使用指针会使
generateRow
中使用的整个
Mat
结构松动。最后,如果调用
generateR>ow(cv::Mat1f(mat.row(i))
我认为您可以动态创建一个传递给
GeneratorRow
的对象,并且
mat.row(i)
不会被修改。我没有提到
cv::mat
。然后,创建
cv::Mat1f
包装器是您的解决方案,因为您创建了函数需要的对象,而它不会创建副本(因此动态创建的
cv::Mat1f
对象实际上是您所在行的别名)。
void generateRow(float * const row){
  // fill row[0], row[1], etc
}

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