juuuding
[Open SW Project] OpenCV_tutorial 본문
💡#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 입력 시
'인공지능 > 컴퓨터비전 기초' 카테고리의 다른 글
[Open SW Project] Lec02_Image display and geometric transform (0) | 2025.01.23 |
---|---|
[Open SW Project] Lec01_Fundamentals (0) | 2025.01.19 |
[Open SW Project] Lec00_Introduction (0) | 2025.01.18 |