open cv 개요멁실습 · mingw(mingw32) 윈도우api를구현할수있는헤더파일을가지고...

78
Open CV 개요 및 실습 Open CV overview and practice 위성 정보 처리 (Satellite Image Processing)

Upload: others

Post on 28-Sep-2020

22 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 개요 및 실습Open CV overview and practice

위성 정보 처리 (Satellite Image Processing)

Page 2: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

Open Source Computer Vision 개요

- 실시간 컴퓨터 비전(Compute Vision) 목적으로

만들어진 프로그래밍 라이브러리

- Windows, Linux, OS X(Mac OS), iOS, Android 플랫폼

지원

- 첫 개발 시 인텔에서 개발 주도 (현재 X)

- 미래 개발을 위해 크라우드 펀딩으로 운영되는

비영리 재단으로 변경 (2012년~)

- 오픈소스 라이선스 채택 (BSD 라이선스)> 비상업적/상업적 이용 가능

- (현재 2018년) 2.x 버전과

3.x 버전을 동시에 사용

2

Computer Vision, 한빛아카데미

Page 3: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

Homepage / Github

3

- 공식 홈페이지 : https://opencv.org

- 공식 Github :

> https://github.com/Itseez/opencv

- Extra Contribute:

> https://github.com/ltseez/opencv_contrib

Extra Contribute공식적이지는 않지만 최신

기술이 반영된 모듈들이 제공되고 있어 다양한 기능을더 추가할 수 있음

Page 4: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

주요 릴리즈 버전

날짜 버전 내용

2006/10 1.0 • 공식첫버전릴리즈• Python 모듈포함

2009/10 2.0 • MinGW 사용MinGW(mingw32) 윈도우 API를구현할수있는헤더파일을가지고있어윈도우기반프로그램을만들기편리

2010/04 2.1 • OpenCV 모든병렬처리구조가 OpenMP에서Intel TBB로전환

• Mac OS X 공식지원

2012/07 2.4.2 • Android / iOS 공식지원

2013/03 2.4.4 • 데스크톱기반 Java 공식지원• Android / iOS 버전업그레이드

2014/04 2.4.9 • VTK 기반 3D 시각화모듈추가

2015/06 3.0 • 2 버전과는별도로 3으로릴리즈

4

Page 5: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

버전별 특징

5

1.0 2.0 2.1

• C언어 기반 API• 구조체 기반 데이터 구조 사용• 8비트 PNG, JPEG2000 입출력

지원

• C++언어 기반 API• 클래스 기반 데이터 구조 도입• Cmake를 이용하여 라이브러리

컴파일 후 사용 가능• 스테레오 카메라 지원

• OpenMP에서 인텔 TBB로 병렬처리 루프 변경

• Mac OS X에서 빌드 가능

2.2 2.3 2.4.3

• 안드로이드 지원• 16비트 LZW 압축 지원(TIFF 영

상)• GPU 처리 지원

• 파노라마 지원• GPU 모듈 CUDA 4.0 지원

• TBB 설치 없이 기본적인 병렬처리 지원

• OpenCL 컴퓨터 비전 알고리즘인 ocl 모듈 도입

• 안드로이드 카메라 지원 개선

2.4.7 3.0

2.X 와 3.x 가 동시 지원되고 있지만, 새로 만드는 프로젝트일

경우 3.0을 추천

• 비디오 고해상도 모듈 도입• GPU 모듈 CUDA 5.0 지원• 안드로이드 NDK-r9지원• 안드로이드 4.3 지원

• 기존 C++ API 대폭 개선• 모바일 CUDA 지원• IPP, FastCV 같은 저수준 API 지

Page 6: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

활용 범위

- 이미치 프로세싱 : 영상 추출, 필터, 히스토그램 …

6Computer Vision, 한빛아카데미

Page 7: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

활용 범위

- 로봇, 비디오 : 트래킹, 특징 추출

7https://www.youtube.com/watch?v=h8BDMiNxmvA&feature=youtu.behttps://www.youtube.com/watch?v=LYpug_bHle8

Page 8: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

활용 범위

- 인공지능 : 신경막, 딥러닝, 손글씨 인식, …

8Computer Vision, 한빛아카데미

Page 9: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

활용 범위

- 의료, 방송통신, 자동화, 게임, 기상 및 지질 탐사

9Computer Vision, 한빛아카데미

Page 10: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

Open CV 참고 문서 (https://docs.opencv.org/3.4.2/)

10Computer Vision, 한빛아카데미

Page 11: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

OpenCV JavaScript 버전 (OpenCV.js)

11

https://www.youtube.com/watch?v=AlOKQFKCCsYhttp://soswow.github.io/Various-JS-and-Python/JS/OpenCV.js-receipt/

Page 12: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

설치 방법

- 라이브러리 형태이므로 다운로드 받은 후 API 형태로

원하는 프로그램 언어를 통해 사용

12

https://opencv.org/releases.html

Page 13: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

13

- 다운로드된 파일

Opencv-3.4.2-vc14_vc15.exe버전 빌드된 버전

3.X는 Windows 64bit 빌드 버전만 존재

만약 32bit를 사용하고 있다면 별도로 빌드해야 함

vc14(Visual Studio 2015)vc15(Visual Studio 2017)

Page 14: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

14

미리 빌드된 파일Source 코드 모두포함되어 있음

해당 폴더를 원하는 위치로 이동본 강의에서는 C:\opencv\...

Page 15: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

15

iOS

Android

Page 16: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

16

Path 환경 변수 경로 추가

- 오픈 소스로 제공되는 API들은 대부분 동적 연결 라이브러리 파일

로 제공

- 동적 연결 라이브러리 역할?> 함수 호출 정보만 포함하여 목적 코드를 실행 시간에 호출하여 실행하므로

메모리 적약 / 디스크 공간 줄임

- 동적 연결 라이브러리를 사용하려면?> DLL 파일이 프로젝트의 실행 디렉토리로 복사

> 환경변수에 이미 추가된 Path 디렉토리에 복사

> 환경변수 Path에 DLL 파일 디렉토리 경로 추가

Page 17: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

17

Path 환경 변수 경로 추가

만약 나타나지 않을 경우 “내 컴퓨터” -> 빈공간 오른쪽 클릭 -> 속성

Page 18: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

18

Page 19: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

19

C:\opencv\build\x64\vc15\bin

VS community 2017 이므로 vc15 동적 라이브러리사용

릴리즈 배포시에는???>> dll 파일을 exe파일과 같이 배포

Page 20: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

20

https://visualstudio.microsoft.com/ko/vs/community/?rr=https%3A%2F%2Fwww.google.co.kr%2F

2018년 최신버전 community 2017 사용

VC15

Page 21: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

21

Visual Studio 에서 OpenCV 디렉토리 설정

- 총 세 가지 파일 필요

> Open API 파일 (.dll)

> 헤더 파일 (.hpp)

> dll 빌드할 때 함수 정보를

포함하는 라이브러리 (.lib)

Page 22: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

22

둘 중에 아무거나선택해도 됨

Page 23: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

23

Windows 콘솔 응용 프로그램 선택 했을 경우Main 함수와 동시에 cpp 파일 자동 생성

Page 24: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

24

빈 프로젝트 생성 시cpp 파일 별도 생성

Page 25: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

25

Page 26: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

26

Page 27: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

27

Page 28: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

28

Opencv_world342d.lib> 디버그 모드

Opencv_world342.lib> 릴리즈 모드

Page 29: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

29

Open CV 3.0 이상부터는 기본적으로 제공되는 빌드 라이브러리 형태가64비트만 지원그러므로 디버그 / 릴리즈 모두 64비트로 변경 필요(32비트를 하기 위해서는 별도 소스코드 빌드 필요)

본 강의에서는 64비트 Debug용만 세팅

Page 30: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

30

- 위 수행한 속성 설정은 프로젝트에만 해당

- 새 프로젝트 생성 시 동일한 작업을 매번 수행

- 그러므로 이를 저장할 수 있는 “속성 시트“ 기능 존재

속성 관리자를 통해 새 속성 추가

Page 31: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

31

Page 32: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

32

Page 33: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

33

간단한 창 띄우기

- API를 제대로 사용하는지 확인하기 위해 간단한 창을 띄어봄

#include <opencv2/highgui.hpp>

int main(){cv::Mat image(300, 400, CV_8UC1, cv::Scalar(200));cv::imshow("영상보기", image);cv::waitKey(0);

}

Page 34: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

34

기본 헤더파일

- opencv.hpp 기본 헤더 파일

- 이를 추가하면 다른 기본 헤더 파일은 별도 정의할 필요 없음

Page 35: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV

35

Ceemple Open CV

https://marketplace.visualstudio.com/items?itemName=Ceemple.CeempleOpenCV

- OpenCV 프로젝트 생성시 바로 사용할 수 있도록 가능하게 해주는

비쥬얼 스튜디오 확장팩

- 하지만 Visual Studio 2013 버전에서 제공

좀더많은기능이포함되어빌드된 Open CV 라이브러리로편리하게사용할수있다는장점

Page 36: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 기본

OpenCV 기본 자료 구조

- C++ API 에서는 Point2_, Point3_, Size_, Rect_, Vec_, Scalar_,

Mat_ 등 자료구조를 위한 템플릿 클래스 제공

36

Point_ 클래스

- 가로와 세로의 위치를 2차원 좌표로 나타내기 위한 탬플릿 클래스

- 멤버 변수 : x, y

원점(0, 0)

원점(3, 4)

Point_ <int> pt(3, 4)

https://docs.opencv.org/3.4.2/dc/dd1/structCvPoint.html

Page 37: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 기본

Point_ 클래스 예제

37

#include <opencv2/opencv.hpp>

int main(){

// Point_ 객체 선언 방식cv::Point_<int> pt1(100, 200);cv::Point_<float> pt2(92.3f, 125.23f);cv::Point_<double> pt3(100.2, 300.9);

// Point_ 객체 간결 선언 방식cv::Point2i pt4(120, 69);cv::Point2f pt5(0.3f, 0.f), pt6(0.f, 0.4f);cv::Point2d pt7(0.25, 0.6);

// Point_ 객체 연산cv::Point pt8 = pt1 + (cv::Point) pt2;cv::Point2f pt9 = pt6 * 3.14f;cv::Point2d pt10 = (pt3 + (cv::Point2d) pt6) * 10;

std::cout << "pt8 = " << pt8.x << " , " << pt8.y << std::endl;std::cout << "[pt9] = " << pt9 << std::endl;std::cout << (pt2 == pt6) << std::endl;std::cout << "pt7과 pt8의 내적 : " << pt7.dot(pt8) << std::endl;system("pause");return 0;

}

Page 38: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 기본

Size_ 클래스

- 이미지나 사각형 크기를 규정하는 템플릿 클래스

- 멤버 변수 : width, height

38https://docs.opencv.org/3.4.2/da/dcb/structCvSize.html

width

height

Size_ <int> sz(5, 3)

Page 39: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 기본

Size_ 클래스 예제

39

#include <opencv2/opencv.hpp>using namespace cv;using namespace std;int main(){

// Size_ 객체 기본 선언 방식Size_<int> sz1(100, 200);Size_<float> sz2(192.3f, 25.3f);Size_<double> sz3(100.2, 30.9);

// Size 객체 간결 선언 방식Size sz4(120, 69);Size2f sz5(0.3f, 0.f);Size2d sz6(0.25, 0.6);

Point2d pt1(0.25, 0.6);Size2i sz7 = sz1 + (Size2i)sz2;Size2d sz8 = sz3 - (Size2d)sz4;Size2d sz9 = sz5 + (Size2f)pt1;

cout << "sz1.width = " << sz1.width;cout << ", sz1.height = " << sz1.height << endl;cout << "sz1 넓이 " << sz1.area() << endl;cout << "[sz7] = " << sz7 << endl;cout << "[sz8] = " << sz8 << endl;cout << "[sz9] = " << sz9 << endl;system("pause");return 0;

}

Page 40: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 기본

Rect_ 클래스

- 2차원 사각형 정보를 나타내기 위한 탬플릿 클래스

- 멤버 변수: 시작 좌표(x, y), 크기(width, height)

40https://docs.opencv.org/3.4.2/d0/d76/structCvRect.html

시작좌표 (pt1)Rect_::t1()

종료좌표 (pt2)Rect_::br()

크기(sz)width

height

Page 41: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 기본

Rect_ 클래스 예제

41

#include <opencv2/opencv.hpp>using namespace cv;using namespace std;int main(){

Size2d sz(100.5, 60.6);Point2f pt1(20.f, 30.f), pt2(100.f, 200.f);

// Rect_ 객체 기본 선언 방식Rect_<int> rect1(10, 10, 30, 50);Rect_<float> rect2(pt1, pt2);Rect_<double> rect3(Point2d(20.5, 10), sz);

// 간결 선언 방식 & 연산 적용Rect rect4 = rect1 + (Point)pt1;Rect2f rect5 = rect2 + (Size2f)sz;Rect2d rect6 = rect1 & (Rect)rect2;

// 결과 출력cout << "rect3 = " << rect3.x << "," << rect3.y << ", ";cout << rect3.width << "x" << rect3.height << endl;cout << "rect4 = " << rect4.tl() << " " << rect4.br() << endl;cout << "rect5 크기 = " << rect5.size() << endl;cout << "[rect6] = " << rect6 << endl;system("pause");return 0;

}

Page 42: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 기본

Vec_ 클래스

- 원소 개수가 작은 숫자 벡터를 위한 템플릿 클래스

- Vec<Tp, 2>, Vec<Tp, 3>, Vec<Tp, 4>

각 각 Point_, Point3_, Scalar_ 클래스로 형변환 가능

42https://docs.opencv.org/3.4.2/d6/dcf/classcv_1_1Vec.htmlhttps://docs.opencv.org/3.4.2/d6/db3/structCvScalar.html

Scalar_ 클래스

- Vec<Tp, 4)에서 파생된 템플릿 클래스

- 4개 원소를 갖음

- OpenCV에서 특별히 화소의 값을 지정하기 위한 자료형으로 정의

- 파랑, 초록, 빨강, 투명도 4개 값 저장

Page 43: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 기본

Mat 클래스

- 1채널 또는 다채널의 실수, 복소수, 행렬, 영상 등 수치 데이터를 표현하는

N 차원 행렬 클래스 (행과 열을 다루는 클래스)

- 1버전에서는 IplImage를 사용하여 화소에 접근(구조체)

- 이미지 데이터는 모두 행과 열로 구성

- 이미지 저장소라고 생각해도 무방

43

1 2 3

1 2 3

1 2 3

… … … … … … … … … …

… 0 0 0 0 0 20 30 40 …

… 0 0 0 0 0 0 0 0 …

… 0 0 0 0 0 0 0 0 …

… 0 0 0 0 20 56 40 0 …

… 20 0 0 0 0 0 0 0 …

… 0 0 0 0 30 20 40 20 …

… … … … … … … … … …

… … … … … … … … … …

… 0 0 0 0 0 20 30 40 …

… 0 0 0 0 0 0 0 0 …

… 0 0 0 0 0 0 0 0 …

… 0 0 0 0 20 56 40 0 …

… 20 0 0 0 0 0 0 0 …

… 0 0 0 0 30 20 40 20 …

… … … … … … … … … …

… … … … … … … … … …

… 0 0 0 0 0 20 30 40 …

… 0 0 0 0 0 0 0 0 …

… 0 0 0 0 0 0 0 0 …

… 0 0 0 0 20 56 40 0 …

… 20 0 0 0 0 0 0 0 …

… 0 0 0 0 30 20 40 20 …

… … … … … … … … … …

(예)

Page 44: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 기본

Mat 클래스

44https://docs.opencv.org/3.4.2/d3/d63/classcv_1_1Mat.html

- IplImage 구조체

> C 단점을 그대로 갖고 있음

> 처리 속도 느림

> 화소 데이터 타입에 따른 배열 인덱싱과 형변환 복잡

> 메모리 관리 차원에서 사용 후 모두 직접 해제해 주어야하기 때문에

관리가 제대로 되지 않을 경우 메모리 누수 문제 발생

- Mat 클래스

> 자료형 표현 쉬움

> 화소에 대한 접근 방법 수월

> 메모리 해제도 소멸자에서 처리하기 때문에 관리 또한 편리

Page 45: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 기본

Mat 클래스 예제

45

#include <opencv2/opencv.hpp>using namespace cv;using namespace std;int main(){

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

};// Mat 객체 선언 방법Mat m1(2, 3, CV_8U);Mat m2(2, 3, CV_8U, Scalar(300));Mat m3(2, 3, CV_16S, Scalar(300));Mat m4(2, 3, CV_32F, data);

// Size 객체로 Mat 객체 선언 방법Size sz(2, 3);Mat m5(Size(2, 3), CV_64F);Mat m6(sz, CV_32F, data);

cout << "[m1] =" << endl << m1 << endl;cout << "[m2] =" << endl << m2 << endl;cout << "[m3] =" << endl << m3 << endl;cout << "[m4] =" << endl << m4 << endl << endl;cout << "[m5] =" << endl << m5 << endl;cout << "[m6] =" << endl << m6 << endl;system("pause");return 0;

}

결과에서 확인할 수 있듯이Size를 통해 행렬을 생성하면행과 열 순서가 뒤바뀜

Page 46: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

이미지 파일 처리

- 이미지 파일 읽기 (흑백) (169)

47

#include <opencv2/opencv.hpp>using namespace cv;using namespace std;

void print_matInfo(string name, Mat img){string str;int depth = img.depth();

if (depth == CV_8U) str = "CV_8U";else if (depth == CV_8S) str = "CV_8S";else if (depth == CV_16U) str = "CV_16U";else if (depth == CV_16S) str = "CV_16S";else if (depth == CV_32S) str = "CV_32S";else if (depth == CV_32F) str = "CV_32F";else if (depth == CV_64F) str = "CV_64F";

cout << name;cout << format(": depth(%d) channels(%d) -> 자료형: ", depth, img.channels());cout << str << "C" << img.channels() << endl;}

int main(){string filename1 = "image.jpg";Mat gray2gray = imread(filename1, IMREAD_GRAYSCALE);Mat gray2color = imread(filename1, IMREAD_COLOR);CV_Assert(gray2gray.data && gray2color.data);

Rect roi(100, 100, 1, 1);cout << "행렬 좌표 (100,100) 화소값 " << endl;cout << "gray2gray " << gray2gray(roi) << endl;cout << "gray2color " << gray2color(roi) << endl << endl;

print_matInfo("gray2gray", gray2gray);print_matInfo("gray2color", gray2color);imshow("gray2gray", gray2gray);imshow("gray2color", gray2color);waitKey(0);return 0;}

Page 47: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

48

컬러 사진을 읽었을 때

회색조 사진을 읽었을 때

Page 48: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

행렬 연산 (기본 배열 처리 함수)

- flip : 입력된 2차원 배열을 수직, 수평, 양축으로 뒤집음

- repeat: 입력 배열의 반복된 복사본으로 출력배열을 채움

- transpose : 입력 행렬의 전치 행렬을 출력 인수로 반환

49

#include <opencv2/opencv.hpp>using namespace cv;using namespace std;int main(){

Mat image = imread("image.jpg", IMREAD_COLOR);CV_Assert(image.data);

Mat x_axis, y_axis, xy_axis, rep_img, trans_img;flip(image, x_axis, 0);flip(image, y_axis, 1);flip(image, xy_axis, -1);

repeat(image, 1, 2, rep_img);transpose(image, trans_img);

imshow("image", image);imshow("x_axis", x_axis);imshow("y_axis", y_axis);imshow("xy_axis", xy_axis);imshow("rep_img", rep_img);imshow("trans_img", trans_img);

waitKey();return 0;

}

Page 49: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

50

Page 50: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

행렬 연산 (산술 연산 함수)

- 사칙 연산: add, subtract, multiply, divide, addWeighted

- 지수 로그 루트 관련 함수: exp, log, sqrt, pow, magnitude, phase,

cartToPolar, polarToChart

- 논리 연산함수: bitwise_and, gitwise_or, bitwise_xor, bitwise_not

51

#include <opencv2/opencv.hpp>using namespace cv;using namespace std;int main(){Mat m1(3, 6, CV_8UC1, Scalar(10));Mat m2(3, 6, CV_8UC1, Scalar(50));Mat m_add1, m_add2, m_sub, m_div1, m_div2;Mat mask(m1.size(), CV_8UC1);// 마스크 행렬 - 8비트 단일채널

Rect rect(Point(3, 0), Size(3, 3));// 관심영역 지정mask(rect).setTo(1);

add(m1, m2, m_add1);add(m1, m2, m_add2, mask);

divide(m1, m2, m_div1);m1.convertTo(m1, CV_32F);// 형변환 – 소수점이하 값 보존

m2.convertTo(m2, CV_32F);divide(m1, m2, m_div2);

cout << "[m1] = " << endl << m1 << endl;cout << "[m2] = " << endl << m2 << endl;cout << "[mask] = " << endl << mask << endl << endl;

cout << "[m_add1] = " << endl << m_add1 << endl;cout << "[m_add2] = " << endl << m_add2 << endl;cout << "[m_div1] = " << endl << m_div1 << endl;cout << "[m_div2] = " << endl << m_div2 << endl;system("pause");return 0;

}

Page 51: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

행렬 연산 (산술 연산 함수)

52

Page 52: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

논리 연산 오버랩 예제

53

#include <opencv2/opencv.hpp>using namespace cv;using namespace std;int main(){

Mat image = imread("river.jpg", IMREAD_COLOR);Mat logo = imread("moon.jpg", IMREAD_COLOR);CV_Assert(image.data && logo.data);// 예외처리Mat logo_th, masks[5], background, foreground, dst;// 결과 행렬

threshold(logo, logo_th, 70, 255, THRESH_BINARY); // 로고 영상 이진화split(logo_th, masks);// 로고영상 채널 분리

bitwise_or(masks[0], masks[1], masks[3]);// 전경통과 마스크bitwise_or(masks[2], masks[3], masks[3]);bitwise_not(masks[3], masks[4]);// 배경통과 마스크

Point center1 = image.size() / 2;// 영상 중심좌표Point center2 = logo.size() / 2;;// 로고 중심좌표Point start = center1 - center2;Rect roi(start, logo.size());// 로고가 위치할 관심영역

//비트곱과 마스킹을 이용한 관심 영역의 복사bitwise_and(logo, logo, foreground, masks[3]);bitwise_and(image(roi), image(roi), background, masks[4]);

add(background, foreground, dst);// 로고 전경과 배경 합성dst.copyTo(image(roi));// 로고 합성 영상을 관심영역에 복사

imshow("background", background);imshow("foreground", foreground);imshow("dst", dst);imshow("image", image);waitKey();return 0;

}

Page 53: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

논리 연산 오버랩 예제

54

Page 54: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

영상 처리 (영상 밝기)

- 화소 값이 영상 밝기를 나타내기 때문에 이 화소 값을 변경하면

영상 밝기를 변경할 수 있음

55

#include <opencv2/opencv.hpp>using namespace cv;using namespace std;int main(){

Mat image = imread("image.jpg", IMREAD_GRAYSCALE);CV_Assert(!image.empty());

Mat dst1 = image + 100;Mat dst2 = image - 100;Mat dst3 = 255 - image;

Mat dst4(image.size(), image.type());Mat dst5(image.size(), image.type());

for (int i = 0; i < image.rows; i++) {for (int j = 0; j < image.cols; j++){

dst4.at<uchar>(i, j) = image.at<uchar>(i, j) + 100;//dst4.at<uchar>(i, j) =

saturate_cast<uchar>(image.at<uchar>(i, j) + 100);dst5.at<uchar>(i, j) = 255 - image.at<uchar>(i, j);

}}

imshow("원 영상", image);imshow("dst1 - 밝게", dst1);imshow("dst2 - 어둡게", dst2);imshow("dst3 - 반전", dst3);imshow("dst4 - 밝게", dst4);imshow("dst5 - 반전", dst5);waitKey();return 0;

}

Page 55: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

56dst4 밝게는 255가 넘기 때문에 밝기가 제대로 되지 않음

Page 56: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

영상 처리 (명암 대비)

- 명암 대비는 상이한 두 가지 색이 경계에서 서로 영향을 미쳐

그 차이가 강조되어 나타나는 현상

57

#include <opencv2/opencv.hpp>using namespace cv;using namespace std;int main(){Mat image = imread("image.jpg", 0);// 명암도 타입 읽기CV_Assert(image.data);// 예외처리

Scalar avg = mean(image) / 2.0;// 원본 영상 화소 평균의 절반Mat dst1 = image * 0.5;// 명암대비 감소Mat dst2 = image * 2.0;// 명암대비 증가Mat dst3 = image * 0.5 + avg[0];// 영상 평균 이용 대비 감소Mat dst4 = image * 2.0 - avg[0];// 영상 평균 이용 대비 중가

imshow("image", image);imshow("dst1-대비감소", dst1), imshow("dst2-대비증가", dst2);imshow("dst3-평균이용 대비감소", dst3), imshow("dst4-평균이용 대비증가", dst4);

waitKey();return 0;

}

Page 57: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

영상 처리 (명암 대비 예제)

58

Page 58: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

영상 처리 (히스토그램)

- 화소 접근, 밝기 변환, 히스토그램, 컬러 공간

59

#include <opencv2/opencv.hpp>using namespace cv;using namespace std;

void calc_histo(Mat image, Mat &hist, int bins, int range_max = 256){

hist = Mat(bins, 1, CV_32F, Scalar(0));float gap = range_max / (float)bins;

for (int i = 0; i < image.rows; i++) {for (int j = 0; j < image.cols; j++){int idx = int(image.at<uchar>(i, j) / gap);hist.at<float>(idx)++;}

}}

int main(){Mat image = imread("image.jpg", IMREAD_GRAYSCALE);CV_Assert(!image.empty());

Mat hist;calc_histo(image, hist, 256);// 히스토그램 계산cout << hist.t() << endl;

imshow("image", image);waitKey();return 0;

}

Page 59: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

60

엑셀로 데이터 표현

Page 60: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

영상 처리 (히스토그램 – 함수 활용)

- OpenCV 에서 제공하는 히스토그램 계산 함수

cv:calcHist()

- 다채널 행렬에서 다차원의 히스토그램을 구하기 때문에 인수와 구조

복잡

61

#include <opencv2/opencv.hpp>using namespace cv;using namespace std;

void calc_Histo(const Mat& image, Mat& hist, int bins, int range_max = 256){

inthistSize[] = { bins };// 히스토그램 계급개수float range[] = { 0, (float)range_max };// 채널 화소값 범위intchannels[] = { 0 };// 채널 목록const float* ranges[] = { range };

calcHist(&image, 1, channels, Mat(), hist, 1, histSize, ranges);}

int main(){Mat image = imread("image.jpg", IMREAD_GRAYSCALE);CV_Assert(!image.empty());

Mat hist;calc_histo(image, hist, 256);// 히스토그램 계산cout << hist.t() << endl;

imshow("image", image);waitKey();return 0;

}

Page 61: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

영상 처리 (히스토그램 – 함수 활용)

62

Page 62: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

영상 처리 (히스토그램 그리기)

63

#include <opencv2/opencv.hpp>using namespace cv;using namespace std;

void calc_Histo(const Mat& image, Mat& hist, int bins, int range_max = 256){

int histSize[] = { bins };// 히스토그램 계급개수float range[] = { 0, (float)range_max };// 히스토그램 범위int channels[] = { 0 };// 채널 목록const float* ranges[] = { range };

calcHist(&image, 1, channels, Mat(), hist, 1, histSize, ranges);}

void draw_histo(Mat hist, Mat &hist_img, Size size = Size(256, 200)){

hist_img = Mat(size, CV_8U, Scalar(255));float bin = (float)hist_img.cols / hist.rows;normalize(hist, hist, 0, size.height, NORM_MINMAX);

for (int i = 0; i < hist.rows; i++){float start_x = (i * bin);float end_x = (i + 1) * bin;Point2f pt1(start_x, 0);Point2f pt2(end_x, hist.at <float>(i));

if (pt2.y > 0)rectangle(hist_img, pt1, pt2, Scalar(0), -1);

}flip(hist_img, hist_img, 0);

}

int main(){Mat image = imread("image.jpg", IMREAD_GRAYSCALE);CV_Assert(!image.empty());

Mat hist, hist_img;calc_Histo(image, hist, 256);draw_histo(hist, hist_img);

imshow("hist_img", hist_img);imshow("image", image);waitKey();return 0;}

Page 63: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

영상 처리 (히스토그램 그리기)

64

색상 히스토그램

Page 64: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

영상 처리 (히스토그램 평활화)

65

void calc_Histo(const Mat& image, Mat& hist, int bins, int range_max = 256){…}void draw_histo(Mat hist, Mat &hist_img, Size size = Size(256, 200)){…}void create_hist(Mat img, Mat &hist, Mat &hist_img){…}int main(){

Mat image = imread("image.jpg", 0);// 명암도 영상 읽기CV_Assert(!image.empty());// 영상파일 예외처리

Mat hist, dst1, dst2, hist_img, hist_img1, hist_img2;create_hist(image, hist, hist_img);// 히스토그램 및 그래프 그리기

// 히스토그램 누적합 계산Mat accum_hist = Mat(hist.size(), hist.type(), Scalar(0));accum_hist.at<float>(0) = hist.at<float>(0);for (int i = 1; i < hist.rows; i++) {accum_hist.at<float>(i) = accum_hist.at<float>(i - 1) + hist.at<float>(i);

}

accum_hist /= sum(hist)[0];// 누적합의 정규화accum_hist *= 255;dst1 = Mat(image.size(), CV_8U);for (int i = 0; i < image.rows; i++) {for (int j = 0; j < image.cols; j++) {

int idx = image.at<uchar>(i, j);dst1.at<uchar>(i, j) = (uchar)accum_hist.at<float>(idx);

}}

//normalize(accum_hist, accum_hist, 0, 255, NORM_MINMAX);// 누적합의 정규화//accum_hist.convertTo(accum_hist, CV_8U);//LUT(image, accum_hist, dst1);// 룩업 테이블 적용

equalizeHist(image, dst2);// 히스토그램 평활화create_hist(dst1, hist, hist_img1);// 히스토그램 및 그래프 그리기create_hist(dst2, hist, hist_img2);

imshow("image", image), imshow("img_hist", hist_img);// 원본 히스토그램imshow("dst1-User", dst1), imshow("User_hist", hist_img1);// 사용자 평활화imshow("dst2-OpenCV", dst2), imshow("OpenCV_hist", hist_img2);// OpenCV 평활화waitKey();return 0;}

Page 65: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

영상 처리 (히스토그램 평활화)

66

Page 66: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

영역 처리 (블러링)

67

#include <opencv2/opencv.hpp>using namespace cv;using namespace std;

void filter(Mat img, Mat& dst, Mat mask)// 회선 수행 함수{

dst = Mat(img.size(), CV_32F, Scalar(0));// 회선 결과 저장 행렬Point h_m = mask.size() / 2;// 마스크 중심 좌표

for (int i = h_m.y; i < img.rows - h_m.y; i++) {// 입력 행렬 반복 순회for (int j = h_m.x; j < img.cols - h_m.x; j++){

float sum = 0;for (int u = 0; u < mask.rows; u++) {// 마스크 원소 순회

for (int v = 0; v < mask.cols; v++){

int y = i + u - h_m.y;int x = j + v - h_m.x;sum += mask.at<float>(u, v) * img.at<uchar>(y, x);// 회선 수식

}}

dst.at<float>(i, j) = sum;// 회선 누적값 출력화소 저장}

}}int main(){

Mat image = imread("image.jpg", IMREAD_GRAYSCALE);CV_Assert(image.data);// 영상파일 예외 처리

float data[] = {// 블러링 마스크 원소 지정1/9.f, 1/9.f, 1 / 9.f,1 / 9.f, 1 / 9.f, 1 / 9.f,1 / 9.f, 1 / 9.f, 1 / 9.f

};

Mat mask1(3, 3, CV_32F, data);// 마스크 행렬 선언Mat blur;filter(image, blur , mask1);// 회선 수행blur.convertTo(blur, CV_8U);// 자료형 변환

imshow("blur", blur);// 결과 행렬 윈도우에 표시imshow("image", image);waitKey();return 0;

}

Page 67: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

영역 처리 (블러링)

68

Page 68: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

영역 처리 (샤프닝)

69

#include <opencv2/opencv.hpp>using namespace cv;using namespace std;

void filter(Mat img, Mat& dst, Mat mask)// 회선 수행 함수{

dst = Mat(img.size(), CV_32F, Scalar(0));// 회선 결과 저장 행렬Point h_m = mask.size() / 2;// 마스크 중심 좌표

for (int i = h_m.y; i < img.rows - h_m.y; i++) {// 입력 행렬 반복 순회for (int j = h_m.x; j < img.cols - h_m.x; j++){

float sum = 0;for (int u = 0; u < mask.rows; u++) {// 마스크 원소 순회

for (int v = 0; v < mask.cols; v++){

int y = i + u - h_m.y;int x = j + v - h_m.x;sum += mask.at<float>(u, v) * img.at<uchar>(y, x);// 회선 수식

}}

dst.at<float>(i, j) = sum;// 회선 누적값 출력화소 저장}

}}int main(){

Mat image = imread("image.jpg", IMREAD_GRAYSCALE);CV_Assert(image.data);// 영상파일 예외 처리

float data1[] = {// 사프닝 마스크 원소 지정0, -1, 0,-1, 5, -1,0, -1, 0,};float data2[] = {// 사프닝 마스크 원소 지정-1, -1, -1,-1, 9, -1,-1, -1, -1,};

Mat mask1(3, 3, CV_32F, data1);// 마스크 행렬 선언Mat mask2(3, 3, CV_32F, data2);Mat sharpen1, sharpen2;filter(image, sharpen1, mask1);// 회선 수행filter(image, sharpen2, mask2);sharpen1.convertTo(sharpen1, CV_8U);// 자료형 변환sharpen2.convertTo(sharpen2, CV_8U);

imshow("sharpen1", sharpen1);// 결과 행렬 윈도우에 표시imshow("sharpen2", sharpen2);imshow("image", image);waitKey();return 0;

}

Page 69: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

영역 처리 (샤프닝)

70

Page 70: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

영역 처리 (엣지 검출 – 유사연산자)

71

#include <opencv2/opencv.hpp>using namespace cv;using namespace std;

void homogenOp(Mat img, Mat& dst, int mask_size){

dst = Mat(img.size(), CV_8U, Scalar(0));Point h_m(mask_size / 2, mask_size / 2);

for (int i = h_m.y; i < img.rows - h_m.y; i++) {for (int j = h_m.x; j < img.cols - h_m.x; j++){

uchar max = 0;for (int u = 0; u < mask_size; u++) {for (int v = 0; v < mask_size; v++){

int y = i + u - h_m.y;int x = j + v - h_m.x;uchar difference = abs(img.at<uchar>(i, j) - img.at<uchar>(y, x));if (difference > max) max = difference;

}}dst.at<uchar>(i, j) = max;

}}

}

int main(){

Mat image = imread("image.jpg", IMREAD_GRAYSCALE);

CV_Assert(image.data);

Mat edge;homogenOp(image, edge, 3);

imshow("image", image);imshow("edge-homogenOp", edge);waitKey();return 0;

}

Page 71: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

영역 처리 (엣지 검출 – 유사연산자)

72

Page 72: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

영역 처리 (엣지 검출 – 프리윗/소벨)

73

#include <opencv2/opencv.hpp>using namespace cv;using namespace std;

void differential(Mat image, Mat& dst, float data1[], floatdata2[]){Mat dst1, mask1(3, 3, CV_32F, data1);Mat dst2, mask2(3, 3, CV_32F, data2);

filter2D(image, dst1, CV_32F, mask1);// OpenCV 제공 회선 함수filter2D(image, dst2, CV_32F, mask2);magnitude(dst1, dst2, dst);dst.convertTo(dst, CV_8U);

convertScaleAbs(dst1, dst1);// 절대값 및 형변환 동시 수행 함수convertScaleAbs(dst2, dst2);imshow("dst1 - 수직 마스크", dst1);// 윈도우 행렬 표시imshow("dst2 - 수평 마스크", dst2);}

int main(){Mat image = imread("../image/edge_test1.jpg", IMREAD_GRAYSCALE);CV_Assert(image.data);

float data1[] = {-1, 0, 1,-2, 0, 2,-1, 0, 1};float data2[] = {-1, -2, -1,0, 0, 0,1, 2, 1};

Mat dst, dst3, dst4;differential(image, dst, data1, data2);// 두 방향 소벨 회선 및 크기 계산

// OpenCV 제공 소벨 에지 계산Sobel(image, dst3, CV_32F, 1, 0, 3);// x방향 미분 - 수직 마스크Sobel(image, dst4, CV_32F, 0, 1, 3);// y방향 미분 - 수평 마스크convertScaleAbs(dst3, dst3);// 절대값 및 uchar 형변환convertScaleAbs(dst4, dst4);

imshow("image", image), imshow("소벨에지", dst);imshow("dst3-수직_OpenCV", dst3), imshow("dst4-수평_OpenCV", dst4);

waitKey();return 0;}

float data1[] = {-1, 0, 1,-1, 0, 1,-1, 0, 1};float data2[] = {-1, -1, -1,0, 0, 0,1, 1, 1};

소벨 마스크

프리윗 마스크

Page 73: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

변환 영역 처리

- 영상 데이터는 화소값이 직접 표현된 공간영역과 우주 공간과 같은

변환영역 크게 2가지 영역으로 구분

- 변환영역은 직교변환에 의해 얻어진 영상 데이터의 다른 표현

74

공간 주파수

- 영상 처리에서는 공간 주파수라는 개념 사용

- 예) 화소 밝기의 변화도에 따른 빈도를 주파수로 표현

Page 74: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

공간 주파수

- 저주파 공간 영역

> 화소 밝기가 거의 변화가 없거나 점진적으로 변화하는 것

> 영상에서 배경 또는 객체의 내부

- 고주파 공간 영역

> 화소 밝기가 급변하는 것

> 경계부분이나 객체의 모서리 부분

75

Page 75: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

영상 분할 (k-최근접 이웃 분류기)

- 기존 가지고 있는 데이터들을 일정한 규칙에 의해 분류된 상태에서

새로운 입력 데이터의 종류를 예측하는 분류 알고리즘

76

트레이닝 데이터

실험 데이터숫자 인식 예제

Page 76: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

영상 분할 (k-최근접 이웃 분류기)

77

Page 77: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

응용 사례 (얼굴 검출)

78

- 하르 기반 검출기 이용 얼굴 / 눈을 검출

- 하르 기반 분류기> 2001년 Viola와 Jones가 제안한 방법

> OpenCV 3 버전 디렉토리에 검출기 내용이 이미 포함되어 있음

(본 강의 기준 : C:\opencv\sources\data\haarcascades)

Page 78: Open CV 개요멁실습 · MinGW(mingw32) 윈도우API를구현할수있는헤더파일을가지고 있어윈도우기반프로그램을만들기편리 2010/04 2.1 • OpenCV 모든병렬처리구조가OpenMP에서

Open CV 실습

응용 사례 (성별 검출)

79