From 0b541348b05d8c301c22e070e5d235d425969fd1 Mon Sep 17 00:00:00 2001 From: "Kueffner, Maximilian" Date: Fri, 14 Mar 2025 19:32:40 +0100 Subject: [PATCH] can render 2 cv::mats --- .dir-locals.el | 6 +++- CMakeLists.txt | 11 ++++--- lib/CMakeLists.txt | 2 ++ lib/imaging/CMakeLists.txt | 23 +++++++++++++ lib/imaging/Image.cpp | 15 +++++++++ lib/imaging/Image.hpp | 32 ++++++++++++++++++ lib/rendering/CMakeLists.txt | 15 +++++++++ lib/rendering/CvMatRender.cpp | 49 +++++++++++++++++++++++++++ lib/rendering/CvMatRender.hpp | 30 +++++++++++++++++ lib/utilities/ILog.hpp | 21 ++++++++++++ lib/utilities/SpdLogger.hpp | 19 +++++++++++ src/AppGLFW.cpp | 62 +++++++++++++++++++++++++++++++++-- src/AppGLFW.hpp | 10 +++++- src/main.cpp | 2 +- src/uiresources.h.in | 5 ++- 15 files changed, 290 insertions(+), 12 deletions(-) create mode 100644 lib/CMakeLists.txt create mode 100644 lib/imaging/CMakeLists.txt create mode 100644 lib/imaging/Image.cpp create mode 100644 lib/imaging/Image.hpp create mode 100644 lib/rendering/CMakeLists.txt create mode 100644 lib/rendering/CvMatRender.cpp create mode 100644 lib/rendering/CvMatRender.hpp create mode 100644 lib/utilities/ILog.hpp create mode 100644 lib/utilities/SpdLogger.hpp diff --git a/.dir-locals.el b/.dir-locals.el index aa64a27..a75c213 100644 --- a/.dir-locals.el +++ b/.dir-locals.el @@ -1,4 +1,8 @@ ;;; Directory Local Variables -*- no-byte-compile: t -*- ;;; For more information see (info "(emacs) Directory Variables") -((nil . ((compile-command . "cmake -B build -S . && cmake --build build")))) +((nil . ((compile-command . + (eval + (format "cmake -B build -S . -DCMAKE_C_COMIPLER=%S -DCMAKE_CXX_COMIPLER=%S -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DFETCHCONTENT_FULLY_DISCONNECTED=OFF -G Ninja && cmake --build build" + (executable-find "clang") + (executable-find "clang++"))))))) diff --git a/CMakeLists.txt b/CMakeLists.txt index c35375c..97cafb6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,9 +11,6 @@ set(glfw_DIR ${PROJECT_SOURCE_DIR}/modules/glfw) set(pfd_DIR ${PROJECT_SOURCE_DIR}/modules/portable-file-dialogs) set(spdlog_DIR ${PROJECT_SOURCE_DIR}/modules/spdlog) -include(cmake/libCZI.cmake) - -find_package(OpenCV REQUIRED) find_package(OpenGL REQUIRED) message(STATUS "IMGUI:\t" ${imgui_DIR}) @@ -38,6 +35,7 @@ add_subdirectory(${pfd_DIR}) add_subdirectory(${spdlog_DIR}) add_subdirectory(${glfw_DIR}) add_subdirectory(src) +add_subdirectory(lib) set(SRC src/AppGLFW.cpp @@ -52,12 +50,15 @@ set(SRC add_executable(${PROJECT_NAME} ${SRC}) +message(STATUS "Linking " pixelariumimagelib) target_link_libraries(${PROJECT_NAME} - LINK_PUBLIC ${OpenCV_LIBS}) + PRIVATE pixelariumimagelib + PRIVATE pixelariumrenderlib) target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/src - PUBLIC ${OpenCV_INCLUDE_DIRS} + PUBLIC ${PROJECT_SOURCE_DIR}/lib + PUBLIC ${PROJECT_SOURCE_DIR}/lib/imaging PUBLIC ${imgui_DIR} PUBLIC ${imgui_DIR}/backends PUBLIC ${glfw_INCLUDE_DIR} diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt new file mode 100644 index 0000000..9480cb7 --- /dev/null +++ b/lib/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(imaging) +add_subdirectory(rendering) \ No newline at end of file diff --git a/lib/imaging/CMakeLists.txt b/lib/imaging/CMakeLists.txt new file mode 100644 index 0000000..8afdacc --- /dev/null +++ b/lib/imaging/CMakeLists.txt @@ -0,0 +1,23 @@ +include(${CMAKE_SOURCE_DIR}/cmake/libCZI.cmake) + +find_package(OpenCV REQUIRED) + +message(STATUS "Found opencv: " ${OpenCV_INCLUDE_DIRS}) +message(STATUS "OpenCV_LIBs from: " ${OpenCV_LIBS}) + +set(IMAGELIBSRC + Image.cpp) + +set(IMAGELIBLIBNAME pixelariumimagelib) + +add_library(${IMAGELIBLIBNAME} + STATIC ${IMAGELIBSRC}) + +target_link_libraries(${IMAGELIBLIBNAME} + PUBLIC ${OpenCV_LIBS} + PRIVATE libCZIStatic) + + +target_include_directories(${IMAGELIBLIBNAME} + PUBLIC ${OpenCV_INCLUDE_DIRS} + PRIVATE ${LIBCZI_INCLUDE_DIR}) \ No newline at end of file diff --git a/lib/imaging/Image.cpp b/lib/imaging/Image.cpp new file mode 100644 index 0000000..1f3988f --- /dev/null +++ b/lib/imaging/Image.cpp @@ -0,0 +1,15 @@ +#include "Image.hpp" + +#include +#include +#include + +pixelarium::imaging::Image::Image(const std::string& uri) +{ + if (!std::filesystem::exists(uri)) + { + throw std::runtime_error("File not found"); + } + + this->_img = cv::imread(uri); +} \ No newline at end of file diff --git a/lib/imaging/Image.hpp b/lib/imaging/Image.hpp new file mode 100644 index 0000000..564b8db --- /dev/null +++ b/lib/imaging/Image.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace pixelarium::imaging +{ +class Image +{ + public: + + explicit Image(const std::string& uri); + + // get back the defaults + Image() = default; + Image(const Image& other) = default; + Image(Image&& other) noexcept = default; + Image& operator=(const Image& other) = default; + Image& operator=(Image&& other) noexcept = default; + ~Image() = default; + + const cv::Mat& GetImage() const { return this->_img; } + + private: + cv::Mat _img; +}; + +} // namespace pixelarium::imaging \ No newline at end of file diff --git a/lib/rendering/CMakeLists.txt b/lib/rendering/CMakeLists.txt new file mode 100644 index 0000000..486adb3 --- /dev/null +++ b/lib/rendering/CMakeLists.txt @@ -0,0 +1,15 @@ +set(RENDERSRC) + +set(RENDERLIBNAME pixelariumrenderlib) + +set(RENDERLIBSRC + CvMatRender.cpp) + +add_library(${RENDERLIBNAME} STATIC + ${RENDERLIBSRC}) + +target_link_libraries(${RENDERLIBNAME} + PRIVATE pixelariumimagelib) + +target_include_directories(${RENDERLIBNAME} + PRIVATE ${CMAKE_SOURCE_DIR}/lib) \ No newline at end of file diff --git a/lib/rendering/CvMatRender.cpp b/lib/rendering/CvMatRender.cpp new file mode 100644 index 0000000..e678d07 --- /dev/null +++ b/lib/rendering/CvMatRender.cpp @@ -0,0 +1,49 @@ +#include "CvMatRender.hpp" +#include + +using namespace pixelarium::imaging; + +pixelarium::render::CvMatRender::CvMatRender(const Image& img) +{ + this->_img = img.GetImage(); + this->_texture = 0; + + cv::cvtColor(this->_img, this->_img, cv::COLOR_BGR2RGBA); +} + +/*static*/ void pixelarium::render::matToTexture(const cv::Mat& image, GLuint* texture) +{ + glGenTextures(1, texture); + glBindTexture(GL_TEXTURE_2D, *texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + // auto image = img.GetImage(); + switch (image.type()) + { + case CV_16U: + case CV_16UC3: + case 26: + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.cols, image.rows, 0, + GL_RGBA, GL_UNSIGNED_SHORT, image.data); + break; + case 5: + case 29: + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.cols, image.rows, 0, + GL_RGBA, GL_FLOAT, image.data); + break; + default: + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.cols, image.rows, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image.data); + break; + } +} + +GLuint pixelarium::render::CvMatRender::Render() +{ + matToTexture(this->_img, &this->_texture); + return this->_texture; +} diff --git a/lib/rendering/CvMatRender.hpp b/lib/rendering/CvMatRender.hpp new file mode 100644 index 0000000..2b05b27 --- /dev/null +++ b/lib/rendering/CvMatRender.hpp @@ -0,0 +1,30 @@ +#pragma once +#ifdef _WIN32 +#include +#include +#else +#define GL_SILENCE_DEPRECATION +#if defined(IMGUI_IMPL_OPENGL_ES2) +#include +#endif +#include // Will drag system OpenGL headers +#endif +#include "imaging/Image.hpp" + +namespace pixelarium::render +{ + static void matToTexture(const cv::Mat& image, + GLuint* texture); +class CvMatRender +{ + public: + explicit CvMatRender(const pixelarium::imaging::Image& img); + // void* Render(); + GLuint Render(); + + private: + cv::Mat _img; + GLuint _texture; +}; + +} // namespace pixelarium::render \ No newline at end of file diff --git a/lib/utilities/ILog.hpp b/lib/utilities/ILog.hpp new file mode 100644 index 0000000..b754505 --- /dev/null +++ b/lib/utilities/ILog.hpp @@ -0,0 +1,21 @@ +#pragma once +#include + +namespace pixelarium::utils::log +{ +class ILog +{ + public: + virtual void Info(const std::string& msg, + const std::string& source = "") = 0; + virtual void Debug(const std::string& msg, + const std::string& source = "") = 0; + virtual void Warn(const std::string& msg, + const std::string& source = "") = 0; + virtual void Error(const std::string& msg, + const std::string& source = "") = 0; + + virtual ~ILog() {} +}; + +} // namespace pixelarium::utils \ No newline at end of file diff --git a/lib/utilities/SpdLogger.hpp b/lib/utilities/SpdLogger.hpp new file mode 100644 index 0000000..bcf9b5f --- /dev/null +++ b/lib/utilities/SpdLogger.hpp @@ -0,0 +1,19 @@ +#pragma once +#include "ILog.hpp" +namespace pixelarium::utils::log +{ +class SpdLogger : public ILog +{ + public: + SpdLogger(const std::string& file_sink); + + void Info(const std::string& msg, + const std::string& source = "") override; + void Debug(const std::string& msg, + const std::string& source = "") override; + void Warn(const std::string& msg, + const std::string& source = "") override; + void Error(const std::string& msg, + const std::string& source = "") override; +}; +} // namespace pixelarium::utils::log \ No newline at end of file diff --git a/src/AppGLFW.cpp b/src/AppGLFW.cpp index d036b15..4e95b3d 100644 --- a/src/AppGLFW.cpp +++ b/src/AppGLFW.cpp @@ -1,9 +1,15 @@ #include "AppGLFW.hpp" +#include "imgui.h" + +#include "imaging/Image.hpp" #include "portable-file-dialogs.h" +#include "rendering/CvMatRender.hpp" #include "uiresources.h" -ui::AppGLFW::AppGLFW() +using namespace pixelarium::imaging; + +pixelarium::ui::AppGLFW::AppGLFW() { glfwSetErrorCallback(glfw_error_callback); if (!glfwInit()) @@ -91,7 +97,7 @@ ui::AppGLFW::AppGLFW() ImGui_ImplOpenGL3_Init(glsl_version); } -int ui::AppGLFW::Run() +int pixelarium::ui::AppGLFW::Run() { ImGuiIO& io = ImGui::GetIO(); (void)io; @@ -103,7 +109,17 @@ int ui::AppGLFW::Run() ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); - ImGui::DockSpaceOverViewport(ImGui::GetID("MainDockSpace")); + ImGui::DockSpaceOverViewport(ImGui::GetID("Backspace")); + + this->MenuBar(); + + if (this->_imagep) + { + auto render = render::CvMatRender(this->_img); + ImGui::Begin("An image", &this->_imagep, NULL); + ImGui::Image(render.Render(), ImVec2(this->_img.GetImage().cols, this->_img.GetImage().rows)); + ImGui::End(); + } // Rendering ImGui::Render(); @@ -133,3 +149,43 @@ int ui::AppGLFW::Run() return 0; } + +void pixelarium::ui::AppGLFW::MenuBar() +{ + if (ImGui::BeginMainMenuBar()) + { + // main menu + if (ImGui::BeginMenu(MAINMENUNAME)) + { + ImGui::EndMenu(); + } + + // file menu + if (ImGui::BeginMenu(FILEMENUNAME)) + { + if (ImGui::MenuItem("Load File")) + { + this->LoadImageProt(); + } + + ImGui::EndMenu(); + } + + ImGui::EndMainMenuBar(); + } +} + +void pixelarium::ui::AppGLFW::LoadImageProt() +{ + auto res{pfd::open_file("Load Inputs", pfd::path::home(), + {"All Files", "*"}, pfd::opt::multiselect) + .result()}; + for (auto& p : res) + { + // lg::Logger::Debug("Adding image from " + std::string(p), + // __FUNCTION__); + + this->_img = Image(p); + this->_imagep = true; + } +} \ No newline at end of file diff --git a/src/AppGLFW.hpp b/src/AppGLFW.hpp index 696f67b..ca69ff6 100644 --- a/src/AppGLFW.hpp +++ b/src/AppGLFW.hpp @@ -1,13 +1,15 @@ #pragma once #include + #include +#include "Image.hpp" #include "imgui.h" #include "imgui_impl_glfw.h" #include "imgui_impl_opengl3.h" -namespace ui +namespace pixelarium::ui { enum LogLevelSelection { @@ -23,10 +25,16 @@ class AppGLFW AppGLFW(); int Run(); + private: + void MenuBar(); + void LoadImageProt(); + private: LogLevelSelection log_level_ = static_cast(0); GLFWwindow* window = nullptr; ImGuiWindowFlags window_flags = 0; + pixelarium::imaging::Image _img; + bool _imagep { false }; }; static void glfw_error_callback(int error, const char* description) diff --git a/src/main.cpp b/src/main.cpp index 6952495..113630e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,7 +5,7 @@ int main(int argc, char** argv) { std::cout << "ok\n"; - auto app = ui::AppGLFW(); + auto app = pixelarium::ui::AppGLFW(); return app.Run(); } \ No newline at end of file diff --git a/src/uiresources.h.in b/src/uiresources.h.in index ef02a8b..706bc9c 100644 --- a/src/uiresources.h.in +++ b/src/uiresources.h.in @@ -2,4 +2,7 @@ /*-- Gets filled in during the cmake configuration step --*/ -#cmakedefine PIXELARIUM_TITLE "@PIXELARIUM_TITLE@" \ No newline at end of file +#cmakedefine PIXELARIUM_TITLE "@PIXELARIUM_TITLE@" + +#define MAINMENUNAME "Menu" +#define FILEMENUNAME "File" \ No newline at end of file