OpenCV에 대해 알아보기 전에
OpenCV는 정적 라이브러리와 동적 라이브러리 두 가지 형태로 제공되지만
필자는 정적 라이브러리와 동적 라이브러리가 뭔지 모르기 때문에 동적 라이브러리, 정적 라이브러리가 무엇인지 먼저 알아보겠습니다.
정적 라이브러리와 동적 라이브러리는 모두 소프트웨어 개발에서 자주 사용되는 라이브러리 유형입니다.

장점
- 프로그램 실행 속도가 동적 라이브러리보다 빠름
- 라이브러리와 프로그램 간의 인터페이스가 안정적임
- 응용 프로그램이 다른 컴퓨터에서 실행될 때 라이브러리 버전 충돌 문제가 발생하지 않음
단점
- 프로그램 실행 파일의 크기가 커짐

장점
- 실행 파일의 크기를 줄일 수 있음
- 라이브러리를 공유하여 메모리를 절약
- 라이브러리가 업데이트될 때 응용 프로그램을 다시 컴파일할 필요 없이 라이브러리만 업데이트할 수 있음
단점
- 프로그램 실행 속도가 느림
- 라이브러리와 프로그램 간의 인터페이스 문제가 발생할 수 있음
- 다른 컴퓨터에서 실행될 때 라이브러리 버전 충돌 문제가 발생할 수 있음
따라서 정적 라이브러리는 안정성과 속도에 중점을 둔 응용 프로그램에 적합하고, 동적 라이브러리는 유연성과 효율성에 중점을 둔 응용 프로그램에 적합합니다.
*.dll, *.lib, *.h는 C/C++ 프로그램에서 외부 라이브러리를 사용하는 데 필요한 파일들입니다.
*.dll을 사용하는 이유
- 메모리 절약
여러 프로그램에서 동일한 라이브러리를 사용할 경우, 이 라이브러리는 하나만 메모리에 로드되고, 모든 프로그램에서 이 라이브러리를 참조할 수 있습니다. 따라서 메모리 사용량이 줄어들고, 시스템 성능이 향상됩니다.
- 코드의 재사용
동적 라이브러리를 사용하면 여러 프로그램에서 동일한 코드를 중복해서 작성하지 않아도 되므로, 코드의 재사용성이 높아집니다. 이는 개발 비용과 시간을 절약하는 데 큰 도움이 됩니다.
- 라이브러리 업데이트
동적 라이브러리를 사용하면 라이브러리가 업데이트될 때 응용 프로그램을 다시 컴파일할 필요 없이 라이브러리만 업데이트할 수 있습니다. 이는 프로그램 유지보수에 매우 유용합니다.
- 유연성
동적 라이브러리를 사용하면 프로그램이 실행될 때 필요한 라이브러리를 동적으로 로드할 수 있으므로, 프로그램의 유연성이 높아집니다. 이는 플러그인 시스템 등에서 매우 유용합니다.
정적 라이브러리 파일입니다. 라이브러리를 사용하는 프로그램과 함께 링크되어 실행 파일에 포함됩니다. 따라서 프로그램 실행 시 라이브러리를 별도로 로드할 필요가 없습니다.
*.lib를 사용하는 이유
- 실행속도
정적 라이브러리를 사용하면 라이브러리의 함수나 코드가 실행 파일에 포함되므로, 프로그램이 실행될 때 라이브러리를 별도로 로드할 필요가 없습니다. 따라서 실행 속도가 빨라집니다.
- 안정성
정적 라이브러리를 사용하면 라이브러리와 프로그램 간의 인터페이스가 안정적이며, 라이브러리 버전 충돌 문제가 발생하지 않습니다. 따라서 안정성이 높아집니다.
- 배포
정적 라이브러리를 사용하면 라이브러리 파일이 프로그램 실행 파일에 포함되므로, 라이브러리 파일을 따로 배포할 필요가 없습니다. 이는 프로그램 배포를 간편하게 할 수 있도록 도와줍니다.
- 플랫폼 호환성
정적 라이브러리를 사용하면 프로그램이 실행될 때 필요한 라이브러리가 없어도 실행이 가능합니다. 따라서 플랫폼 호환성이 높아집니다.
- 이식성
정적 라이브러리를 사용하면 라이브러리를 소스 코드와 함께 배포할 수 있으므로, 이식성이 높아집니다.
헤더 파일입니다. 라이브러리에서 제공하는 함수와 변수 등의 정보를 선언하는 파일로, 프로그램에서 해당 라이브러리의 기능을 사용하기 위해 필요한 정보를 제공합니다.

OpenCV는 컴퓨터 비전 및 이미지 처리 분야에서 사용되는 라이브러리로, 영상 처리, 물체 인식, 얼굴 인식 등 다양한 컴퓨터 비전 기능을 제공합니다. C++, Python, Java 등의 언어에서 사용할 수 있으며, 오픈 소스로 제공되어 있어 무료로 사용할 수 있습니다. OpenCV는 컴퓨터 비전 분야에서 널리 사용되는 라이브러리 중 하나이며, 영상 처리, 컴퓨터 비전 및 머신 러닝 등 다양한 분야에서 활용됩니다.
// 현재 사용하고 있는 OpenCV 라이브러리 버전 출력
std::cout << "OpenCV version : " << MessageBox(_T(CV_VERSION)) << std::endl;
// OpenCV에서 이미지를 다루기 위한 Mat 클래스 객체 img 생성
cv::Mat img;
// 이미지 파일을 읽어서 img 객체에 저장
img = cv::imread("Test-shinho-0301-2.bmp");
// 이미지 파일이 정상적으로 로드되지 않았을 때 예외 처리
if (img.empty())
{
// 에러 메시지 출력
MessageBox(_T("Image load failed"));
return;
}
// 윈도우 창 생성
cv::namedWindow("image");
// img 객체에 저장된 이미지를 윈도우 창에 출력
cv::imshow("image", img);
// 키 입력을 기다리며 윈도우 창이 유지되도록 함
cv::waitKey();


cv::imread()
이미지 파일을 읽어서 Mat 클래스 객체로 반환합니다.
cv::Mat cv::imread(const String& filename, int flags = cv::IMREAD_COLOR)imread 함수의 인자로는 이미지 파일의 경로와 파일 형식에 대한 정보를 전달합니다.
filename 인자는 읽어들일 이미지 파일의 경로와 파일 이름을 문자열 형태로 전달합니다.
flags 인자는 이미지 파일을 읽어들일 때 사용할 옵션을 전달합니다. 기본값은 IMREAD_COLOR으로, 이미지 파일을 컬러 이미지로 읽어들입니다. 이외에도 IMREAD_GRAYSCALE, IMREAD_UNCHANGED 등의 다양한 옵션이 있습니다.
imread 함수는 읽어들인 이미지를 Mat 클래스 객체로 반환합니다. 반환된 객체는 읽어들인 이미지의 픽셀 데이터를 가지고 있습니다.
Mat::empty()
Mat 객체가 비어있는지 여부를 반환합니다. 객체가 비어있으면 true를 반환하고, 그렇지 않으면 false를 반환합니다.
bool Mat::empty() constempty() 메서드는 객체가 초기화되었거나, 메모리 할당에 실패했을 때 등에 유용하게 사용될 수 있습니다. 예를 들어, imread() 함수로 이미지를 읽어들인 후, 해당 이미지가 비어있는지 여부를 empty() 메서드로 확인하여 예외 처리를 수행할 수 있습니다.
cv::namedWindow()
윈도우 창을 생성합니다.
void cv::namedWindow(const String& winname, int flags = cv::WINDOW_AUTOSIZE)winname: 생성할 윈도우 창의 이름을 전달합니다.
flags: 윈도우 창의 속성을 전달합니다. 기본값은 WINDOW_AUTOSIZE로, 윈도우 창 크기가 이미지 크기에 맞게 자동으로 조정됩니다. WINDOW_NORMAL, WINDOW_FULLSCREEN, WINDOW_OPENGL 등의 다양한 속성을 사용할 수 있습니다.
namedWindow() 함수를 호출하면, 지정한 이름을 가진 새로운 윈도우 창이 생성됩니다. 만약 같은 이름을 가진 윈도우 창이 이미 존재하는 경우, 해당 윈도우 창을 찾아내어 활성화합니다.
생성된 윈도우 창은 imshow() 함수로 이미지를 출력할 때 사용됩니다. imshow() 함수의 첫 번째 인자로 윈도우 창의 이름을 전달하면, 해당 윈도우 창에 이미지가 출력됩니다.
cv::imshow()
이미지를 화면에 출력합니다.
void cv::imshow(const String& winname, cv::InputArray mat)winname: 출력할 윈도우 창의 이름을 전달합니다.
mat: 출력할 이미지를 cv::Mat 클래스 객체로 전달합니다.
imshow() 함수를 호출하면, 지정한 이름을 가진 윈도우 창에 이미지가 출력됩니다. 이미지 출력 후, 사용자의 입력을 대기하기 위해 waitKey() 함수를 호출해야 합니다.
주의할 점은 imshow() 함수의 두 번째 인자로 전달되는 이미지는 cv::Mat 클래스 객체 뿐만 아니라, cv::UMat, cv::MatExpr, cv::cuda::GpuMat 등의 다양한 형태로 전달될 수 있다는 것입니다.
waitKey()
입력된 키보드 이벤트를 처리합니다.
int cv::waitKey(int delay = 0)delay: 키 입력 대기 시간을 밀리초 단위로 전달합니다. 기본값은 0으로, 무한정 대기합니다.
waitKey() 함수를 호출하면, 지정한 시간 동안 사용자의 입력을 대기합니다. 사용자가 키를 입력하면 해당 키의 ASCII 코드값이 반환됩니다. 입력된 키의 코드값이 없으면 -1을 반환합니다.
waitKey() 함수를 호출하는 이유는, imshow() 함수로 출력된 이미지가 화면에 보여지도록 하기 위해 사용자 입력을 대기해야 하기 때문입니다. waitKey() 함수는 이벤트 루프에서 사용되며, 대기하는 동안 다른 이벤트를 처리할 수 있도록 해 줍니다. 대기 시간이 0일 경우, 사용자 입력을 기다리지 않고 즉시 종료됩니다.
while (true)
{
int key = cv::waitKey(1); // 1ms 대기 후 사용자 입력 대기
if (key == 27) // ESC 키가 눌리면
{
cv::destroyAllWindows(); // 모든 윈도우 창 닫기
break; // 루프 종료
}
}
destroyAllWindows()
모든 윈도우 창을 닫습니다.
void cv::destroyAllWindows()destroyAllWindows() 함수를 호출하면, 현재 생성된 모든 윈도우 창을 닫습니다. 이 함수는 namedWindow() 함수로 생성한 모든 윈도우 창을 닫으며, createWindow() 함수로 생성한 윈도우 창은 닫지 않습니다.
(이어서...)
출처 :
1. https://www.vbflash.net/193
2. https://velog.io/@msj0130/OpenCV-C-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%B6%9C%EB%A0%A5%ED%95%B4%EB%B3%B4%EA%B8%B0