[OpenCV C++] 이미지 불러오고 저장하기 (Ubuntu CMakeLists, Command args 연결, Clion)
2023.04.19 - [Code/CMake] - [Ubuntu] VSCode CMake build&debug (C++)
2023.04.20 - [Code/C++] - [OpenCV C++] 이미지 저장하고 불러오기 , 창닫기 (CV 함수 설명)
🐣 목적 : CPP 파일을 Build 한 후 object file을 실행시킬 경우 args를 받아(입력 이미지, 출력이미지) 실행시키기!
🐣 방법 1 : CMakefile과 cpp 파일을 생성하고 clion으로 실행시킬 때 args를 넣기
🐣 방법 2 : CMakefile과 cpp 파일을 생성하고 shell 창을 통해 실행 시키기
📌 공통과정
- 아래와 같은 구조로 폴더를 구성해 준다
.
├── CMakeLists.txt #1
├── examples
│ ├── lenna.bmp
│ └── imgread.cpp
├── main.cpp
├── modules
│ ├── CMakeLists.txt #2
│ ├── module1
│ ├── CMakeLists.txt #3
│ ├── include > module1 > ClassMat.hpp
│ └── src > ClassMat.cpp
│
└── thirdparty
│
└── OpenCV
├── build
├── install
└── opencv
2023.04.18 - [Code/CMake] - Ubuntu - OpenCV 원하는 폴더에 build & Install
-> 이 부분을 참고해서 thirdparty내에 설치하면 된다 (단 -DCMAKE_BUILD_TYPE=Debug 모드로 진행)
총 3가지의 CMakeLists.txt를 작성해야하는데
#1은 전체 폴더에서 링크를 연결해준다고 생각하면 되고,
2번은 module1과 #1을 연결 module1 내부는 include를 찾을 수 있도록 해준다
CMakeLists.txt 🧡 #1
cmake_minimum_required(VERSION 3.16)
project(<project_name> LANGUAGES CXX) # CXX -> C++
set(CMAKE_CXX_STANDARD 14) # CMAKE_ : Depends on Cmake
set(CMAKE_CXX_STANDARD_REQUIRED ON) # only do 14 versions of cmake
add_subdirectory(modules)
add_executable(<project_name> main.cpp) # (project-name project.cpp)
# add_excutable을 통해서 실행할 파일을 생성
add_executable(read_img examples/imgread.cpp)
# target_link_libraries : target libraries 연결
target_link_libraries(read_img PRIVATE
module1
)
CMakeLists.txt 💚 #2
add_subdirectory(module1) // 하위 directory 연결을 위한 징검다리!
CMakeLists.txt 💜 #3
cmake_minimum_required(VERSION 3.16)
project(module1 LANGUAGES CXX) # CXX -> C++
set(CMAKE_CXX_STANDARD 14) # CMAKE_ : Depends on Cmake
set(CMAKE_CXX_STANDARD_REQUIRED ON) # only do 14 versions of cmake
set(MODULE1_SOURCE_FILES
src/ClassMat.cpp
) # Create a variable : MODULE1_SOURCE_FILES
add_library(module1
${MODULE1_SOURCE_FILES}
) # 위 변수에 있는 모든 소스파일들을 넣으려고 함
# REQUIRED : 없으면 build 안 하겠다
find_package(OpenCV REQUIRED HINTS ${CMAKE_SOURCE_DIR}/thirdparty/OpenCV/install/lib/cmake/opencv4)
if (OpenCV_FOUND)
message(STATUS "OpenCV Found! - ${OpenCV_DIR}")
endif()
#include_directories() # global 하위 cmake directory
target_include_directories(module1 PUBLIC
include
${OpenCV_INCLUDE_DIRS}
) # target header files folder
target_link_libraries(module1 PUBLIC
${OpenCV_LIBS} # link libraries 하고 싶어요!
)
이후에 hpp, cpp file들을 작성해 주자
🐍ClassMat.hpp🐍
# include "opencv2/opencv.hpp"
class ClassMat
{
public:
ClassMat() = default;
private:
cv::Mat cv_mat_;
};
🦕ClassMat.cpp🦕
#include "module1/ClassMat.hpp"
🐬imgread.cpp🐬
#include <iostream>
#include <typeinfo> // type information
#include <unistd.h> // dir
#include "opencv2/opencv.hpp"
int main(int argc, char* argv[]) // argc : input num, argv : input char s // char* argv[]와 char **argv는 모두 문자열 포인터 배열을 나타
{
std::string input_img;
std::string output_img;
// argc 가 몇 개인지 확인한 후 값을 사용할 것인지 아닌지 판단
if (argc == 2){
input_img = argv[1];
output_img = "./examples/result.png";
std::cout << "here!" << std::endl;
}
else if(argc == 3){
input_img = argv[1];
output_img = argv[2];
}
else{
input_img = "./examples/lenna.bmp";
output_img = "./examples/result.png";
}
// directory가 어디인지 궁금해서 넣어둔 부분 의미없음
char cwd[1024];
if (getcwd(cwd, sizeof(cwd)) != nullptr) {
std::cout << "Current working directory: " << cwd << std::endl;
} else {
std::cerr << "Failed to get current working directory\n";
return 1;
}
// 1. imread
cv::Mat src = cv::imread(input_img, cv::IMREAD_GRAYSCALE); // cmake-build-debug에서 실행됨으로,,,, 상위단으로 올라가서 다시 exaple로,,
// 2. file check
if (src.empty()) {
std::cerr << "Image laod failed!" << std::endl;
return -1;
}
// 3. img 조작
cv::Mat dst = 255 - src;
// 4. 조작된 이미지 저장 imwrite
cv::imwrite(output_img, dst);
// 5. 결과확인
cv::imshow("src", src);
cv::imshow("dst", dst);
cv::waitKey();
cv::destroyAllWindows();
}
🪄 방법 1
- 망치모양을 통해 빌드한 후 실행 시킬 경우 Run > Edit Configurations
🪄 방법 2
- build 후 shell 창에 입력
./cmake-build-debug/read_img ./examples/lenna.bmp
# <실행 파일의 경로> <read image arg> <write image arg>