OpenCv에서 MatND로 저장된 3D 데이터 큐브에서 2D Mat 오브젝트를 가져올 수 있습니까? 기본적으로 "mexopencv"를 사용하여 MexFile에 3D 행렬을 전달합니다. MxArray (prhs [0]). toMatND()를 사용하여 행렬을 MatND 객체로 변환합니다. 이제이 데이터 큐브를 세 번째 차원을 따라 cv :: Matrices의 벡터로 분리하려고합니다. 따라서이 2D 행렬에 대한 연산을 수행하여 세 번째 차원을 반복해야합니다. 필요에 따라 데이터 큐브를 분할하는 기능이 있습니까? 아니면 3D 데이터 큐브의 2D 하위 행렬 포인터를 가져 오는 방법일까요?3D 매트를 2D 매트 벡터로 분할 opencv
편집 :이 코드는 mexopencv를 사용하여 Matlab 입력 인수를 MatND 배열로 변환하는 코드입니다. 3D 데이터 코드를 2D 행렬의 벡터로 분할하는 @ chappjc의 방법을 구현했습니다. 사실 x와 y 치수가 바뀌어도 모든 것이 좋습니다.
#include "mexopencv.hpp"
#include <iostream>
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
// Check arguments
if (nlhs!=1 || nrhs!=1)
mexErrMsgIdAndTxt("myfunc:invalidArgs", "Wrong number of arguments");
// 1) Convert MxArray to cv::Mat
cv::MatND matnd = MxArray(prhs[0]).toMatND();
// Extract planes from matrix
int dims[] = { matnd.size[0],matnd.size[1],matnd.size[2]};
std::vector<cv::Mat> matVec;
for (int p = 0; p < dims[2]; ++p) {
double *ind = (double*)matnd.data + p * dims[0] * dims[1]; // sub-matrix pointer
matVec.push_back(cv::Mat(2, dims, CV_64F, ind).clone()); // clone if mnd goes away
}
std::cout << "\nmatVec[0]:\n" << matVec[0] << std::endl;
std::cout << "\nmatVec[1]:\n" << matVec[1] << std::endl;
// Here I will do some stuff with the 2D submatrices from matVec
// ...
// 2) Here I want to pass the 3D matrix back to Matlab
// I only know how to convert cv::Mat back to mxArray* using mexopencv:
plhs[0] = MxArray(matnd);
}
두 번째 편집. 실제로 치수가 "matVec"으로 전환된다는 사실은 매우 성가시다. 누구든지 더 나은 해결책이 있습니까?
이
작은 [5 × 4 × 2 실시 예의 출력 :>> b
b(:,:,1) =
1 6 11 16
2 7 12 17
3 8 13 18
4 9 14 19
5 10 15 20
b(:,:,2) =
101 106 111 116
102 107 112 117
103 108 113 118
104 109 114 119
105 110 115 120
>> c = cv.myFunc(b)
matVec[0]:
[1, 2, 3, 4, 5;
6, 7, 8, 9, 10;
11, 12, 13, 14, 15;
16, 17, 18, 19, 20]
matVec[1]:
[101, 102, 103, 104, 105;
106, 107, 108, 109, 110;
111, 112, 113, 114, 115;
116, 117, 118, 119, 120]
c(:,:,1) =
1 6 11 16
2 7 12 17
3 8 13 18
4 9 14 19
5 10 15 20
c(:,:,2) =
101 106 111 116
102 107 112 117
103 108 113 118
104 109 114 119
105 110 115 120
+1 - 난 내 [매트릭스]에서 웃었다 (http://en.wikipedia.org/wiki/The_Matrix) 기준 :) – rayryeng
@rayryeng 방금 내 머리에 터졌다. :). 다시 : 답변, 또한 MATLAB의':'와 비슷한 'Range' 함수가 있지만 그것을 사용한 적이 없습니다. 또한 일반적으로'cv : Rect'를 통해 ROI를 사용할 수는 있지만 2 차원이라고 생각합니다. 어쨌든, 나는 다차원의'Mat's을 자주 사용하지 않지만'MatND''t typedef에 대해서 알고 있습니다. – chappjc
답변 해 주셔서 감사합니다. 2D 하위 행렬의 포인터를 얻는 방법은 다음과 같습니다 :). mexopencv 내부에서 일어나는 일은 여전히 이상 할지라도 : cv :: MatND와 prhs [0]). toMatND()를 사용하는 것은 더 이상 사용되지 않습니다. Matlab에서 mexopencv로 큰 3D 행렬을 전달할 때 충돌이 발생하기 때문에 toMatND prhs [0]). toMat() (cv :: Mat는 세 번째 차원을 "채널"로 저장하고 최대 채널 번호는 4입니다. – mcExchange