programming/Image Processing

OpenCV로 배우는 영상처리 및 응용:: 3장

krystalS2ee 2020. 6. 25. 14:20

OpenCV 로 배우는 영상 처리 및 응용 <3 OpenCV 의 기본 자료 구조>

 

연습문제

 

 

 

 

 

1. 데이터를 저장하고 다루는 자료 구조의 차원에서 매트릭스와 벡터의 차이는 무엇인가?

 

-벡터 : 동일한 유형의 데이터로 구성되어 있는 1차원 데이터 구조

 

-매트릭스: 동일한 유형의 2차원 데이터 구조

 

 

 

 

 

2. 클래스(class)의 정의는 무엇이며, 구조체와 큰 차이는 무엇인가?

 

-클래스란 동일한 속성을 갖는 객체들의 집합으로 하나의 데이터 타입이며, 함수를 포함하지 않는 구조체와 달리 클래스는 함수도 포함할 수 있다.

 

 

 

 

 

3. Point_ 클래스와 Size_ 클래스의 세부 자료형에 대해서 기술하고, 객체 선언을 하시오.

 

Point_ : Point2i(Point), Point2I, Point2f, Point2d 자료형이 있다.

Size_ : Size2i(Size), Size2I, Size2f, Size2d 자료형이 있다.

 

객체 선언

#include
using namespace std;
using namespace cv;

 

int main()
{
Point_ ipt(100, 200);
//Point2i ipt(100,200);
Point_ fpt(92.3f, 125.23f);
//Point2f fpt(92.3f, 125.23f);
Point_ dpt(100.2, 300.9);
//Point2d dpt(100.2,300.9);

Size_ isize(100, 200);
//Size isize(100,200);
Size_ fsize(192.f, 25.3f);
//Size2f fsize(192.f,25.3f);
Size_ dsize(100.2, 30.9);
//Size2d dsize(100.2, 30.9);

return 0;

}

 

 

 

 

 

 

4. Rect_ 클래스의 멤버 변수와 내부 메서드를 기술하고, 각 세부 자료형으로 객체 선언 하시오.

 

멤버 변수 : x, y, width, height,

 

내부 메서드 : tl(), br(), size(), area(), empty(), contains()

 

객체 선언

Rect_ irect1(10, 10, 20, 40); //x, y, width, height
Rect_ irect2(Point(10, 10), Point(30, 50)); //좌상단, 우하단
Rect_ irect3(Point(10, 10), Size(20, 40)); //좌상단, 크기(w,h)

 

 

 

 

 

 

 

 

 

5. Mat 클래스의 내부 메서드들을 나열하고 기능들을 정리하시오.

 

channels() : 행렬의 채널 수를 반환

 

depth() : 행렬 요소의 depth 값 반환

 

elemSize() : 행렬 요소의 크기를 바이트 단위로 반환

 

elemSize1( ) : 각 행렬 요소의 한 채널의 크기를 바이트 단위로 반환

 

empty() : 배열에 아무런 요소가 없으면 참값 반환

 

isSubmatrix() : 행렬이 다른 행렬의 하위 행렬인 경우(참조행렬인지) true 반환

 

size() : 행렬 크기를 Size 자료형으로 반환

 

step1() : 정규화 된 step 반환, 임의의 행렬 원소에 신속하게 접근하는 것이 유용하다.

 

total() : 행렬 원소의 전체 개수를 반환

 

type() : 행렬의 데이터 타입(자료형+채널수) 반환

 

 

 

 

 

 

 

6. 네임 스페이스를 사용하는 이유를 설명하시오.

 

-소스별로 이름 공간을 따로 설정하여 이름 충돌을 막기 위해 사용한다.

 

 

 

 

 

 

 

7. Rect_ 객체를 생성하는 대표적인 세 가지 방법으로 float형과 int형 사각형을 선언하시오.

Rect_ irect1(10, 10, 20, 40); //x, y, width, height
Rect_ irect2(Point(10, 10), Point(30, 50)); //좌상단, 우하단
Rect_ irect3(Point(10, 10), Size(20, 40)); //좌상단, 크기(w,h)

Rect_ frect1(20.f, 30.f, 100.f, 200.f);
Rect_ frect2(Point2f(20.f, 30.f), Point2f(100.f, 200.f));
Rect_ frect3(Point2f(20.f, 30.f), Size2f(80.f, 170.f));

 

 

 

 

 

 

 

8. Rect_ 객체의 산술(덧셈, 뺄셈) 연산과 논리(&, |) 연산에 대해서 설명하시오.

 

-산술(덧셈, 뺄셈) 연산 : Point 자료형에 대한 산술연산은 사각형에 대한 평행이동이고 size 자료형에 대한 산술연산은 크기를 변경하는 연산이다

 

-논리(&, |) 연산 : Rect 에 대한 교집합(&), 합집합(|) 영역을 구한다

 

 

 

 

 

 

 

 

 

 

9. Mat 클래스를 선언하고, 초기화하는 방법을 세 가지 이상으로 작성하시오.

 

Mat 객체 선언 방법

 

1) Scalar 값으로 초기화

 

2) 배열 원소로 초기화)

 

Size_ 객체로 Mat 객체 선언 방법

float data[] = {
1.2f, 2.3f, 3.2f,
4.5f, 5.f, 6.5f,
};

Mat m1(2, 3, CV_8U, Scalar(300)); //2x3 행렬, CV_8U(자료형 지정), uchar형 300으로 초기화, 255으로 저장
Mat m2(2, 3, CV_32F, data); //2x3 행렬, float 형으로 선언, 배열 원소로 초기화
Mat m3(Size(2, 3), CV_8U, Scalar(300)); //Size_ 객체로 초기화

 

 

 

 

 

 

 

 

10. Mat::reshape() 함수와 Mat::resize() 함수를 비교 설명하시오.

 

-Resize() 는 행렬의 행수를 지정하여 행의 개수를 변경하는 함수로 원소의 개수(채널 수*행수*열수)가 변경될 수 있음

 

-Reshape() 함수는 행렬의 전체 원소 개수를 변경하지 않은 채, 채널의 개수나 행의 개수를 바꾸고자 할 때 사용됨

 

 

 

 

 

 

 

11. Matx 클래스는 어떤 상황에서 사용하며, 어떻게 초기화하는지 예시하시오.

 

-Matx Mat와 비교했을 때, 크기가 작은 행렬을 위한 템플릿 클래스이고,

 

Size가 정해져 있으면 Matx, Vec 를 주로 사용하고

 

정해져 있지 않으면 Mat를 사용한다.

 

 

 

 

 

 

 

 

12. 5개의 원소를 갖는 float 배열을 선언하고, 이 배열을 사용해서 벡터 클래스의 객체를 생성하여 초기화하시오.

#include

using namespace std;

using namespace cv;

int main(){

float fdata[] = { 10.2, 20.6, 30.0, 40.0, 50.0 };
vector fv(fdata, fdata + sizeof(fdata) / sizeof(float));

cout << "[fv] " << ((Mat)fv).reshape(1,1) << endl;

return 0;

}

 

 

 

 

13. 영상 처리 과정에서 처리된 데이터가 주어진 화소값의 범위를 벗어나 문제가 발생할 경우가 있다. 이 경우에 해결 방법은 무엇인가?

 

-포화 캐스팅을 사용해 해결할 수 있다. Cv::saturate_cast< _Tp> ()라는 템플릿 함수를 이용하여 _Tp 의 타입의 범위보다 값이 작거나 크면(언더플로우나 오버플로우 발생 시) 자동으로 최소값/최대값 으로 바꾸어준다

 

 

 

 

 

 

14. 시작 좌표가 30, 40 이고, 크기가 100X200 인 실수형 Rect 객체를 선언하고, 객체를 좌표(10,10) 만큼 평행이동하고, 20X30 만큼 크기를 증가시키는 프로그램 소스를 작성하시오.

 

#include

using namespace std;
using namespace cv;

int main()
{
Rect2f rect(Point2f(30.f, 40.f), Size2f(100, 200));
Rect2f res = rect + Point2f(10.0, 10.0);
res += Size2f(20.0, 30.0);

cout << "rect = " << "(" << rect.x << "," << rect.y << ") ";
cout << "width: " << rect.width << ", height: " << rect.height << endl;
cout << "result = " << "(" << res.x << "," << res.y << ") ";
cout << "width: " << res.width << ", height: " << res.height << endl;

return 0;

}

 

 

 

 

 

 

 

 

15. double Point_ 객체를 5개 생성하고, 벡터에 추가하는 소스를 작성하시오.

 

#include

 

using namespace std;
using namespace cv;

int main()
{
Point2d dpt1(1.2, 2.3);
Point2d dpt2(2.2, 3.3);
Point2d dpt3(3.5, 5.5);
Point2d dpt4(10.2, 30.0);
Point2d dpt5(55.5, 10.0);

vector v;

v.push_back(dpt1);
v.push_back(dpt2);
v.push_back(dpt3);
v.push_back(dpt4);
v.push_back(dpt5);

cout << "[v] " << ((Mat)v).reshape(1, 1) << endl;

}

 

 

 

 

 

 

 

 

 

16. floatMat 객체를 4, 5열로 선언하고, 배열 원소로 초기화하는 소스를 작성하시오.

 

#include

using namespace std;
using namespace cv;

int main()
{
float data[] = {
1.1, 2.2, 3.3, 4.0, 5.5,
6.0, 7.0, 8.0, 9.`0, 0.0,
6.0, 7.0, 8.0, 9.0, 0.0,
1.1, 2.2, 3.3, 4.0, 5.5,
};
Mat m(4, 5, CV_32F, data);

cout << m << endl;
}


 

 

 

 

 

 

 

 

 

17. 실행 결과를 적으시오.

 

33

 

 

 

18. 실행 결과를 적으시오.

 

10

 

20

 

75

 

30

 

40

 

150

 

50

 

55

 

100

 

 

 

 

 

 

 

 

 

19. 다음과 같이 출력하는 프로그램을 작성하시오.

 

#include

using namespace std;
using namespace cv;

int main()
{
Mat m(Size(15, 10), CV_32S, Scalar(100));

Range r200(1, 5), end200(3, 8);
Range r300(5, 9), end300(8, 14);
Range r555(3, 7), end555(5, 10);

//Mat roi(4, 5, CV_32S, Scalar(200));

Mat roi = m(r200, end200);
roi.setTo(200);
roi = m(r300, end300);
roi.setTo(300);
roi = m(r555, end555);
roi.setTo(555);

cout << "[m]" << endl << m << endl;
}