juuuding

[Open SW Project] OpenCV_tutorial 본문

인공지능/컴퓨터비전 기초

[Open SW Project] OpenCV_tutorial

jiuuu 2025. 1. 24. 00:49

💡#include <opencv2/opencv.hpp>

 OpenCV의 기본 API를 포함하는 헤더 파일. core, highgui, imgproc, calib3d, features2d  다양한 모듈을 한 번에 불러올 수 있다. 이 헤더 파일로 주요 OpenCV 기능을 쉽게 사용 가능하다. 

 

 - core: OpenCV의 핵심 기능. 기본 데이터 구조, 행렬 연산 등을 포함함. 예를 들어, cv::Mat, cv::Scalar, cv::Size 등.

 - highgui: GUI 및 이미지/비디오 입출력을 위한 모듈. 예를 들어. cv::imshow(), cv::waitKey(), cv::imread() 등.

 - imgproc: 필터링, 엣지 검출, 모폴로지 연산 등 이미지를 처리하는 기능. cv::cvtColor(), cv::GaussianBlur(), cv::threshold등

 - calib3d: 카메라 보정 및 3D 재구성 기능.

 - features2d: 2D 피처 추출 및 매칭. 

 

💡메모리 할당 및 해제 (Memory allocation/release)

  •  Mat

 Mat 클래스는 n-dimensional dense array 클래스로, OpenCV에서 이미지를 포함한 행렬 데이터를 저장하고 처리하는데 사용되는 자료구조다. 이 클래스에는 실수 또는 복소수 값의 벡터, 행렬을 저장할 수 있고, grayscale 및 color 이미지를 저장할 수 있다. 아래 보다시피 Mat 객체는 행, 열, 채널로 구성되고, 각 요소(픽셀)은 특정 데이터 유형과 채널 개수를 가진다. 

 

  • Mat Constructors(생성자) <- 메모리 할당
//기본 생성자(빈 객체 생성)
Mat M;

//행, 열 및 데이터 유형 지정
Mat M(rows, cols, type);

//크기(Size) 객체 사용
Mat M(Size(width, height), type);

//초기화 값 설정<- BGR (255,0,0) 이므로 파란색으로 초기화 한 것.
Mat M(rows, cols, type, Scalar(255, 0, 0));

//create() 함수 사용 <- 기존 데이터 삭제하고 새로운 크기로 메모리 재할당
M.create(100, 60, CV_8UC3);	// 기존 행렬 M의 데이터 삭제하고 100x60 크기의 3채널 color 행렬

 

  • Mat 객체 메모리 해제(Release) - M.release()

 OpenCV의 Mat 클래스는 main 함수의 끝에서 이 command가 자동으로 호출된다. 따라서 내가 직접 추가할 필요는 없다. 

 

  • Mat 데이터 타입

 OpenCV에서 지원하는 데이터 타입은 다음과 같다. 

 

  * multi-channel type을 지정할 때는 CV_MAKETYPE(CV_8U, 3) 처럼 매크로를 통해 동적으로 채널을 지정할 수도 있다. 이렇게 작성하면 8비트 부호 없는 정수로 이루어진 3채널을 의미한다.

// 7x7 크기의 복소수 행렬(1+3i) 
Mat M(7, 7, CV_32FC2, Scalar(1, 3));

// M을 100x60 크기의 3채널 8비트 행렬로 재할당
M.create(100, 60, CV_8UC3);

 

 

💡Image read/write

  • imread()

    - Mat cv::imread(const String& filename, int flags=IMREAD_COLOR)

     + filename: 로드할 파일의 이름

     + flags: cv::ImreadModes 값

   - 파일로부터 이미지를 불러옴

   - 이미지를 읽을 수 없는 경우(경로 잘못됨, 지원하지 않는 형식, 접근 불가 등) empty matrix를 반환함

     -> Mat::data==NULL.

   - 지원하는 파일 형식: .bmp, .jpeg, .jpg, .jp2, .png, .pbm, .ppm, .tiff, .tif

// lena.jpg 이미지 파일을 img라는 행렬에 저장
Mat img = imread("lena.jpg", IMREAD_COLOR);

 

   - imread()의 flags

 

  • imwrite()

    - bool cv::imwrite(const String& filename, InputArray img, const std::vector<int>& param=std::vector<int>())

     + filename: 로드할 파일의 이름

     + img: 저장할 이미지

     + params: 형식 지정 파라미터

   - imwrite()의 flags

Mat img = imread("lena.jpg", IMREAD_COLOR);
cvtColor(img, img, COLOR_RGB2GRAY);	//RGB img를 gray scale img로 변환
imwrite("lena_gray.png", img);	// gray scale로 바꾼 이미지를 저장

 

 

💡Image show

  • namedWindow()

   - void cv::namedWindow(const String& winname, int flags=WINDOW_AUTOSIZE)

   - 윈도우를 만듦

   - namedWindow()의 flags

 

  • imshow()

   - void cv::imshow(const String& winnname, InputArray mat)

    + mat: show할 이미지

   - 특정 윈도우에 이미지를 display함. 만약 윈도우가 미리 만들어져있지 않다 cv::WINDOW_AUTOSIZE로 윈도우를 만들었다 가정함

   - 이미지의 depth에 따라 scale함

    + 8bit unsigned: 그대로 display

    + 16bit unsigned or 32bit interger: 픽셀 값을 256으로 나눔. [0,255*256] 범위가 [0,255]로 매핑됨.

    + 32bit or 64bit floating-point: 픽셀 값을 255로 곱함. 값의 범위가 [0,1] 범위가 [0,255]로 매핑됨.

 

 

💻Practice

 OpenCV를 사용해서 두 개의 이미지를 blending(Adding)해보자. documentation에서 addWeighted()를 찾아 사용하면 된다.

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() {

	double alpha = 0.5; double beta; double input;
	Mat src1, src2, dst;

	cout << "Simple Linear Blender" << endl;
	cout << "---------------------" << endl;
	cout << "* Enter alpha [0.0-1.0]: " << endl;
	cin >> input;

	if (input >= 0 && input <= 1) {
		alpha = input;
	}

	
	src1 = imread("C:/Users/user/Desktop/2025-winter/OSP/skeleton code-Lec01/LinuxLogo.jpg", IMREAD_COLOR);
	src2 = imread("C:/Users/user/Desktop/2025-winter/OSP/skeleton code-Lec01/WindowsLogo.jpg", IMREAD_COLOR);

	if (src1.empty()) { cout << "Error loading src1" << endl; return -1; }
	if (src2.empty()) { cout << "Error loading src2" << endl; return -1; }

	beta = (1.0 - alpha);

	addWeighted(src1, alpha, src2, beta, 0, dst);       //dst = src1*alpha + src2*beta + gamma;

	imshow("Linear Blend", dst);

	waitKey(0);


	return 0;
}

 

 

 - 결과 => alpha에 0.5입력 시

 

 - 결과 => alpha에 1.0 입력 시

 - 결과 => alpha에 0 입력 시