只复制C++OpenCV中findNonZero函数中Mat的行索引



我正在尝试将MATLAB代码转换为C++。在MATLAB中,我使用find函数来获得向量的索引,然后将这些索引复制到其他变量。例如:

idx = find(A>s);
B = idx;
% A, idx, and B are vectors; s is a scalar

在C++OpenCV(C++14/OpenCV 3.4.10(中,我知道我可以使用findNonZero函数,但它同时返回行和列索引:

double s;
Mat1d A;
Mat1i B;
Mat idx;
.
.
.
findNonZero(A>s, idx);

我不知道如何直接只复制行索引(不使用for循环(。我认为可以通过定义Mat2i idx并像这样使用mixChannels来完成:

Mat2i idx;
findNonZero(A>s, idx);
B = Mat1i::zeros(idx.size());
int from_to[] = {1, 0};
mixChannels(&idx, 1, &B, 1, from_to, 1);

然而,在运行findNonZero函数时,我得到了以下错误:

OpenCV(3.4.10(错误:断言失败(!fixedType((||((Mat*(obj(->type((==mtype(在cv::debug_build_guard::_OutputArray::create,中

但是如果我设置Mat idx,我在运行mixChannel函数时会得到另一个错误:

OpenCV(3.4.10(错误:cv::mixChannels,中的断言失败(j<nsrcs&&src[j].depth((==深度(

我不知道该怎么办。如有帮助,不胜感激。

MATLAB的find确定输入矩阵中值为非零的列主索引。如果您指定它的单一输出版本,这是正确的。如果您提供两个输出变量,则会生成输入中非零值的行和列位置。在您的示例中,您已经提供了find的单一输出版本,所以我将使用它。

OpenCV的cv::Mat将图像布置在主行中。我想你会喜欢主要指数行。如果是这样,由于cv::findNonZero同时输出行和列坐标,您必须自己循环输出坐标并创建行主索引。你不应该害怕在这里使用循环。事实上,cv::Mat上的for环路已针对快速访问进行了优化。因此:

Mat2i idx;
Mat1d A; // Define somewhere else
double s; // Define somewhere else
findNonZero(A > s, idx);
B = Mat1i::zeros(idx.total());
for (int i = 0; i < idx.total(); ++i) {
B.at<int>(i) = idx.at<Point>(i).y * A.cols + idx.at<Point>(i).x;
}

CCD_ 15将包含CCD_ 16中的行主索引。如果我误解了你的查询,只是想要非零值的行位置,那么它只是:

Mat2i idx;
Mat1d A; // Define somewhere else
double s; // Define somewhere else
findNonZero(A > s, idx);
B = Mat1i::zeros(idx.total());
for (int i = 0; i < idx.total(); ++i) {
B.at<int>(i) = idx.at<Point>(i).y;
}

请记住,您只在非零值上迭代,因此最糟糕的复杂情况是在非零值的位置上迭代。

相关内容

  • 没有找到相关文章

最新更新