2014-03-24 3 views
1

나는 n x n 행렬을 형성하는 여러 개의 방향에서 하나의 알고리즘을 수행해야하는 mat을 가지고있다.데이터를 변경하지 않고 매트 해석을 변경할 수 있습니까? (미러링해라.)

나는 mat을 고전적으로 y = [0..n]과 x = [0..n]로 반복하여 그 위에 몇 가지 기능을 적용하려고한다.

그렇다면 mat y = [n..0] 및 x = [n..0]을 루프해야합니다. 기본적으로 "다른 방법"입니다. 기본적으로 모든 4 방향에서 mat에 접근해야합니다 (예 : 마지막 하나 y = [0..n]/x = [n..0] 및 y = [n..0]/x = [0 .. N])

지금 내가 코드 네 번하지만 적용해야하는 작업을 복제하지 않으려는 단순히

void apply(cv::Mat & mat, uint xStart, uint xEnd, uint xDirection, uint yStart, uint yEnd, uint yDirection); 

때문에 같은 하나 개의 함수로 최소, 최대 및 방향 값을 전달보다 복잡 알고리즘이 앞을 내다 보겠습니다.

이제 데이터의 헤더 해석을 변경하여 데이터를 변경하지 않고 주어진 매트릭스를 변형 할 수 있는지 생각했습니다. 그런 다음 apply을 항상 같은 매개 변수로 호출 할 수 있습니다.

cv :: transform, cv :: transpose 등의 작업이 있지만 데이터 복사본을 만들지 만 원하지 않습니다.

+0

데이터를 어떻게 저장하고 있습니까? X와 Y 방향 모두에 대해 순방향과 역방향의 두 종류의 반복자를 만들 수 있습니까? 그러면 가능한 모든 방법으로 자유롭게 조합 할 수 있습니다. –

+0

@RSahu 데이터를 cv :: Mat에 저장하려고합니다. 그 동안 데이터에 액세스 할 수 있지만 상당한 메모리 오버 헤드를 생성하는 매트 뷰를 만들었습니다. – Samuel

+0

나는'opencv' 태그를 놓쳤습니다.나는 자신의'Mat' 클래스를 커스터마이즈 할 수있는 방법을 생각하고있었습니다. 나는 opencv에 대해 많이 모른다. 내 사과. –

답변

1

아니요. 불가능합니다. 메모리 저장 공간에 대해 생각하면 실제로는 간단합니다. 메모리 저장은 선형 (행 방향)이며 데이터를 변경하지 않고 선형 메모리를 따라 이동하기위한 단계 만 변경할 수 있습니다. 즉, 형식을 바꿀 수 있고 변경할 수 있음을 의미합니다.

조 변경 및 반사 조작으로 인해 데이터가 변경됩니다. 이것은 여전히 ​​4 가지 검색 방향에 대해 별도의 알고리즘을 작성하고 실행하는 것보다 더 빠르고 명확합니다. 물론 검색 결과를 저장하는 것은 해석이 Mat 구성에 따라 달라지기 때문에 번거로운 작업이 될 수 있습니다. 그래서, 더 이상의 합병증을 피하기 위해, 제 조언은 4 개의 별도의 알고리즘을 작성하는 것입니다.

1

나는 모든 방향에 대한 추상화 않는 MatView 클래스를 만들었습니다 :이 메모리의 복잡성에 큰 영향이라고 생각하는 방법 이제까지

/** 
* Allows to create different views of mat with direct access. 
* Supports inversion of axis so that iteration of a row is a col indeed a switch 
* Possible optimization: Remove switches, introduce compile time constants 
*/ 
template<typename T> 
class MatView 
{ 
public: 

    MatView(cv::Mat & mat, int rowStart, int rowEnd, int colStart, int colEnd, bool switchAxes = false) : 
     m_mat(mat), m_rowStart(rowStart), m_rowEnd(rowEnd), m_colStart(colStart), m_colEnd(colEnd), m_switchedAxes(switchAxes) 
    { 
     m_rowDirection = rowStart < rowEnd? 1: -1; 
     m_colDirection = colStart < colEnd? 1: -1; 
    } 

    T & at(int rowY, int colX) 
    { 
     // Project the data 

     auto finalRow = m_rowStart + rowY * m_rowDirection; 
     auto finalCol = m_colStart + colX * m_colDirection; 

     if(m_switchedAxes == false) 
     { 
      return m_mat.at<T>(finalRow,finalCol); 
     } 
     else 
     { 
      return m_mat.at<T>(finalCol,finalRow); 
     } 
    } 

    const T & at(int rowY, int colX) const 
    { 
     auto finalRow = m_rowStart + rowY * m_rowDirection; 
     auto finalCol = m_colStart + colX * m_colDirection; 

     if(m_switchedAxes == false) 
     { 
      return m_mat.at<T>(finalRow,finalCol); 
     } 
     else 
     { 
      return m_mat.at<T>(finalCol,finalRow); 
     } 
    } 

protected: 

    cv::Mat m_mat; 

    int m_rowStart; 
    int m_rowEnd; 

    int m_colStart; 
    int m_colEnd; 

    int m_rowDirection; 
    int m_colDirection; 

    bool m_switchedAxes; 
}; 

을, 또한 조건은 분기 예측에 막대한 영향을 미칠 수 있습니다 .

sizeof(cv::Mat) 96로 동일하고 sizeof(MatView)가 128 에 동일하지만 나의 현재 Mat 데이터가 실제로 단지 4*4* sizeof(int) (64 비트로 컴파일 할 때 내 INT의 크기는 4 동안).

물론 어쨌든 cv::Mat의 선형 메모리 액세스가 끊어 지지만 원본 Mat은 임의의 방식으로 (반복 데이터가 반복되지 않음) 액세스됩니다.

음,이 솔루션에는 만족하지 않지만 알고리즘 코드는 실제로 복제되지 않습니다.

관련 문제