gpt4 book ai didi

c++ - 从C++ OpenCV中的findNonZero函数仅复制Mat的行索引

转载 作者:行者123 更新时间:2023-12-02 10:10:38 29 4
gpt4 key购买 nike

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

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) Error: Assertion failed (!fixedType() || ((Mat*)obj)->type() == mtype) in cv::debug_build_guard::_OutputArray::create,


但是,如果我设置 Mat idx,则在运行 mixChannel函数时出现另一个错误:

OpenCV(3.4.10) Error: Assertion failed (j < nsrcs && src[j].depth() == depth) in cv::mixChannels,


我不确定该怎么办。任何帮助表示赞赏。

最佳答案

MATLAB的find确定列-主要索引,这些索引的值在输入矩阵中为非零值。如果指定单个输出版本,则为true。如果提供两个输出变量,则将生成输入中非零值的行和列位置。在您的示例中,您提供了find的单个输出版本,因此我将对此进行处理。
OpenCV的cv::Mat将图像布置在行主要中。我假设您想要行优先索引。如果是这样,由于cv::findNonZero同时输出行和列坐标,因此您必须自己遍历输出坐标并创建行主要索引。您不必担心在这里使用循环。实际上,for上的cv::Mat循环已针对快速访问进行了优化。因此:

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;
}
B将在 cv::Mat1i中包含行优先索引。如果我误解了您的查询,只是想要非零值的行位置,那么就可以了:
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;
}
请记住,您仅在非零值上进行迭代,因此最坏的情况是在非零位置上进行迭代。

关于c++ - 从C++ OpenCV中的findNonZero函数仅复制Mat的行索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63698322/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com