OpenCV 中的五角矩阵
Pentadiagonal Matrix in OpenCV
我正在尝试在 VisualStudio 中使用 c++ 和 opencv 实现活动轮廓模型算法。
我在创建五对角矩阵时遇到问题,该矩阵的五个主对角线在矩阵的其余部分具有值和零。
我已经在 MatLab 中实现了这个,结果是这样的:
K = diag(repmat(a,1,n));
K = K + diag(repmat(b,1,n-1),1) + diag(repmat(b,1,n-1),-1)...
+ diag(b,n-1) + diag(b,-n+1);
K = K + diag(repmat(c,1,n-2),2) + diag(repmat(c,1,n-2),-2)...
+ diag([c c],n-2) + diag([c c],-n+2);
如何在 opencv 中做同样的事情?
谢谢!
您可以像下面的代码一样包装 Matlab 函数 repmat
和 diag
。
然后你就可以像在Matlab中一样编写OpenCV代码了。唯一的区别是您不能使用 [c c]
连接 2 个矩阵,但您应该使用 repmat(c, 2, 1)
,或 repmat(c,1,2)
连接 [c; c]
。
代码:
#include <opencv2\opencv.hpp>
using namespace cv;
Mat repmat(const Mat& src, int nx, int ny)
{
return repeat(src, nx, ny);
}
Mat diag(const Mat& src, int k=0)
{
// src must be a row or column matrix
//CV_Assert(src.rows == 1 || src.cols == 2);
int n = src.rows * src.cols;
Mat1d _src;
src.convertTo(_src, CV_64F);
// Create output matrix of correct dimension
int dim = n + abs(k);
Mat1d _dst(dim, dim, double(0.0));
// Select the ranges where to put src data
Range rrows;
Range rcols;
if (k >= 0)
{
rrows = Range(0, n);
rcols = Range(k, k+n);
}
else
{
rrows = Range(-k, -k + n);
rcols = Range(0, n);
}
// Create square n x n submatrix
Mat1d sub(_dst(rrows, rcols));
// Put data on the diagonal of the submatrix
for (int i = 0; i < n; ++i)
{
sub(i, i) = _src(i);
}
Mat dst;
_dst.convertTo(dst, src.type());
return dst;
}
int main()
{
Mat a;
Mat b;
Mat c;
int n;
// ... init a, b, c, n
Mat K;
K = diag(repmat(a, 1, n));
K = K + diag(repmat(b, 1, n - 1), 1) + diag(repmat(b, 1, n - 1), -1) + diag(b, n - 1) + diag(b, -n + 1);
K = K + diag(repmat(c, 1, n - 2), 2) + diag(repmat(c, 1, n - 2), -2) + diag(repmat(b, 2, 1), n - 2) + diag(repmat(b, 2, 1), -n + 2);
return 0;
}
我正在尝试在 VisualStudio 中使用 c++ 和 opencv 实现活动轮廓模型算法。 我在创建五对角矩阵时遇到问题,该矩阵的五个主对角线在矩阵的其余部分具有值和零。 我已经在 MatLab 中实现了这个,结果是这样的:
K = diag(repmat(a,1,n));
K = K + diag(repmat(b,1,n-1),1) + diag(repmat(b,1,n-1),-1)...
+ diag(b,n-1) + diag(b,-n+1);
K = K + diag(repmat(c,1,n-2),2) + diag(repmat(c,1,n-2),-2)...
+ diag([c c],n-2) + diag([c c],-n+2);
如何在 opencv 中做同样的事情? 谢谢!
您可以像下面的代码一样包装 Matlab 函数 repmat
和 diag
。
然后你就可以像在Matlab中一样编写OpenCV代码了。唯一的区别是您不能使用 [c c]
连接 2 个矩阵,但您应该使用 repmat(c, 2, 1)
,或 repmat(c,1,2)
连接 [c; c]
。
代码:
#include <opencv2\opencv.hpp>
using namespace cv;
Mat repmat(const Mat& src, int nx, int ny)
{
return repeat(src, nx, ny);
}
Mat diag(const Mat& src, int k=0)
{
// src must be a row or column matrix
//CV_Assert(src.rows == 1 || src.cols == 2);
int n = src.rows * src.cols;
Mat1d _src;
src.convertTo(_src, CV_64F);
// Create output matrix of correct dimension
int dim = n + abs(k);
Mat1d _dst(dim, dim, double(0.0));
// Select the ranges where to put src data
Range rrows;
Range rcols;
if (k >= 0)
{
rrows = Range(0, n);
rcols = Range(k, k+n);
}
else
{
rrows = Range(-k, -k + n);
rcols = Range(0, n);
}
// Create square n x n submatrix
Mat1d sub(_dst(rrows, rcols));
// Put data on the diagonal of the submatrix
for (int i = 0; i < n; ++i)
{
sub(i, i) = _src(i);
}
Mat dst;
_dst.convertTo(dst, src.type());
return dst;
}
int main()
{
Mat a;
Mat b;
Mat c;
int n;
// ... init a, b, c, n
Mat K;
K = diag(repmat(a, 1, n));
K = K + diag(repmat(b, 1, n - 1), 1) + diag(repmat(b, 1, n - 1), -1) + diag(b, n - 1) + diag(b, -n + 1);
K = K + diag(repmat(c, 1, n - 2), 2) + diag(repmat(c, 1, n - 2), -2) + diag(repmat(b, 2, 1), n - 2) + diag(repmat(b, 2, 1), -n + 2);
return 0;
}