[OpenCV 강의] 4. image 다뤄보기

By New AI Engineer - 11월 04, 2023

안녕하세요 오랜만에 돌아온 OpenCV 강의입니다.
오늘은 OpenCV를 이용해서 좀 더 이미지를 심층적으로 다뤄볼 예정입니다.


1. 기본적인 데이터 타입


저번 시간에 기본적으로 사용되는 데이터 타입이 Mat을 이용하여 이미지를 저장해보았습니다. 기본적으로 이미지는 헤더와 픽셀 데이터가 포함 된 메모리 영역으로 저장되는데요.

이미지 헤더(Header)란 컴퓨터가 이미지를 읽을 때 필요한 정보들을 말하는데요. C언어에서도 미리 정의한 함수들을 넣는 장소를 헤더 파일이라고 하듯 이미지에서도 미리 정의한 이미지 정보들을 헤더에 넣어놓습니다.

예를들면 이미지 사이즈, 이미지의 비트 수, 컬러 공간 정보 및 채널 수를 말이죠.

이미지에서 말하는 채널이란 우리가 빛으로 색을 표현할때 빨강 초록 파랑(RGB)을 섞어서 모든 색을 만들어내듯 이러한 색의 강도를 담고있는 하나의 이미지를 하나의 채널이라고 말합니다. 

그레이 스케일(Gray scale) 이미지에는 하나의 채널이 있지만 컬러 이미지는 일반적으로 빨강, 초록 및 파랑 구성 요소에 대해 세 개가 있습니다 (OpenCV는 파란색, 녹색 및 빨간색의 역순으로 저장 함).

일반적으로 3개의 채널이 사용되지만 예외적으로 transparency(투명하고 이미지의 영역이긴 하지만 유리처럼 뒷 배경이 비침)을 사용할 수도 있습니다.

Mat img 이미지의 채널 수는 img.channels()로 값을 받아올 수 있습니다.

Mat img의 비트 심도는 img.depth()를 통해 얻을 수 있으며 반환되는 값은 다음과 같습니다.
  • CV_8U, 8-bit unsigned integers (0..255)
  • CV_8S, 8-bit signed integers (-128..127)
  • CV_16U, 16-bit unsigned integers (0..65,535)
  • CV_16S, 16-bit signed integers (-32,768..32,767)
  • CV_32S, 32-bit signed integers (-2,147,483,648..2,147,483,647)
  • CV_32F, 32-bit floating-point numbers
  • CV_64F, 64-bit floating-point numbers

그레이 스케일 및 컬러 이미지 모두에서 가장 일반적인 이미지 타입은 CV_8U가됩니다.
convertTo 함수를 사용하여 하나의 깊이에서 다른 깊이로 변환 할 수 있습니다.


Mat img = imread("lena.png",IMREAD_GRAYSCALE);
Mat fp;
img.convertTo(fp,CV_32F);

convertTo 함수는 선형 변환으로 구현되며 추가 할 스케일 인수와 델타 값을 각각 나타내는 두 개의 추가 매개 변수 인 alpha와 beta를가집니다. 

새로운 픽셀 값 = alpha * 현재 픽셀 값 + beta 

이는 부동 소수점 이미지를 화면에 올바르게 표시하는 데 사용할 수 있습니다.

img 소수점 이미지에 최소값과 최대 값이 있다고 가정할때 우리는 이를 화면에 표시하기 위해서는 일반적으로 사용되는 8bit 심도의 이미지로 변환해주어야 합니다.
(HDR을 지원하지 않는 모니터의 경우 8bit 심도의 밝기 값 밖에 표현하지 못하기 때문)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char *argv[]) 
{
    Mat m1 = Mat(200200, CV_32FC1);
    randu(m1, 01e6); // random values between 0 and 1e6
    imshow("original", m1);
    double minRange,MaxRange;
    Point mLoc,MLoc;
    minMaxLoc(m1,&minRange,&MaxRange,&mLoc,&MLoc);
    Mat img1;
    m1.convertTo(img1,CV_8U,255.0/(MaxRange-minRange),-255.0*minRange/(MaxRange-minRange));
    imshow("result", img1);
    waitKey(0);
    return 0;
}
cs

위 코드는 m1에 부동 소수점 이미지를 생성한 후 0~ 10^6 범위에 랜덤한 값을 넣고 화면에 디스플레이 하고(original) 최소, 최대 값을 구한 후 0~255 범위로 선형 변환 후 디스플레이(result)하는 코드입니다.


  • Share:

You Might Also Like

0 Comments