我正在尝试将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;
}
请记住,您只在非零值上迭代,因此最糟糕的复杂情况是在非零值的位置上迭代。