[OpenCV] 영상 처리 주요 클래스

happy_quokka·2023년 10월 28일
0

OpenCV

목록 보기
2/11

Point_ 클래스

  • 2차원 점의 좌표 표현
  • 멤버 변수 : x, y
  • 멤버 함수
    • dot() : 내적
    • ddot() : double 내적
    • cross() : 외적
    • inside() : 어떠한 점이 사각형 안에 존재하는지 여부
  • 사칙 연산에 대한 연산자 오버로딩, << 연산자 오버로딩 지원

Size_ 클래스

  • 영상, 사각형의 크기 표현
  • 멤버 변수 : width, height
  • 멤버 함수
    • area() : 면적 계산
  • 사칙 연산에 대한 연산자 오버로딩, << 연산자 오버로딩 지원

Rect_ 클래스

  • 2차원 사각형 표현
  • 멤버 변수 : x, y, width, height
  • 멤버 함수
    • tl() : top left, 좌측 상단 점의 좌표 반환
    • br() : botton right, 오른쪽 하단 점의 좌표 반환
    • size() : width, height로 구성된 Size 객체 반환
    • area() : 면적 계산
    • contains() : 어떤 점이 사각형 안에 포함되어 있는지
  • 사칙 연산에 대한 연산자 오버로딩, << 연산자 오버로딩 지원

Range 클래스

  • 정수 값의 범위를 나타내기 위한 클래스
  • 멤버 변수 : start, end
  • 멤버 함수
    • size() : 범위 크기(end - start)를 반환
    • empty(): start == end 이면 true 반환
    • all() : start = INT_MIN, end = INT_MAX로 설정한 Range 객체를 반환
  • start는 범위에 포함되고 end는 범위에 포함되지 않는다 [start:end)

string 클래스

  • OpenCV 4.x부터는 std::string 클래스로 대체되었다
  • cv::format() 함수를 사용하여 형식 있는 문자열 생성 가능
String str1 = "hello";
cv::string str1 = "hi";

String filename = format("test%d.bmp", 5); //test5.bpm

Vec 클래스

  • 백터 표현
  • 벡터는 같은 자료형 원소 여러개로 구성된 데이터 형성 (열 벡터, 열의 크기가 1)
  • << 연산자, [] 연산자(행렬처럼 원소에 접근가능) 오버로딩 제공
  • std::vector는 배열을 대체하는 class 느낌
Vec2i vt(10,20) //int 10, 20을 원소로 가진 벡터

Vet 클래스 이름 재정의

  • 형식 : Vec <개수> { b | s | w | i | f | d }
  • { b | s | w | i | f | d }는 순서대로 uchar, short, unshort, int, float, double 의미
typedef Vec<uchar, 2> Vec2b;
typedef Vec<int, 2> Vec2i;
typedef Vec<float, 2> Vec2f;
typedef Vec<double, 2> Vec2d;

Scalar 클래스

  • 크기가 4인 double 배열 double val[4]를 멤버 변수로 가지고 있는 클래스
  • 4채널 이하의 영상에서 픽셀 값을 표현하는 용도로 주로 쓰인다
  • [] 연산자를 통해 원소에 접근 가능
Scalar yellow(0, 255, 255)
Scalar gray = 128

Mat 클래스

  • cv::Mat
  • n차원 1채널 또는 다채널 행렬 표현을 위한 클래스 (행렬, 영상, 텐서 등을 표현)
  • 멤버 변수
    • dims : 행렬의 차원 (일반적인 영상은 2)
    • rows, cols : 행렬의 행, 열 크은
    • uchar* data : 동적 할당된 메모리 영역 주소 (영상 pixel data)
  • 사칙 연산에 대한 연산자 오버로딩, << 연산자 오버로딩 지원

Mat 클래스의 깊이, 채널, 타입

깊이 (depth)

  • 행렬 원소가 사용하는 자료형 정보를 나타내는 매크로 상수
  • Mat::depth() 함수를 이용하여 참조
  • 형식 : CV_<비트수> { U | S | F }
define의미depthval 범위
CV_8Uuchar, unsigned char00 ~ 255
CV_8Ssigned char1-128 ~ 127
CV_16Uushort20 ~ 65535
CV_16Sshort3-32768 ~ 32767
CV_32Sint4-2,147,483,648 ~ 2,147,483,647
CV_32Ffloat5
CV_64Fdouble6
CV_16Ffloat16_t7

채널 (channel)

  • 원소 하나가 몇개의 값으로 구성되어 있는가
  • Mat::channels() 함수를 이용하여 참조
  • grayscale은 1개, color는 3개 (BGR)

타입 (type)

  • 행렬의 깊이와 채널 수를 한꺼번에 나타내는 매크로 상수
  • Mat::type() 함수를 이용하여 참조
  • 형식 : CV_<비트수> { U | S | F } C <채널수>
    • grayscale : CV_8UC1
    • color image : CV_8UC3

Mat 객체 생성

Mat img1; //빈 객체 생성
Mat img2(480, 640, CV_8UC1); //grayscale 이미지 생성 (세로 480,가로 640)
Mat img3(Size(640, 480), CV_8UC3); //color 이미지 생성 (세로 480,가로 640)

Mat img4(480, 640, CV_8UC1, Scalar(128)); //128값으로 초기화한 Mat 객체

Mat img5 = Mat::zeros(3, 3, CV_8UC1); //0으로 초기화
Mat img6 = Mat::ones(3, 3, CV_8UC1)//1으로 초기화
Mat img7 = Mat::eye(3, 3, CV_8UC1); //단위 행렬로 초기화

float data[] = {1, 2, 3, 4, 5, 6};
Mat mat(2, 3, CV_32FC1, data);

Mat mat2 = (Mat_<float>(2,3) << 1, 2, 3, 4, 5, 6);
Mat mat3 = Mat_<uchar>({2, 3}, {1, 2, 3, 4, 5, 6});

mat.create(256, 256, CV_8UC3);

mat = Scaler(255, 0, 0);
mat.setTo(1.f);

Mat 객체의 참조 & 복사

  • = 연산자는 참조(얕은 복사) 수행
  • Mat::clone(), Mat::copyTo() 함수를 이용하여 깊은 복사 수행
Mat img1 = imread("dog.png");

//참조 (얕은 복사)
Mat img2 = img1;
Mat img3;
img3 = img1; 

//깊은 복사
Mat img4 = img1.clone();
Mat img5;
img1.copyTo(img5);

부분 행렬 추출

  • () 연산자를 이용하여 부분 영상 추출 가능
  • () 연산자 안에는 Rect 객체를 지정하여 부분 영상의 위치와 크기 지정
  • 참조를 활용하여 ROI 연산 수행 가능
Mat img1 = imread("cat.bmp");

Mat img2 = img1(Rect(220, 120, 340, 240)); //참조
Mat img3 = img1(Rect(220, 120, 340, 240)).clone();

img2 = ~img2; //영상 반전, img1도 변함

Mat 영상의 픽셀 값 접근

  • Mat::data 멤버 변수가 픽셀 데이터 메모리 공간을 가리키지만 Mat 클래스 멤버 함수를 사용하는 방법을 권장
  • Mat::data의 경우 메모리 연산이 잘못될 경우 프로그램이 비정상 종료할 수 있다

Mat::at() 함수

template<typename _Tp> _Tp& Mat::at(int y, int x)
  • y : 참조 행 번호
  • x : 참조 열 번호
  • 반환값 : y행 x열 원소 값 (참조)
  • 좌표 지정이 직관적, 임의 좌표에 접근 가능
Mat mat1 = Mat::zeros(3, 4, CV_8UC1);

for(int y = 0; y < mat1.rows; y++){
	for(int x = 0; x < mat1.cols, x++){
    	mat1.at<uchar>(y, x)++;
    }
}

Mat::ptr() 함수

template<typename _Tp> _Tp* Mat::ptr(int y)
  • y : 참조 행 번호
  • 반환값 : y번 행의 시작 주소
  • Mat::at()보다 빠르게 동작, 행 단위 연산을 수행할 때 유리
for(int y = 0; y < mat1.rows; y++){
	uchar* p = mat1.ptr<uchar>(y);
    
    for(int x = 0; x < mat1.cols; x++){
    	p[x]++;
    }
}

MatIterator_< T > 반복자

  • OpenCV는 Mat 클래스와 함께 사용할 수 있는 반복자 클래스 템플릿 MatIterator_을 제공
  • MatIterator_는 클래스 템플릿이므로 사용할 때에는 Mat 행렬 타입에 맞는 자료형을 제공해야한다.
  • 좌표를 지정하지 않아서 안전, 성능은 느리다
  • Mat::begin() : 행렬의 첫번째 원소 위치 반환
  • Mat::end() : 행렬의 마지막 원소 바로 다음 위치 반환
for(MatIterator_<uchar> it = mat1.begin<uchar>(); it!=mat1.end<uchar>(); it++){
	(*it)++;
}

Mat 클래스 기본 행렬 연산

float data = {1, 1, 2, 3};
Mat mat1(2, 2, CV_32FC1, data);

Mat mat2 = mat1.inv(); //역행렬
Mat mat3 = mat1.t(); //tanspose

InputArray, OutputArray 클래스

  • OpenCV 함수에서 입력, 출력 인자로 사용
  • 주로 Mat 클래스를 대체하는 프록시 클래스
  • InputOutputArray 클래스도 있다

0개의 댓글