如何以优雅的方式使用 OpenCV、c++ 检索 even/odd 索引中的值?
How to retrieve values in even/odd indices using OpenCV, c++ in an elegant way?
考虑一下,我有以下矩阵
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
我想在不使用 for 循环的情况下检索偶数索引中的值(x 和 y 索引都是偶数)。
0 2
8 10
我有大尺寸图像(许多 5000*5000+ 灰度矩阵)。使用 for 循环似乎不是最好的方法。我想听听是否有比 for 循环更好的方法。
我尝试使用下面的掩码,然后进行操作但效率不高,因为我需要进行 4*n^2 乘法而不是 n^2(假设原始图像为 2n*2n)
1 0 1 0
0 0 0 0
1 0 1 0
0 0 0 0
请注意,我对矩阵进行了多项操作。感谢任何帮助。
提前致谢,
您可以删除无用的行和列,并在原始矩阵大小的一半大小的矩阵上工作。
您可以使用 resize
函数轻松做到这一点,最近插值:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char **argv)
{
Mat1b mat = (Mat1b(4,4) << 0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11,
12, 13, 14, 15);
Mat1b res;
resize(mat, res, Size(0, 0), 0.5, 0.5, INTER_NEAREST);
cout << "Mat:" << endl << mat << endl << endl;
cout << "Res:" << endl << res << endl;
return 0;
}
那么res
中的值就是你需要的索引处的值:
Mat:
[0, 1, 2, 3;
4, 5, 6, 7;
8, 9, 10, 11;
12, 13, 14, 15]
Res:
[0, 2;
8, 10]
为了将值恢复到原始位置,您可以使用具有合适模式的 Kronecker 产品(在 OpenCV 中不可用,但可以 )。这将产生:
Mat:
[0, 1, 2, 3;
4, 5, 6, 7;
8, 9, 10, 11;
12, 13, 14, 15]
Res:
[0, 2;
8, 10]
Res Modified:
[1, 3;
9, 11]
Restored:
[1, 0, 3, 0;
0, 0, 0, 0;
9, 0, 11, 0;
0, 0, 0, 0]
代码:
#include <opencv2/opencv.hpp>
#include <algorithm>
#include <iostream>
using namespace cv;
using namespace std;
Mat kron(const Mat A, const Mat B)
{
CV_Assert(A.channels() == 1 && B.channels() == 1);
Mat1d Ad, Bd;
A.convertTo(Ad, CV_64F);
B.convertTo(Bd, CV_64F);
Mat1d Kd(Ad.rows * Bd.rows, Ad.cols * Bd.cols, 0.0);
for (int ra = 0; ra < Ad.rows; ++ra)
{
for (int ca = 0; ca < Ad.cols; ++ca)
{
Kd(Range(ra*Bd.rows, (ra + 1)*Bd.rows), Range(ca*Bd.cols, (ca + 1)*Bd.cols)) = Bd.mul(Ad(ra, ca));
}
}
Mat K;
Kd.convertTo(K, A.type());
return K;
}
int main(int argc, char **argv)
{
Mat1b mat = (Mat1b(4, 4) << 0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11,
12, 13, 14, 15);
Mat1b res;
resize(mat, res, Size(0, 0), 0.5, 0.5, INTER_NEAREST);
cout << "Mat:" << endl << mat << endl << endl;
cout << "Res:" << endl << res << endl << endl;
// Work on Res
res += 1;
cout << "Res Modified:" << endl << res << endl << endl;
// Define the pattern
Mat1b pattern = (Mat1b(2,2) << 1, 0,
0, 0);
// Apply Kronecker product
Mat1b restored = kron(res, pattern);
cout << "Restored:" << endl << restored << endl << endl;
return 0;
}
考虑一下,我有以下矩阵
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
我想在不使用 for 循环的情况下检索偶数索引中的值(x 和 y 索引都是偶数)。
0 2
8 10
我有大尺寸图像(许多 5000*5000+ 灰度矩阵)。使用 for 循环似乎不是最好的方法。我想听听是否有比 for 循环更好的方法。
我尝试使用下面的掩码,然后进行操作但效率不高,因为我需要进行 4*n^2 乘法而不是 n^2(假设原始图像为 2n*2n)
1 0 1 0
0 0 0 0
1 0 1 0
0 0 0 0
请注意,我对矩阵进行了多项操作。感谢任何帮助。
提前致谢,
您可以删除无用的行和列,并在原始矩阵大小的一半大小的矩阵上工作。
您可以使用 resize
函数轻松做到这一点,最近插值:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char **argv)
{
Mat1b mat = (Mat1b(4,4) << 0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11,
12, 13, 14, 15);
Mat1b res;
resize(mat, res, Size(0, 0), 0.5, 0.5, INTER_NEAREST);
cout << "Mat:" << endl << mat << endl << endl;
cout << "Res:" << endl << res << endl;
return 0;
}
那么res
中的值就是你需要的索引处的值:
Mat:
[0, 1, 2, 3;
4, 5, 6, 7;
8, 9, 10, 11;
12, 13, 14, 15]
Res:
[0, 2;
8, 10]
为了将值恢复到原始位置,您可以使用具有合适模式的 Kronecker 产品(在 OpenCV 中不可用,但可以
Mat:
[0, 1, 2, 3;
4, 5, 6, 7;
8, 9, 10, 11;
12, 13, 14, 15]
Res:
[0, 2;
8, 10]
Res Modified:
[1, 3;
9, 11]
Restored:
[1, 0, 3, 0;
0, 0, 0, 0;
9, 0, 11, 0;
0, 0, 0, 0]
代码:
#include <opencv2/opencv.hpp>
#include <algorithm>
#include <iostream>
using namespace cv;
using namespace std;
Mat kron(const Mat A, const Mat B)
{
CV_Assert(A.channels() == 1 && B.channels() == 1);
Mat1d Ad, Bd;
A.convertTo(Ad, CV_64F);
B.convertTo(Bd, CV_64F);
Mat1d Kd(Ad.rows * Bd.rows, Ad.cols * Bd.cols, 0.0);
for (int ra = 0; ra < Ad.rows; ++ra)
{
for (int ca = 0; ca < Ad.cols; ++ca)
{
Kd(Range(ra*Bd.rows, (ra + 1)*Bd.rows), Range(ca*Bd.cols, (ca + 1)*Bd.cols)) = Bd.mul(Ad(ra, ca));
}
}
Mat K;
Kd.convertTo(K, A.type());
return K;
}
int main(int argc, char **argv)
{
Mat1b mat = (Mat1b(4, 4) << 0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11,
12, 13, 14, 15);
Mat1b res;
resize(mat, res, Size(0, 0), 0.5, 0.5, INTER_NEAREST);
cout << "Mat:" << endl << mat << endl << endl;
cout << "Res:" << endl << res << endl << endl;
// Work on Res
res += 1;
cout << "Res Modified:" << endl << res << endl << endl;
// Define the pattern
Mat1b pattern = (Mat1b(2,2) << 1, 0,
0, 0);
// Apply Kronecker product
Mat1b restored = kron(res, pattern);
cout << "Restored:" << endl << restored << endl << endl;
return 0;
}