OpenCV 학습 노트(10):MAT 대상의 데이터를 보는 세 가지 방법
64764 단어 OpenCV 학습 노트
이미지를 처리하는 과정에서 데이터를 보고 수정하는 것은 비교적 빈번한 작업이어야 한다.
공식 수첩에서 제시한 세 가지 방법을 말씀드리겠습니다.
첫 번째 방법: Mat 데이터 부분을 가리키는 포인터를 사용합니다.
코드는 다음과 같습니다.
1 Mat& ScanImageAndReduceC(Mat& I, const uchar* const table)
2 {
3 // accept only char type matrices
4 CV_Assert(I.depth() != sizeof(uchar));
5
6 int channels = I.channels();
7
8 int nRows = I.rows;
9 int nCols = I.cols * channels;
10
11 if (I.isContinuous())
12 {
13 nCols *= nRows;
14 nRows = 1;
15 }
16
17 int i,j;
18 uchar* p;
19 for( i = 0; i < nRows; ++i)
20 {
21 p = I.ptr(i);
22 for ( j = 0; j < nCols; ++j)
23 {
24 p[j] = table[p[j]];
25 }
26 }
27 return I;
28 }
11 줄은 isContinous 함수를 사용합니다. 그림의 줄마다 연속적이고, 한 줄의 줄 끝과 다음 줄의 시작 데이터 사이의 메모리 단원이 다른 데이터를 저장하지 않도록 하기 위해서입니다.이 함수가true로 되돌아오면, 우리는 그림을 1줄, row*col열의 데이터 형식으로 옮겨다닐 수 있습니다.
21 줄은 ptr 함수를 사용합니다. 0에서 시작하는 줄 번호를 나타내는 매개 변수를 받아들입니다.ptr의 반환값은 기본적으로 uchar* 또는 const uchar* (const 버전의 재부팅) 입니다.또한 ptr는 템플릿이 있어 ptr를 통해 type*와const type*의 반환값을 실현할 수 있다.이 반환 값은 지정한 줄 번호를 가리키는 바늘을 되돌려줍니다.ptr 방법으로 되돌아오는 바늘을 사용합니다. 그림의 모든 바이트 (또는 우리가 지정한 type 길이) 가 픽셀이 아니라, 그림의 모든 바이트 (9행 ncols의 정의에 주의하십시오.)
두 번째 방법: 교체기를 사용한다.
코드는 다음과 같습니다.
1 Mat& ScanImageAndReduceIterator(Mat& I, const uchar* const table)
2 {
3 // accept only char type matrices
4 CV_Assert(I.depth() != sizeof(uchar));
5
6 const int channels = I.channels();
7 switch(channels)
8 {
9 case 1:
10 {
11 MatIterator_ it, end;
12 for( it = I.begin(), end = I.end(); it != end; ++it)
13 *it = table[*it];
14 break;
15 }
16 case 3:
17 {
18 MatIterator_ it, end;
19 for( it = I.begin(), end = I.end(); it != end; ++it)
20 {
21 (*it)[0] = table[(*it)[0]];
22 (*it)[1] = table[(*it)[1]];
23 (*it)[2] = table[(*it)[2]];
24 }
25 }
26 }
27
28 return I;
29 }
MatIterator_Mat의 교체기입니다. 템플릿도 지원합니다.12행과 19행의 순환에서, 우리는 Mat의 begin과end 함수를 사용하여, 교체기가 각각 Mat 데이터 부분의 시작과 끝을 가리키도록 했다.begin과 end의 실현은 다음과 같다.
1 template inline MatIterator_<_tp> Mat::begin()
2 {
3 CV_DbgAssert( elemSize() == sizeof(_Tp) );
4 return MatIterator_<_tp>((Mat_<_tp>*)this);
5 }
6
7 template inline MatIterator_<_tp> Mat::end()
8 {
9 CV_DbgAssert( elemSize() == sizeof(_Tp) );
10 MatIterator_<_tp> it((Mat_<_tp>*)this);
11 it += total();
12 return it;
13 }
4행과 10행에 Mat < 가 사용되었음을 알 수 있습니다.tp> 유형, 이것은 Mat가 특정한 유형에 대한 템플릿으로 볼 수 있으며, 깊이 연구하지 않습니다.Mat_<_tp> 형식은 그림의 데이터를 조작하는 데 편리합니다.문서의 간단한 예를 들면 다음과 같습니다.
1 Mat M(100, 100, CV_8U);
2
3 Mat_<float>& M1 = (Mat_<float>&)M;
4
5 M1(99, 99) = 1.f
Mat_형식은 OpenCV 개발자가 괄호 조작부호를 다시 불러왔기 때문에 데이터를 쉽게 조작할 수 있습니다.우리 Mat 보자.유형 3채널 이미지 처리:
1 Mat_ img(240, 320, Vec3b(0, 255, 0));
2
3 for (int i = 0; i < 100; i++)
4 img(i, i) = Vec3b(255, 255, 255);
5 // ( )
6 for (int i = 0; i < img.rows; i++)
7 for (int j = 0; j < img.cols; j++)
8 img(i, j)[2] ^= (uchar)(i ^ j);
교체기의 조작 중 우리가 가장 자주 사용하는 것은++와 * 조작부호이다. 어떻게 실현되는지 살펴보자.
1 template inline _Tp& MatIterator_<_tp>::operator *() const { return *(_Tp*)(this->ptr); }
2
3 template inline MatIterator_<_tp> MatIterator_<_tp>::operator ++(int)
4 {
5 MatIterator_ b = *this;
6 MatConstIterator::operator ++();
7 return b;
8 }
9 // MatIterator_<_tp> MatConstIterator ,
10 inline MatConstIterator MatConstIterator::operator ++(int)
11 {
12 MatConstIterator b = *this;
13 *this += 1;
14 return b;
15 }
16 // += ,sliceStart sliceEnd , Mat
17 inline MatConstIterator& MatConstIterator::operator += (ptrdiff_t ofs)
18 {
19 if( !m || ofs == 0 )
20 return *this;
21 ptrdiff_t ofsb = ofs*elemSize;
22 ptr += ofsb;
23 if( ptr < sliceStart || sliceEnd <= ptr )
24 {
25 ptr -= ofsb;
26 seek(ofs, true);
27 }
28 return *this;
29 }
세 번째 방법:at방법 또는 Mat 사용유형
at 방법을 사용하면 지정한 데이터를 무작위로 접근할 수 있다.코드는 다음과 같습니다.
1 Mat& ScanImageAndReduceRandomAccess(Mat& I, const uchar* const table)
2 {
3 // accept only char type matrices
4 CV_Assert(I.depth() != sizeof(uchar));
5
6 const int channels = I.channels();
7 switch(channels)
8 {
9 case 1:
10 {
11 for( int i = 0; i < I.rows; ++i)
12 for( int j = 0; j < I.cols; ++j )
13 I.at(i,j) = table[I.at(i,j)];
14 break;
15 }
16 case 3:
17 {
18 Mat_ _I = I;
19
20 for( int i = 0; i < I.rows; ++i)
21 for( int j = 0; j < I.cols; ++j )
22 {
23 _I(i,j)[0] = table[_I(i,j)[0]];
24 _I(i,j)[1] = table[_I(i,j)[1]];
25 _I(i,j)[2] = table[_I(i,j)[2]];
26 }
27 I = _I;
28 break;
29 }
30 }
31
32 return I;
33 }
13줄에서at(i, j)를 사용했습니다. 이 방법은 i줄 j열의 데이터를 인용합니다.at 방법은 cv::Point 형식의 매개 변수를 전송할 수 있습니다. 예를 들어at (cv:Point2f (16,18).
우리는 18행에 Mat 를 사용했음을 알아차렸다.위에서 말한 바와 같이 템플릿과 무작위 접근을 지원하는 Mat류의 변형으로 볼 수 있다.Mat_임의 액세스를 지원하기 위해 괄호 연산자가 다시 로드되고 코드는 다음과 같습니다.
1 template inline const _Tp& Mat_<_tp>::operator ()(int i0, int i1) const
2 {
3 CV_DbgAssert( dims <= 2 && data &&
4 (unsigned)i0 < (unsigned)size.p[0] &&
5 (unsigned)i1 < (unsigned)size.p[1] &&
6 type() == DataType<_tp>::type );
7 return ((const _Tp*)(data + step.p[0]*i0))[i1];
8 }
다음으로 이동:http://www.cnphp6.com/archives/61006?utm_source=tuicool
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
OpenCV 학습 노트 07-스크롤 바 로 그림 크기 조절연습:스크롤 바 를 통 해 그림 의 크기 를 조절 합 니 다. 이 연습 이 실현 하고 자 하 는 기능 은 스크롤 바 를 제어 하여 그림 의 크기 를 조절 하 는 것 입 니 다.크기 가 너무 작 으 면 스크롤 바 를 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.