From 135e659301a3f767a05da1d6a3cc472d1563402d Mon Sep 17 00:00:00 2001 From: Larry Gritz Date: Fri, 16 Aug 2024 08:44:28 -0700 Subject: [PATCH] build: Don't link libOpenImageIO against OpenCV (#4363) Fully linking OpenCV against libOpenImageIO is burdensome for people downstream, especially those who want a static version of libOpenImageIO. There were only three IBA functions that use OpenCV: to_OpenCV(), from_OpenCV(), and capture_image(), and all three are fairly short. Move them to a separate header, imagebufalgo_opencv.h, make them fully INLINE (so they don't actually produce object code in libOpenImageIO, which therefore does not need to link against OpenCV). Applications wanting these three functions should include this header and will be responsible themselves for ensuring that the include paths and linkage of their application makes provisions for finding and using OpenCV. All other applications don't need to deal with OpenCV dependency at all. Our own oiiotool (for --capture) and our python bindings still link against OpenCV to support this functionality (again, still as an optional dependency, enabled only if OpenCV is found at build time). But downstream apps using libOpenImageIO and who do not themselves need our OpenCV functioality now no longer need to link against OpenCV. We have removed capture_image() from the Python bindings -- Python scripts that need to capture live camera images can use OpenCV or any other capture API of their choice without going through OIIO. Signed-off-by: Larry Gritz --- docs/Deprecations-3.0.md | 17 ++ src/cmake/fancy_add_executable.cmake | 1 + src/cmake/modules/FindOpenCV.cmake | 7 +- src/cmake/pythonutils.cmake | 6 +- src/doc/pythonbindings.rst | 12 - src/include/OpenImageIO/imagebufalgo.h | 38 --- .../OpenImageIO/imagebufalgo_opencv.h} | 247 +++++++++--------- src/include/OpenImageIO/imageio.h | 6 - src/include/imageio_pvt.h | 1 - src/libOpenImageIO/CMakeLists.txt | 8 +- src/libOpenImageIO/imagebufalgo_test.cpp | 12 +- src/libOpenImageIO/imageio.cpp | 4 - src/oiiotool/CMakeLists.txt | 3 +- src/oiiotool/oiiotool.cpp | 13 +- src/python/CMakeLists.txt | 5 +- src/python/py_imagebufalgo.cpp | 24 -- 16 files changed, 175 insertions(+), 229 deletions(-) rename src/{libOpenImageIO/imagebufalgo_opencv.cpp => include/OpenImageIO/imagebufalgo_opencv.h} (52%) diff --git a/docs/Deprecations-3.0.md b/docs/Deprecations-3.0.md index 3200e3ea28..49f930e404 100644 --- a/docs/Deprecations-3.0.md +++ b/docs/Deprecations-3.0.md @@ -86,6 +86,14 @@ about being deprecated will be removed in the final 3.0 release. deprecated since OIIO 1.5, now has deprecation warnings. Use `interppixel_NDC()` instead. +## imageio.h + +* The global OIIO::attribute query "opencv_version" has been removed. The + libOpenImageIO library itself no longer has OpenCV as a dependency or links + against it. (However, the IBA functions involving OpenCV still exist and are + defined in `imagebufalgo_opencv.h` as inline functions, so it is up to the + application calling these API functions to find and link against OpenCV.) + ## imagebufalgo.h * The old versions (deprecated since 2.0) of IBA::compare() and @@ -111,6 +119,8 @@ about being deprecated will be removed in the final 3.0 release. cv::Mat. * The pre-KWArgs versions of resize, warp, and fit now have deprecation warnings. Use the versions that take KWArgs instead. +* The OpenCV-related functions `to_OpenCV()`, `from_OpenCV()`, and + `capture_image()` have moved to the `imagebufalgo_opencv.h` header. ## imagebufalgo_util.h @@ -193,3 +203,10 @@ about being deprecated will be removed in the final 3.0 release. it defines. +## python bindings + +* The `ImageBufAlgo.capture_image()` function has been removed from the + Python bindings. Python scripts that wish to capture images from live + cameras should use OpenCV or other capture APIs of choice and then + pass the results to OIIO to construct an ImageBuf. + diff --git a/src/cmake/fancy_add_executable.cmake b/src/cmake/fancy_add_executable.cmake index e00e48bfac..ae3729f2f6 100644 --- a/src/cmake/fancy_add_executable.cmake +++ b/src/cmake/fancy_add_executable.cmake @@ -20,6 +20,7 @@ # fancy_add_executable ([ NAME targetname ... ] # [ SRC source1 ... ] # [ INCLUDE_DIRS include_dir1 ... ] +# [ SYSTEM_INCLUDE_DIRS include_dir1 ... ] # [ DEFINITIONS FOO=bar ... ]) # [ COMPILE_OPTIONS -Wno-foo ... ] # [ LINK_LIBRARIES external_lib1 ... ] diff --git a/src/cmake/modules/FindOpenCV.cmake b/src/cmake/modules/FindOpenCV.cmake index c1b4ffc535..118619c4ba 100644 --- a/src/cmake/modules/FindOpenCV.cmake +++ b/src/cmake/modules/FindOpenCV.cmake @@ -15,12 +15,9 @@ find_path (OpenCV_INCLUDE_DIR NAMES opencv4/opencv2/opencv.hpp opencv2/opencv.hpp - PATHS - /opt/local/include - /usr/local/opt/opencv4 - /usr/local/opt/opencv3 + PATHS /opt/local/include /usr/local/opt/opencv4 PATH_SUFFIXES opencv4 - ) + ) set (_ocv_include_root "${OpenCV_INCLUDE_DIR}") if (OpenCV_INCLUDE_DIR AND EXISTS "${OpenCV_INCLUDE_DIR}/opencv4/opencv2/core/version.hpp") diff --git a/src/cmake/pythonutils.cmake b/src/cmake/pythonutils.cmake index ac7fb617a0..c5f4720400 100644 --- a/src/cmake/pythonutils.cmake +++ b/src/cmake/pythonutils.cmake @@ -63,7 +63,7 @@ endmacro() # pybind11 macro (setup_python_module) - cmake_parse_arguments (lib "" "TARGET;MODULE" "SOURCES;LIBS" ${ARGN}) + cmake_parse_arguments (lib "" "TARGET;MODULE" "SOURCES;LIBS;INCLUDES;SYSTEM_INCLUDE_DIRS" ${ARGN}) # Arguments: args... set (target_name ${lib_TARGET}) @@ -79,6 +79,10 @@ macro (setup_python_module) # add_library (${target_name} MODULE ${lib_SOURCES}) # # Declare the libraries it should link against + target_include_directories (${target_name} + PRIVATE ${lib_INCLUDES}) + target_include_directories (${target_name} + SYSTEM PRIVATE ${lib_SYSTEM_INCLUDE_DIRS}) target_link_libraries (${target_name} PRIVATE ${lib_LIBS}) diff --git a/src/doc/pythonbindings.rst b/src/doc/pythonbindings.rst index 4de35f6210..eb4b90f9a1 100644 --- a/src/doc/pythonbindings.rst +++ b/src/doc/pythonbindings.rst @@ -3698,18 +3698,6 @@ Import / export -.. py:method:: ImageBuf ImageBufAlgo::capture_image (cameranum, convert = OpenImageIO.UNKNOWN) - - Capture a still image from a designated camera. - - Example: - - .. code-block:: python - - WebcamImage = ImageBufAlgo.capture_image (0, OpenImageIO.UINT8) - WebcamImage.write ("webcam.jpg") - - Functions specific to deep images --------------------------------- diff --git a/src/include/OpenImageIO/imagebufalgo.h b/src/include/OpenImageIO/imagebufalgo.h index fcc78e1aa9..10905b0271 100644 --- a/src/include/OpenImageIO/imagebufalgo.h +++ b/src/include/OpenImageIO/imagebufalgo.h @@ -23,14 +23,6 @@ #include -#if !defined(__OPENCV_CORE_TYPES_H__) && !defined(OPENCV_CORE_TYPES_H) -struct IplImage; // Forward declaration; used by Intel Image lib & OpenCV -namespace cv { - class Mat; -} -#endif - - OIIO_NAMESPACE_BEGIN @@ -2345,36 +2337,6 @@ bool OIIO_API make_texture (MakeTextureMode mode, /// @} -/// Convert an OpenCV cv::Mat into an ImageBuf, copying the pixels (optionally -/// converting to the pixel data type specified by `convert`, if not UNKNOWN, -/// which means to preserve the original data type if possible). Return true -/// if ok, false if it was not able to make the conversion from Mat to -/// ImageBuf. Any error messages can be retrieved by calling `geterror()` on -/// the returned ImageBuf. If OpenImageIO was compiled without OpenCV support, -/// this function will return false. -OIIO_API ImageBuf -from_OpenCV (const cv::Mat& mat, TypeDesc convert = TypeUnknown, - ROI roi={}, int nthreads=0); - -/// Construct an OpenCV cv::Mat containing the contents of ImageBuf src, and -/// return true. If it is not possible, or if OpenImageIO was compiled without -/// OpenCV support, then return false. Any error messages can be retrieved by -/// calling OIIO::geterror(). Note that OpenCV only supports up to 4 channels, -/// so >4 channel images will be truncated in the conversion. -OIIO_API bool to_OpenCV (cv::Mat& dst, const ImageBuf& src, - ROI roi={}, int nthreads=0); - - -/// Capture a still image from a designated camera. If able to do so, -/// store the image in dst and return true. If there is no such device, -/// or support for camera capture is not available (such as if OpenCV -/// support was not enabled at compile time), return false and do not -/// alter dst. -ImageBuf OIIO_API capture_image (int cameranum = 0, - TypeDesc convert=TypeUnknown); - - - /// Return the "deep" equivalent of the "flat" input `src`. Turning a flat /// image into a deep one means: /// diff --git a/src/libOpenImageIO/imagebufalgo_opencv.cpp b/src/include/OpenImageIO/imagebufalgo_opencv.h similarity index 52% rename from src/libOpenImageIO/imagebufalgo_opencv.cpp rename to src/include/OpenImageIO/imagebufalgo_opencv.h index 1d5a37fda8..334bbd91b8 100644 --- a/src/libOpenImageIO/imagebufalgo_opencv.cpp +++ b/src/include/OpenImageIO/imagebufalgo_opencv.h @@ -2,69 +2,110 @@ // SPDX-License-Identifier: Apache-2.0 // https://github.com/AcademySoftwareFoundation/OpenImageIO +/// @file +/// +/// This file contains ImageBufAlgo functions that involve interoperability +/// with OpenCV. Please read these guidelines carefully: +/// +/// * Only `#include ` AFTER including +/// the necessary OpenCV headers. These functions use the cv::Mat type +/// from OpenCV. +/// * These functions are inline, in order to make it unnecessary for +/// libOpenImageIO itself to link against OpenCV. +/// * However, since the implementation of the functions in this header make +/// calls to OpenCV, it is necessary for any application calling these +/// functions, the application is responsible for finding OpenCV and +/// linking against the OpenCV libraries. +/// + + +#pragma once +#define OPENIMAGEIO_IMAGEBUFALGO_OPENCV_H -/// \file -/// Implementation of ImageBufAlgo algorithms related to OpenCV. -/// These are nonfunctional if OpenCV is not found at build time. - -#include - -#ifdef USE_OPENCV -# include -# ifdef CV_VERSION_EPOCH -# define OIIO_OPENCV_VERSION \ - (10000 * CV_VERSION_EPOCH + 100 * CV_VERSION_MAJOR \ - + CV_VERSION_MINOR) -# else -# define OIIO_OPENCV_VERSION \ - (10000 * CV_VERSION_MAJOR + 100 * CV_VERSION_MINOR \ - + CV_VERSION_REVISION) -# endif -# if OIIO_GNUC_VERSION >= 110000 && OIIO_CPLUSPLUS_VERSION >= 20 -// Suppress gcc 11 / C++20 errors about opencv 4 headers -# pragma GCC diagnostic ignored "-Wdeprecated-enum-enum-conversion" -# endif -# include -# if OIIO_OPENCV_VERSION >= 40000 -# include -# include -# else -# error "OpenCV 4.0 is the minimum supported version" -# endif -#endif - -#include -#include -#include -#include - -#include -#include -#include #include #include +#include #include -#include - -#include "imageio_pvt.h" - -// using namespace cv; - -OIIO_NAMESPACE_BEGIN +#include +#if !__has_include() +# error "This header requires OpenCV" +#endif -namespace pvt { -#ifdef USE_OPENCV -int opencv_version = OIIO_OPENCV_VERSION; +#include +#ifdef CV_VERSION_EPOCH +# define OIIO_OPENCV_VERSION \ + (10000 * CV_VERSION_EPOCH + 100 * CV_VERSION_MAJOR + CV_VERSION_MINOR) #else -int opencv_version = 0; +# define OIIO_OPENCV_VERSION \ + (10000 * CV_VERSION_MAJOR + 100 * CV_VERSION_MINOR \ + + CV_VERSION_REVISION) #endif -} // namespace pvt +OIIO_PRAGMA_WARNING_PUSH +#if OIIO_GNUC_VERSION >= 110000 || OIIO_CLANG_VERSION >= 120000 \ + || OIIO_APPLE_CLANG_VERSION >= 120000 +# pragma GCC diagnostic ignored "-Wdeprecated-enum-enum-conversion" +// # pragma GCC diagnostic ignored "-Wdeprecated-anon-enum-enum-conversion" +// # pragma GCC diagnostic ignored "-Wunused-but-set-variable" +#endif +#include +#if OIIO_OPENCV_VERSION >= 40000 +# include +# include +#else +# error "OpenCV 4.0 is the minimum supported version" +#endif +OIIO_PRAGMA_WARNING_POP +OIIO_NAMESPACE_BEGIN + namespace ImageBufAlgo { +/// Convert an OpenCV cv::Mat into an ImageBuf, copying the pixels (optionally +/// converting to the pixel data type specified by `convert`, if not UNKNOWN, +/// which means to preserve the original data type if possible). Return true +/// if ok, false if it was not able to make the conversion from Mat to +/// ImageBuf. Any error messages can be retrieved by calling `geterror()` on +/// the returned ImageBuf. If OpenImageIO was compiled without OpenCV support, +/// this function will return false. +inline ImageBuf +from_OpenCV(const cv::Mat& mat, TypeDesc convert = TypeUnknown, ROI roi = {}, + int nthreads = 0); + +/// Construct an OpenCV cv::Mat containing the contents of ImageBuf src, and +/// return true. If it is not possible, or if OpenImageIO was compiled without +/// OpenCV support, then return false. Any error messages can be retrieved by +/// calling OIIO::geterror(). Note that OpenCV only supports up to 4 channels, +/// so >4 channel images will be truncated in the conversion. +inline bool +to_OpenCV(cv::Mat& dst, const ImageBuf& src, ROI roi = {}, int nthreads = 0); + +/// Capture a still image from a designated camera. If able to do so, +/// store the image in dst and return true. If there is no such device, +/// or support for camera capture is not available (such as if OpenCV +/// support was not enabled at compile time), return false and do not +/// alter dst. +inline ImageBuf +capture_image(int cameranum = 0, TypeDesc convert = TypeUnknown); + +} // namespace ImageBufAlgo + + + +////////////////////////////////////////////////////////////////////////// +// +// Implementation details follow. +// +// ^^^ All declarations and documentation is above ^^^ +// +// vvv Below is the implementation. +// +////////////////////////////////////////////////////////////////////////// + +namespace pvt { + // Templated fast swap of R and B channels. template static bool @@ -81,16 +122,16 @@ RBswap(ImageBuf& R, ROI roi, int nthreads) return true; } -} // end namespace ImageBufAlgo +} // namespace pvt + -ImageBuf +inline ImageBuf ImageBufAlgo::from_OpenCV(const cv::Mat& mat, TypeDesc convert, ROI roi, int nthreads) { - pvt::LoggedTimer logtime("IBA::from_OpenCV"); + Timer timer; ImageBuf dst; -#ifdef USE_OPENCV TypeDesc srcformat; switch (mat.depth()) { case CV_8U: srcformat = TypeDesc::UINT8; break; @@ -104,7 +145,7 @@ ImageBufAlgo::from_OpenCV(const cv::Mat& mat, TypeDesc convert, ROI roi, return dst; } - TypeDesc dstformat = (convert != TypeDesc::UNKNOWN) ? convert : srcformat; + TypeDesc dstformat = (convert.is_unknown()) ? srcformat : convert; ROI matroi(0, mat.cols, 0, mat.rows, 0, 1, 0, mat.channels()); roi = roi_intersection(roi, matroi); ImageSpec spec(roi, dstformat); @@ -121,26 +162,21 @@ ImageBufAlgo::from_OpenCV(const cv::Mat& mat, TypeDesc convert, ROI roi, // OpenCV uses BGR ordering if (spec.nchannels >= 3) { OIIO_MAYBE_UNUSED bool ok = true; - OIIO_DISPATCH_TYPES(ok, "from_OpenCV R/B swap", RBswap, dstformat, dst, - roi, nthreads); + OIIO_DISPATCH_TYPES(ok, "from_OpenCV R/B swap", pvt::RBswap, dstformat, + dst, roi, nthreads); } -#else - dst.errorfmt( - "from_OpenCV() not supported -- no OpenCV support at compile time"); -#endif - + log_time("IBA::from_OpenCV", timer); return dst; } -bool +inline bool ImageBufAlgo::to_OpenCV(cv::Mat& dst, const ImageBuf& src, ROI roi, int nthreads) { - pvt::LoggedTimer logtime("IBA::to_OpenCV"); -#ifdef USE_OPENCV + Timer timer; if (!roi.defined()) roi = src.roi(); roi.chend = std::min(roi.chend, src.nchannels()); @@ -169,14 +205,14 @@ ImageBufAlgo::to_OpenCV(cv::Mat& dst, const ImageBuf& src, ROI roi, } else if (spec.format == TypeDesc(TypeDesc::DOUBLE)) { dstFormat = CV_MAKETYPE(CV_64F, chans); } else { - OIIO::errorfmt("to_OpenCV() doesn't know how to make a cv::Mat of {}", - spec.format); - return false; + // Punt, make 8 bit + dstFormat = CV_MAKETYPE(CV_8S, chans); } dst.create(roi.height(), roi.width(), dstFormat); if (dst.empty()) { OIIO::errorfmt("to_OpenCV() was unable to create cv::Mat of {}x{} {}", roi.width(), roi.height(), dstSpecFormat); + log_time("IBA::to_OpenCV", timer); return false; } @@ -190,6 +226,7 @@ ImageBufAlgo::to_OpenCV(cv::Mat& dst, const ImageBuf& src, ROI roi, OIIO::errorfmt( "to_OpenCV() was unable to convert source {} to cv::Mat of {}", spec.format, dstSpecFormat); + log_time("IBA::to_OpenCV", timer); return false; } @@ -200,89 +237,57 @@ ImageBufAlgo::to_OpenCV(cv::Mat& dst, const ImageBuf& src, ROI roi, cv::cvtColor(dst, dst, cv::COLOR_RGBA2BGRA); } + log_time("IBA::to_OpenCV", timer); return true; -#else - OIIO::errorfmt( - "to_OpenCV() not supported -- no OpenCV support at compile time"); - return false; -#endif } -namespace { - -#ifdef USE_OPENCV -static mutex opencv_mutex; - -class CameraHolder { -public: - CameraHolder() {} - // Destructor frees all cameras - ~CameraHolder() {} - // Get the capture device, creating a new one if necessary. - cv::VideoCapture* operator[](int cameranum) - { - auto i = m_cvcaps.find(cameranum); - if (i != m_cvcaps.end()) - return i->second.get(); - auto cvcam = new cv::VideoCapture(cameranum); - m_cvcaps[cameranum].reset(cvcam); - return cvcam; - } - -private: - std::map> m_cvcaps; -}; - -static CameraHolder cameras; -#endif - -} // namespace - - - -ImageBuf +inline ImageBuf ImageBufAlgo::capture_image(int cameranum, TypeDesc convert) { - pvt::LoggedTimer logtime("IBA::capture_image"); + Timer timer; ImageBuf dst; -#ifdef USE_OPENCV cv::Mat frame; { // This block is mutex-protected + static std::map> cameras; + static mutex opencv_mutex; lock_guard lock(opencv_mutex); - auto cvcam = cameras[cameranum]; + auto& cvcam = cameras[cameranum]; if (!cvcam) { - dst.errorfmt("Could not create a capture camera (OpenCV error)"); - return dst; // failed somehow + cvcam.reset(new cv::VideoCapture(cameranum)); + if (!cvcam) { + dst.errorfmt( + "Could not create a capture camera (OpenCV error)"); + log_time("IBA::capture_image", timer); + return dst; // failed somehow + } } (*cvcam) >> frame; if (frame.empty()) { dst.errorfmt("Could not cvQueryFrame (OpenCV error)"); + log_time("IBA::capture_image", timer); return dst; // failed somehow } } - logtime.stop(); + // logtime.stop(); dst = from_OpenCV(frame, convert); - logtime.start(); + // logtime.start(); if (!dst.has_error()) { time_t now; time(&now); struct tm tmtime; Sysutil::get_local_time(&now, &tmtime); std::string datetime - = Strutil::sprintf("{:4d}:{:02d}:{:02d} {:02d}:{:02d}:{:02d}", - tmtime.tm_year + 1900, tmtime.tm_mon + 1, - tmtime.tm_mday, tmtime.tm_hour, tmtime.tm_min, - tmtime.tm_sec); + = Strutil::fmt::format("{:4d}:{:02d}:{:02d} {:02d}:{:02d}:{:02d}", + tmtime.tm_year + 1900, tmtime.tm_mon + 1, + tmtime.tm_mday, tmtime.tm_hour, + tmtime.tm_min, tmtime.tm_sec); dst.specmod().attribute("DateTime", datetime); } -#else - dst.errorfmt( - "capture_image not supported -- no OpenCV support at compile time"); -#endif + log_time("IBA::capture_image", timer); return dst; } diff --git a/src/include/OpenImageIO/imageio.h b/src/include/OpenImageIO/imageio.h index af233d0d0f..927e15119b 100644 --- a/src/include/OpenImageIO/imageio.h +++ b/src/include/OpenImageIO/imageio.h @@ -3134,12 +3134,6 @@ inline bool attribute (string_view name, string_view val) { /// OpenImageiO, or "0.0.0" if no OpenColorIO support has been enabled. /// (Added in OpenImageIO 2.4.6) /// -/// - `int opencv_version` -/// -/// Returns the encoded version (such as 40701 for 4.7.1) of the OpenCV that -/// is used by OpenImageIO, or 0 if no OpenCV support has been enabled. -/// (Added in OpenImageIO 2.5.2) -/// /// - `string hw:simd` /// - `string build:simd` (read-only) /// diff --git a/src/include/imageio_pvt.h b/src/include/imageio_pvt.h index c9befa7421..08fe2bb52f 100644 --- a/src/include/imageio_pvt.h +++ b/src/include/imageio_pvt.h @@ -43,7 +43,6 @@ extern int oiio_log_times; extern int openexr_core; extern int limit_channels; extern int limit_imagesize_MB; -extern int opencv_version; extern int imagebuf_print_uncaught_errors; extern int imagebuf_use_imagecache; extern atomic_ll IB_local_mem_current; diff --git a/src/libOpenImageIO/CMakeLists.txt b/src/libOpenImageIO/CMakeLists.txt index fc3ab80512..0081d9b74c 100644 --- a/src/libOpenImageIO/CMakeLists.txt +++ b/src/libOpenImageIO/CMakeLists.txt @@ -55,7 +55,7 @@ set (libOpenImageIO_srcs imagebufalgo_minmaxchan.cpp imagebufalgo_orient.cpp imagebufalgo_xform.cpp - imagebufalgo_yee.cpp imagebufalgo_opencv.cpp + imagebufalgo_yee.cpp deepdata.cpp exif.cpp exif-canon.cpp formatspec.cpp icc.cpp imagebuf.cpp @@ -120,7 +120,6 @@ endif () target_compile_definitions(OpenImageIO PRIVATE OIIO_FREETYPE_VERSION="${FREETYPE_VERSION_STRING}" - OIIO_OpenCV_VERSION="${OpenCV_VERSION}" OIIO_PYTHON_VERSION="${Python3_VERSION}" OIIO_QT_VERSION="${Qt6_VERSION}${Qt5_VERSION}" OIIO_TBB_VERSION="${TBB_VERSION}" @@ -138,7 +137,6 @@ target_include_directories (OpenImageIO PRIVATE ${ROBINMAP_INCLUDES} ) -target_include_directories (OpenImageIO SYSTEM PUBLIC ${OpenCV_INCLUDES}) if (NOT BUILD_SHARED_LIBS) target_compile_definitions (OpenImageIO PUBLIC OIIO_STATIC_DEFINE=1) @@ -155,7 +153,6 @@ target_link_libraries (OpenImageIO ${OPENIMAGEIO_IMATH_TARGETS} PRIVATE ${OPENIMAGEIO_OPENEXR_TARGETS} - ${OpenCV_LIBRARIES} ${format_plugin_libs} # Add all the target link libraries from the plugins OpenColorIO::OpenColorIO $ @@ -253,6 +250,9 @@ if (OIIO_BUILD_TESTS AND BUILD_TESTING) add_test (unit_imagecache ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/imagecache_test) fancy_add_executable (NAME imagebufalgo_test SRC imagebufalgo_test.cpp + SYSTEM_INCLUDE_DIRS + ${ROBINMAP_INCLUDES} + ${OpenCV_INCLUDES} LINK_LIBRARIES OpenImageIO ${OpenCV_LIBRARIES} ${OPENIMAGEIO_IMATH_TARGETS} diff --git a/src/libOpenImageIO/imagebufalgo_test.cpp b/src/libOpenImageIO/imagebufalgo_test.cpp index c9ca030d2d..0d705e451f 100644 --- a/src/libOpenImageIO/imagebufalgo_test.cpp +++ b/src/libOpenImageIO/imagebufalgo_test.cpp @@ -10,14 +10,6 @@ #include -#if USE_OPENCV -// Suppress gcc 11 / C++20 errors about opencv 4 headers -# if OIIO_GNUC_VERSION >= 110000 && OIIO_CPLUSPLUS_VERSION >= 20 -# pragma GCC diagnostic ignored "-Wdeprecated-enum-enum-conversion" -# endif -# include -#endif - #include #include #include @@ -29,6 +21,10 @@ #include #include +#if USE_OPENCV +# include +#endif + using namespace OIIO; diff --git a/src/libOpenImageIO/imageio.cpp b/src/libOpenImageIO/imageio.cpp index a78ff59947..e7712b19cc 100644 --- a/src/libOpenImageIO/imageio.cpp +++ b/src/libOpenImageIO/imageio.cpp @@ -665,10 +665,6 @@ getattribute(string_view name, TypeDesc type, void* val) (v >> 16) & 0xff, (v >> 8) & 0xff); return true; } - if (name == "opencv_version" && type == TypeInt) { - *(int*)val = OIIO::pvt::opencv_version; - return true; - } if (name == "IB_local_mem_current" && type == TypeInt64) { *(long long*)val = IB_local_mem_current; return true; diff --git a/src/oiiotool/CMakeLists.txt b/src/oiiotool/CMakeLists.txt index f00f11a620..87b6a3e787 100644 --- a/src/oiiotool/CMakeLists.txt +++ b/src/oiiotool/CMakeLists.txt @@ -4,8 +4,9 @@ fancy_add_executable (SYSTEM_INCLUDE_DIRS ${ROBINMAP_INCLUDES} + ${OpenCV_INCLUDES} LINK_LIBRARIES OpenImageIO $ - $ + ${OpenCV_LIBRARIES} ) diff --git a/src/oiiotool/oiiotool.cpp b/src/oiiotool/oiiotool.cpp index b266ea641d..6adf879a27 100644 --- a/src/oiiotool/oiiotool.cpp +++ b/src/oiiotool/oiiotool.cpp @@ -43,6 +43,10 @@ # include #endif +#ifdef USE_OPENCV +# include +#endif + using namespace OIIO; using namespace OiioTool; using namespace ImageBufAlgo; @@ -3716,14 +3720,19 @@ action_capture(Oiiotool& ot, cspan argv) OIIO_DASSERT(argv.size() == 1); string_view command = ot.express(argv[0]); OTScopedTimer timer(ot, command); + +#ifdef USE_OPENCV auto options = ot.extract_options(command); int camera = options.get_int("camera"); - - ImageBuf ib = ImageBufAlgo::capture_image(camera /*, TypeDesc::FLOAT*/); + ImageBuf ib = ImageBufAlgo::capture_image(camera /*, TypeDesc::FLOAT*/); if (ib.has_error()) { ot.error(command, ib.geterror()); return; } +#else + ot.warning(command, "capture requires OpenCV support"); + ImageBuf ib(ImageSpec(640, 480, 3, TypeDesc::FLOAT)); +#endif ImageRecRef img(new ImageRec("capture", ib.spec(), ot.imagecache)); (*img)().copy(ib); ot.push(img); diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index e8f733221c..e0b50dde5c 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -8,8 +8,9 @@ file (GLOB python_srcs *.cpp) setup_python_module (TARGET PyOpenImageIO MODULE OpenImageIO SOURCES ${python_srcs} - LIBS OpenImageIO ${OPENIMAGEIO_IMATH_TARGETS} - ) + LIBS OpenImageIO + ${OPENIMAGEIO_IMATH_TARGETS} + ) # Unity builds: If in unity group mode, make the python bindings one group. If # in unity batch mode, use the smaller batch size because these tend to be diff --git a/src/python/py_imagebufalgo.cpp b/src/python/py_imagebufalgo.cpp index 22db42d338..e35fde48a3 100644 --- a/src/python/py_imagebufalgo.cpp +++ b/src/python/py_imagebufalgo.cpp @@ -2326,25 +2326,6 @@ IBA_histogram(const ImageBuf& src, int channel = 0, int bins = 256, -bool -IBA_capture_image(ImageBuf& dst, int cameranum, - TypeDesc::BASETYPE convert = TypeDesc::UNKNOWN) -{ - py::gil_scoped_release gil; - dst = ImageBufAlgo::capture_image(cameranum, convert); - return !dst.has_error(); -} - -ImageBuf -IBA_capture_image_ret(int cameranum, - TypeDesc::BASETYPE convert = TypeDesc::UNKNOWN) -{ - py::gil_scoped_release gil; - return ImageBufAlgo::capture_image(cameranum, convert); -} - - - bool IBA_make_texture_ib(ImageBufAlgo::MakeTextureMode mode, const ImageBuf& buf, const std::string& outputfilename, const ImageSpec& config) @@ -3013,11 +2994,6 @@ declare_imagebufalgo(py::module& m) .def_static("fillholes_pushpull", &IBA_fillholes_pushpull_ret, "src"_a, "roi"_a = ROI::All(), "nthreads"_a = 0) - .def_static("capture_image", &IBA_capture_image, "dst"_a, - "cameranum"_a = 0, "convert"_a = TypeDesc::UNKNOWN) - .def_static("capture_image", &IBA_capture_image_ret, "cameranum"_a = 0, - "convert"_a = TypeDesc::UNKNOWN) - .def_static("over", &IBA_over, "dst"_a, "A"_a, "B"_a, "roi"_a = ROI::All(), "nthreads"_a = 0) .def_static("over", &IBA_over_ret, "A"_a, "B"_a, "roi"_a = ROI::All(),