ygreenb
yellowgreenblue
ygreenb
전체 방문자
오늘
어제
  • TIL (130)
    • Algorithm & Data Structure (70)
      • 이론 (4)
      • 프로그래머스 (54)
      • 백준 (12)
    • JAVA (4)
    • Android Studio (9)
    • Database (1)
    • WEB (25)
      • HTML+CSS (7)
      • Javascript (5)
      • React (11)
      • Django (1)
      • Node.js (1)
    • Computer Vision (13)
    • Git (8)

블로그 메뉴

  • HOME
  • TAG
  • GITHUB

공지사항

인기 글

태그

  • DP
  • stack
  • 프로그래머스 Lv.2
  • React
  • PriorityQueue
  • Arrays.sort()
  • 안드로이드
  • Queue
  • HashMap
  • dfs
  • git bash
  • BFS
  • java
  • Android
  • 깃
  • compareTo()
  • Comparator
  • entrySet
  • 해시
  • 프로그래머스
  • 백준
  • 코틀린
  • sort
  • git
  • greedy
  • reactjs
  • 스택/큐
  • 깃허브
  • getOrDefault
  • kotiln

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
ygreenb

yellowgreenblue

Computer Vision

[OpenCV] Open CV 기초

2020. 1. 9. 05:35

목표

  • Open CV의 기본데이터 타입 Mat에 대해 알아보기
  • 영상, 비디오 읽고 출력하는 방법을 알아보기

1. Mat이란?

Open CV의 기본 데이터 타입으로 Matrix(행렬)의 약어이다.

영상은 픽셀들의 집합으로 구성되어있고, 각의 픽셀들은 2차원 좌표로 그 위치를 표현가능하다.

즉, 영상은 2차원배열로 생각할 수 있다는 의미이다.

 

Mat 선언방법에는

  • Mat(int rows, int cols, int type) 행,열 개수와 각각의 픽셀타입 설정
  • Mat(Size size, int type) size 함수로 메트릭스 크기 설정함
  • Mat(const Mat & m) 이미 선언되어있는 메트릭스가 있는 경우, 그 메트릭스을 받아오는 방법. m과 크기가 같으면서 메트릭스를 복사해온다.
  • Mat(Size size, int type, const Scalar & s) 각각의 픽셀의 특정한 값을 설정하는 방법

Pixel type (고정 픽셀 유형)

Mat의 element가 특정 형식의 데이터인지를 지정한다.

- CV_8U: 8-bit unsigned integer: uchar ( 0~255 )
- CV_8S: 8-bit signed integer: schar ( -128~127 )
- CV_16U: 16-bit unsigned integer: ushort ( 0~65535 )
- CV_16S: 16-bit signed integer: short ( -32768~32767 )
- CV_32S: 32-bit signed integer: int ( -2147483648~2147483647 )
- CV_32F: 32-bit floating-point number: float ( -FLT_MAX~FLT_MAX, INF, NAN )
- CV_64F: 64-bit floating-point number: double (-DBL_MAX~ DBL_MAX, INF, NAN )
Multi-channel array: CV_8UC3, CV_8U(3), CV_64FC4, CV_64FC(4)

CV_8UC1에서

- CV : 컴퓨터비전의 약자

- 8 : 비트단위, 하나의 픽셀을 표현하기 위해서 8bits를 활용하겠다는 의미.

- U : unsigned의 약자 (S : signed, F : floating)

- C1 : channel-1, 즉 채널 1개를 의미

 

openCV에서 mat을 단순히 영상을 표현하는데만 사용하는 것이 아니라. 일반적인 행렬 영상에도 사용하거나

전처리과정이나 에지검출 과정 때 같이, 경우에 따라 위와 같은 다양한 픽셀 타입을 선언할 수 있다.

 

Example

Mat mtx(3, 3, CV_32F);
// make a 3x3 floating-point matrix
// 세로3가로3, 픽셀 float타입

Mat cmtx(10, 1, CV_64FC2);
// make a 10x1 2-channel floating-point matrix
// (10-element complex vector)

//밑의 두 선언은 같은 매트릭스로 Size함수 사용하고 안하고의 차이.
Mat img(1080, 1920, CV_8UC3); // 세로, 가로 순으로 선언
// make a 3-channel (color) image of 1920 columns and 1080 rows.

Mat img(Size(1920, 1080), CV_8UC3); //Size함수를 사용하는 경우엔 가로, 세로 순으로 선언함
// make a 3-channel (color) image of 1920 columns and 1080 rows.

 

// 가장 기본적인 openCV 활용코드
#include "cv.hpp" // openCV활용하기 위해 추가해주는 헤더
#include <iostream> // c++ 활용하기 위해 사용하는 헤더

using namespace cv; // openCV활용하기 위해 nampspace 추가
using namespace std; // c++ 이하생략...

int main()
{
	int w = 150, h = 100; // 가로, 세로
	Mat image(h, w, CV_8UC1, Scalar(255)); // 이미지. 1-channel이기 때문에 scalar값 하나만 설정함
	cout << "Size: " << image.size().height << "," << image.size().width << endl;
	imshow("image", image); // 영상출력. image라는 이름을 가진 윈도우에 해당 메트릭스 결과 출력.
	
    waitKey(0);
	return 0;
}

Scalar(255,0,0) 3-channel인 경우 선언방법. openCV의 경우 B,G,R순서로 선언됨.

 

 

2. 영상을 읽어들이는 방법

  • Mat imread(const string& filename, int flags=1)

imread 함수를 사용해서 영상을 읽는다.

파라미터1 : 읽어들이는 영상의 파일이름

파라미터2 : 이 영상을 컬러or그레이스케일로 받아들일 것인지를 결정함)

Flag value as 1:read image as color image 

Flag value as 0:read image as gray scale image

int main() {
	Mat gray_image, color_image;
    
	// 0 on the 2nd parameter means read img in grayscale
	gray_image = imread("lena.png", 0);
    
	// blank 2nd parameter means 1, which means read img in colors
    color_image = imread("lena.png");
    
    imshow("gray image", gray_image);
    imshow("color image", color_image);
    
    waitKey(0);
    return 0;
}

 

Example

  • file로부터 비디오 읽어옴
int main() {
  Mat frame;
  VideoCapture cap; // 비디오를 읽기 위해 활용하는 클래스로 openCV에서 제공함
  
  // check if file exists. if none program ends
  // 특정한 파일(동영상)로부터 동영상을 읽어옴
  if (cap.open("background.mp4") == 0) { // 해당 파일이 존재하지 않을 때
    cout << "no such file!" << endl;
    waitKey(0);
  }
  
  while (1) {
    cap >> frame; // 다수의 영상의 집합이 모여있는 cap에서 하나의 영상, 프레임이 matrix에 이동된다.
    if (frame.empty()) { // 비어있는 경우 -> 모든 영상을 다 참조했다는 의미
      cout << "end of video" << endl;
      break; // 무한루프 빠져나옴
    }
    imshow("video", frame); // 각각의 프레임을 출력함
    waitKey(33); // 동영상을 구성하는 영상 사이의 간격이 33(ms)이라는 의미로, 그 숫자만큼 시스템을 일시적으로 정지(사용자의 입력을 기다린다.)
    
  }
}

 

  • webcam으로부터 비디오 읽어옴
int main() {
  Mat frame;
  // capture from webcam
  // whose device number=0
  VideoCapture cap(0); // 대부분의 경우 노트북에 부착되어있는 웹캠 디바이스의 넘버가 0임
  
  while (1) {
    cap >> frame;
    
    imshow("web cam", frame);
    waitKey(16);
  }
}

 

 

VideoCapture Class에 포함되어있는 다양한 함수들

- grab() : 현재 존재하는 프레임의 다음 프레임을 가져오는 함수

- open(const String & filename) : 특정한 동영상 파일을 읽어오는 함수

- operator>> : 비디오캡쳐 클래스가 가지고있는 동영상의 특정 프레임을 메트릭스에 전달해주게 됨

- get(int propid) const : 비디오가 가지고있는 상세정보를 확인할 수 있다.

  현재 비디오 파일의 위치. 몇ms재생되었는지, 프레임의 개수, 가로세로, fps 등등..

 

int main() {
  Mat frame;
  VideoCapture cap;
  
  if (cap.open("background.mp4") == 0) return -1;
  double fps = cap.get(CAP_PROP_FPS); //fps정보 얻어옴
  double time_in_msec = 0; int curr_frame = 0; // 현재 재생되고 있는 시간과 프레임 0으로 초기화
  int total_frames = cap.get(CAP_PROP_FRAME_COUNT); // 동영상의 총 프레임 수 확인
  
  // video stops after 3 sec
  while (time_in_msec < 3000) { // 최초 3초만을 보겠다는 의미
    cap >> frame;
    if (frame.empty()) break; // 비디오 끝에 도달했는지 확인, 루프 벗어남..
    time_in_msec = cap.get(CAP_PROP_POS_MSEC); // 현재 재생되고 있는 시간 들어감
    curr_frame = cap.get(CAP_PROP_POS_FRAMES);
    // printing current frames over total frames
    cout << "frames: " << curr_frame << " / " << total_frames << endl;
    imshow("video", frame); 
    
    // calculating the right delay from given fps
    waitKey(1000 / fps); // 영상 간의 간격을 알고 싶을 때 사용하는 공식.. (일반적으로) 33 넣는거랑 동일한 효과
  }
  waitKey(0);
  return 0;
}

 

3. 영상과 동영상을 재생하는 방법

// Display an image
int main() {
  Mat img;
  img = imread("lena.png", 1); // 영상 읽어옴
  imshow("Window", img); // 영상 display(재생)함 (윈도우이름, 재생하고싶은 데이터(메트릭스)
  waitKey(0);
}
// Display a video
int main() {
  Mat frame;
  VideoCapture cap("background.mp4");
  while (1) {
    cap >> frame;
    imshow("Window", frame);
    waitKey(30); // 30ms 만큼 기다리겠다. 딜레이주겠다는 의미
  }
}
  • int waitKey(int delay=0)

Delay in milliseconds

waitKey(0) : 프레임을 일시정지한 것같은 효과. 계속 기다리겠다는 의미

 

이 게시물은 한동대학교 황성수 교수님의 컴퓨터비전 강의를 공부하며 정리한 내용입니다. 

'Computer Vision' 카테고리의 다른 글

[OpenCV] Drawing 함수(Drawing Function)  (0) 2020.01.11
[OpenCV] Mat 연산자(Mat operator)  (0) 2020.01.11
[컴퓨터 비전] 색공간의 이해  (0) 2020.01.09
[컴퓨터 비전] 디지털 영상/ 동영상의 기초  (0) 2020.01.09
[컴퓨터 비전] 컴퓨터비전(Computer Vision)이란?  (0) 2020.01.09
    'Computer Vision' 카테고리의 다른 글
    • [OpenCV] Drawing 함수(Drawing Function)
    • [OpenCV] Mat 연산자(Mat operator)
    • [컴퓨터 비전] 색공간의 이해
    • [컴퓨터 비전] 디지털 영상/ 동영상의 기초
    ygreenb
    ygreenb
    개발공부기록장

    티스토리툴바