From 422b27a75a2f18fc08de9e216c3dbd52f5a22909 Mon Sep 17 00:00:00 2001 From: Nicolo' Genesio Date: Tue, 27 Nov 2018 15:10:39 +0100 Subject: [PATCH 1/6] Add YARP_cv, a conversion library from YARP images to cv::Mat and viceversa --- src/CMakeLists.txt | 1 + src/libYARP_cv/CMakeLists.txt | 41 ++++++++++ src/libYARP_cv/include/yarp/cv/Cv-inl.h | 103 ++++++++++++++++++++++++ src/libYARP_cv/include/yarp/cv/Cv.h | 62 ++++++++++++++ src/libYARP_pcl/CMakeLists.txt | 2 +- src/libYARP_sig/src/Image.cpp | 2 + 6 files changed, 210 insertions(+), 1 deletion(-) create mode 100644 src/libYARP_cv/CMakeLists.txt create mode 100644 src/libYARP_cv/include/yarp/cv/Cv-inl.h create mode 100644 src/libYARP_cv/include/yarp/cv/Cv.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 43d650fcd39..9b2f6d11022 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,6 +20,7 @@ add_subdirectory(libYARP_math) add_subdirectory(libYARP_rosmsg) add_subdirectory(libYARP_dev) add_subdirectory(libYARP_pcl) +add_subdirectory(libYARP_cv) # private libraries add_subdirectory(libYARP_companion) diff --git a/src/libYARP_cv/CMakeLists.txt b/src/libYARP_cv/CMakeLists.txt new file mode 100644 index 00000000000..31827f195e1 --- /dev/null +++ b/src/libYARP_cv/CMakeLists.txt @@ -0,0 +1,41 @@ +# Copyright (C) 2006-2018 Istituto Italiano di Tecnologia (IIT) +# All rights reserved. +# +# This software may be modified and distributed under the terms of the +# BSD-3-Clause license. See the accompanying LICENSE file for details. + +project(YARP_cv) + +set(YARP_cv_HDRS include/yarp/cv/Cv.h + include/yarp/cv/Cv-inl.h) + +source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" + PREFIX "Header Files" + FILES ${YARP_cv_HDRS}) + +add_library(YARP_cv INTERFACE) +add_library(YARP::YARP_cv ALIAS YARP_cv) + +target_include_directories(YARP_cv INTERFACE $ + $) + +target_link_libraries(YARP_cv INTERFACE YARP::YARP_sig) +list(APPEND YARP_cv_PUBLIC_DEPS YARP_sig) + +target_include_directories(YARP_cv SYSTEM INTERFACE ${OPENCV_INCLUDE_DIR}) +target_link_libraries(YARP_cv INTERFACE ${OPENCV_INCLUDE_DIR}) +list(APPEND YARP_cv_PUBLIC_DEPS OpenCV) + + +install(TARGETS YARP_cv + EXPORT YARP_cv + COMPONENT YARP_cv + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/yarp/cv) + +install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/yarp/cv + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/yarp) + +include(YarpInstallBasicPackageFiles) +yarp_install_basic_package_files(YARP_cv + DEPENDENCIES ${YARP_cv_PUBLIC_DEPS} + PRIVATE_DEPENDENCIES ${YARP_cv_PRIVATE_DEPS}) diff --git a/src/libYARP_cv/include/yarp/cv/Cv-inl.h b/src/libYARP_cv/include/yarp/cv/Cv-inl.h new file mode 100644 index 00000000000..ae1bba0e12b --- /dev/null +++ b/src/libYARP_cv/include/yarp/cv/Cv-inl.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2006-2018 Istituto Italiano di Tecnologia (IIT) + * All rights reserved. + * + * This software may be modified and distributed under the terms of the + * BSD-3-Clause license. See the accompanying LICENSE file for details. + */ + +#ifndef YARP_CV_CV_INL_H +#define YARP_CV_CV_INL_H + +#include + +namespace yarp { +namespace cv { + +template +struct type_code; + +template<> struct type_code : std::integral_constant {}; +template<> struct type_code : std::integral_constant {}; +template<> struct type_code : std::integral_constant {}; +template<> struct type_code : std::integral_constant {}; +template<> struct type_code : std::integral_constant {}; +template<> struct type_code : std::integral_constant {}; +template<> struct type_code : std::integral_constant {}; +template<> struct type_code : std::integral_constant {}; +template<> struct type_code : std::integral_constant {}; +template<> struct type_code : std::integral_constant {}; +template<> struct type_code : std::integral_constant {}; +template<> struct type_code : std::integral_constant {}; +template<> struct type_code : std::integral_constant {}; +template<> struct type_code : std::integral_constant {}; + +// -1 : no conversion required. +template +struct convert_code_to_cv; + +template<> struct convert_code_to_cv : std::integral_constant {}; +template<> struct convert_code_to_cv : std::integral_constant {}; +template<> struct convert_code_to_cv : std::integral_constant {}; +template<> struct convert_code_to_cv : std::integral_constant {}; +template<> struct convert_code_to_cv : std::integral_constant {}; +template<> struct convert_code_to_cv : std::integral_constant {}; +template<> struct convert_code_to_cv : std::integral_constant {}; +template<> struct convert_code_to_cv : std::integral_constant {}; +template<> struct convert_code_to_cv : std::integral_constant {}; +template<> struct convert_code_to_cv : std::integral_constant {}; +template<> struct convert_code_to_cv : std::integral_constant {}; +template<> struct convert_code_to_cv : std::integral_constant {}; +template<> struct convert_code_to_cv : std::integral_constant {}; +template<> struct convert_code_to_cv : std::integral_constant {}; + +template +struct convert_code_from_cv; + +template<> struct convert_code_from_cv : std::integral_constant {}; +template<> struct convert_code_from_cv : std::integral_constant {}; +template<> struct convert_code_from_cv : std::integral_constant {}; +template<> struct convert_code_from_cv : std::integral_constant {}; +template<> struct convert_code_from_cv : std::integral_constant {}; +template<> struct convert_code_from_cv : std::integral_constant {}; +template<> struct convert_code_from_cv : std::integral_constant {}; +template<> struct convert_code_from_cv : std::integral_constant {}; +template<> struct convert_code_from_cv : std::integral_constant {}; +template<> struct convert_code_from_cv : std::integral_constant {}; +template<> struct convert_code_from_cv : std::integral_constant {}; +template<> struct convert_code_from_cv : std::integral_constant {}; +template<> struct convert_code_from_cv : std::integral_constant {}; +template<> struct convert_code_from_cv : std::integral_constant {}; + + +} // namespace cv +} // namespace yarp + + +template +::cv::Mat yarp::cv::toCvMat(yarp::sig::ImageOf& yarpImage) +{ + ::cv::Mat outMat (yarpImage.height(), yarpImage.width(), yarp::cv::type_code::value, + yarpImage.getRawImage(), yarpImage.getRowSize()); // RVO + if (convert_code_to_cv::value >= 0) + { + ::cv::cvtColor(outMat, outMat, convert_code_to_cv::value); + } + return outMat; +} + + +template +yarp::sig::ImageOf yarp::cv::fromCvMat(::cv::Mat& cvImage) +{ + yarp::sig::ImageOf outImg; + assert(yarp::cv::type_code::value == cvImage.type()); // Checking cv::Mat::type() compatibility with the T PixelType + if (convert_code_from_cv::value >= 0) + { + ::cv::cvtColor(cvImage, cvImage, convert_code_from_cv::value); + } + outImg.setExternal(cvImage.data, cvImage.cols, cvImage.rows); + return outImg; +} + +#endif // YARP_CV_CV_INL_H diff --git a/src/libYARP_cv/include/yarp/cv/Cv.h b/src/libYARP_cv/include/yarp/cv/Cv.h new file mode 100644 index 00000000000..214efd9eed8 --- /dev/null +++ b/src/libYARP_cv/include/yarp/cv/Cv.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2006-2018 Istituto Italiano di Tecnologia (IIT) + * All rights reserved. + * + * This software may be modified and distributed under the terms of the + * BSD-3-Clause license. See the accompanying LICENSE file for details. + */ + +#ifndef YARP_CV_CV_H +#define YARP_CV_CV_H + +#include + +#include +#include +#include + +namespace yarp { +namespace cv { + +/** + * Convert a yarp::sig::ImageOf to a cv::Mat object + * @param[in] yarpImage yarp::sig::ImageOf input. + * Since the argument is passed as right-reference, the integrity + * of the data of the input yarp image is not guaranteed. + * @note The output cv::Mat has the default OpenCV color representation: + * - 1 channel: GRAY + * - 3 channels: BGR + * - 4 channel: BGRA + * Moreover pay attention on the lifetime of the memory of the input image, + * since no copy is involved. + * @return the resulting cv::Mat. + */ +template +::cv::Mat toCvMat(yarp::sig::ImageOf& yarpImage); + +/** + * Convert a cv::Mat to a yarp::sig::ImageOf object. + * @param[in] cvImage cv::Mat input. + * Since the argument is passed as right-reference, the integrity + * of the data of the input cv::Mat is not guaranteed. + * @note The input cv::Mat's type(e.g. CV_8UC1) must be compatible + * with the output yarp image pixel type requested. + * E.g.: + * - CV_8UC3 -> ImageOf// OK + * - CV_8UC1 -> ImageOf OK + * - CV_8UC3 -> ImageOf NOT OK + * - CV_8UC1 -> ImageOf// NOT OK + * Please pay attention to the number of channels and pixel depth. + * Moreover pay attention on the lifetime of the memory of the input image, + * since no copy is involved. + * @return the resulting yarp::sig::ImageOf. + */ +template +yarp::sig::ImageOf fromCvMat(::cv::Mat& cvImage); + +} // namespace cv +} // namespace yarp + +#include "Cv-inl.h" + +#endif // YARP_CV_CV_H diff --git a/src/libYARP_pcl/CMakeLists.txt b/src/libYARP_pcl/CMakeLists.txt index bdc5ba8b9a3..117fba3397c 100644 --- a/src/libYARP_pcl/CMakeLists.txt +++ b/src/libYARP_pcl/CMakeLists.txt @@ -18,7 +18,7 @@ add_library(YARP::YARP_pcl ALIAS YARP_pcl) target_include_directories(YARP_pcl INTERFACE $ $) -target_link_libraries(YARP_pcl INTERFACE YARP_sig) +target_link_libraries(YARP_pcl INTERFACE YARP::YARP_sig) list(APPEND YARP_pcl_PUBLIC_DEPS YARP_sig) target_include_directories(YARP_pcl SYSTEM INTERFACE ${PCL_INCLUDE_DIR}) diff --git a/src/libYARP_sig/src/Image.cpp b/src/libYARP_sig/src/Image.cpp index dc30bf5f636..a11776033dc 100644 --- a/src/libYARP_sig/src/Image.cpp +++ b/src/libYARP_sig/src/Image.cpp @@ -542,6 +542,7 @@ size_t Image::getRawImageSize() const { return 0; } +#ifndef YARP_NO_DEPRECATED // Since YARP 3.2.0 void *Image::getIplImage() { return ((ImageStorage*)implementation)->pImage; } @@ -651,6 +652,7 @@ void Image::wrapIplImage(void *iplImage) { } } +#endif // YARP_NO_DEPRECATED bool Image::read(yarp::os::ConnectionReader& connection) { From a3ae75834fe7ceeea5a0c0cfea455cabfe7a7cf6 Mon Sep 17 00:00:00 2001 From: Nicolo' Genesio Date: Fri, 7 Dec 2018 16:11:59 +0100 Subject: [PATCH 2/6] Add YARP_cv to the documentation --- cmake/template/Doxyfile.in | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmake/template/Doxyfile.in b/cmake/template/Doxyfile.in index 5911368f598..604cbf3b8cc 100644 --- a/cmake/template/Doxyfile.in +++ b/cmake/template/Doxyfile.in @@ -171,6 +171,8 @@ STRIP_FROM_INC_PATH = @CMAKE_BINARY_DIR@/src/libYARP_conf/include \ @CMAKE_SOURCE_DIR@/src/libYARP_name/include/ \ @CMAKE_SOURCE_DIR@/src/libYARP_gsl/include/ \ @CMAKE_SOURCE_DIR@/src/libYARP_eigen/include/ \ + @CMAKE_SOURCE_DIR@/src/libYARP_pcl/include/ \ + @CMAKE_SOURCE_DIR@/src/libYARP_cv/include/ \ @CMAKE_SOURCE_DIR@/src/libYARP_rosmsg/idl_generated_code/include/ \ @CMAKE_SOURCE_DIR@/src/libYARP_run/include/ \ @CMAKE_SOURCE_DIR@/src/libYARP_rtf/include/ \ @@ -812,6 +814,8 @@ INPUT = @CMAKE_BINARY_DIR@/src/libYARP_conf/include \ @CMAKE_SOURCE_DIR@/src/libYARP_gsl/include \ @CMAKE_SOURCE_DIR@/src/libYARP_gsl/src \ @CMAKE_SOURCE_DIR@/src/libYARP_eigen/include \ + @CMAKE_SOURCE_DIR@/src/libYARP_pcl/include/ \ + @CMAKE_SOURCE_DIR@/src/libYARP_cv/include/ \ @CMAKE_SOURCE_DIR@/src/libYARP_rosmsg/idl_generated_code/include/ \ @CMAKE_SOURCE_DIR@/src/libYARP_run/include/ \ @CMAKE_SOURCE_DIR@/src/libYARP_run/src/ \ @@ -2083,6 +2087,8 @@ INCLUDE_PATH = @CMAKE_BINARY_DIR@/src/libYARP_conf/include \ @CMAKE_SOURCE_DIR@/src/libYARP_name/include/ \ @CMAKE_SOURCE_DIR@/src/libYARP_gsl/include/ \ @CMAKE_SOURCE_DIR@/src/libYARP_eigen/include/ \ + @CMAKE_SOURCE_DIR@/src/libYARP_pcl/include/ \ + @CMAKE_SOURCE_DIR@/src/libYARP_cv/include/ \ @CMAKE_SOURCE_DIR@/src/libYARP_rosmsg/idl_generated_code/include/ \ @CMAKE_SOURCE_DIR@/src/libYARP_run/include/ \ @CMAKE_SOURCE_DIR@/src/libYARP_rtf/include/ \ From e8278a207e1a4dfad7617adbaf0488edb5d69d18 Mon Sep 17 00:00:00 2001 From: Nicolo' Genesio Date: Fri, 7 Dec 2018 16:13:17 +0100 Subject: [PATCH 3/6] YARP_sig: deprecate getIplImage and wrapIplImage. Deprecation in favour of toCvMat and fromCVMat respectively --- src/libYARP_sig/include/yarp/sig/Image.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libYARP_sig/include/yarp/sig/Image.h b/src/libYARP_sig/include/yarp/sig/Image.h index a58d2406add..a27684b159e 100644 --- a/src/libYARP_sig/include/yarp/sig/Image.h +++ b/src/libYARP_sig/include/yarp/sig/Image.h @@ -267,12 +267,14 @@ class YARP_sig_API yarp::sig::Image : public yarp::os::Portable { */ size_t getRawImageSize() const; +#ifndef YARP_NO_DEPRECATED // Since YARP 3.2.0 /** * Returns IPL/OpenCV view of image, if possible. * Not possible if the image is the wrong size, with no padding. * This method is currently not well documented. * @return pointer to an IplImage structure or nullptr */ + YARP_DEPRECATED_MSG("Use yarp::cv::toCvMat instead") void *getIplImage(); /** @@ -281,6 +283,7 @@ class YARP_sig_API yarp::sig::Image : public yarp::os::Portable { * This method is currently not well documented. * @return pointer to an IplImage structure or nullptr */ + YARP_DEPRECATED_MSG("Use yarp::cv::toCvMat instead") const void *getIplImage() const; /** @@ -294,7 +297,9 @@ class YARP_sig_API yarp::sig::Image : public yarp::os::Portable { * * @param iplImage pointer to an IplImage structure */ + YARP_DEPRECATED_MSG("Use yarp::cv::fromCvMat instead") void wrapIplImage(void *iplImage); +#endif // YARP_NO_DEPRECATED //void wrapRawImage(void *buf, int imgWidth, int imgHeight); From 2e2e40d3819307cd96d59bd28b7104065792e6e4 Mon Sep 17 00:00:00 2001 From: Nicolo' Genesio Date: Fri, 7 Dec 2018 16:14:00 +0100 Subject: [PATCH 4/6] yarpdatadumper: fix deprecation warning of getIplImage --- src/yarpdatadumper/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yarpdatadumper/main.cpp b/src/yarpdatadumper/main.cpp index 765dd1fcf3d..7c994be7e99 100644 --- a/src/yarpdatadumper/main.cpp +++ b/src/yarpdatadumper/main.cpp @@ -130,7 +130,7 @@ class DumpImage : public DumpObj return (fName.str()+" ["+Vocab::decode(code)+"]"); } - void *getPtr() override { return p->getIplImage(); } + void *getPtr() override { return p->getRawImage(); } }; From 3861621edbb4af12b0468cbab918c1e1784069fd Mon Sep 17 00:00:00 2001 From: Nicolo' Genesio Date: Fri, 7 Dec 2018 16:21:55 +0100 Subject: [PATCH 5/6] Update release note --- doc/release/v3_2_0.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/release/v3_2_0.md b/doc/release/v3_2_0.md index 1b79306aee4..3a0d4995da8 100644 --- a/doc/release/v3_2_0.md +++ b/doc/release/v3_2_0.md @@ -72,6 +72,12 @@ New Features * Added two methods for computing a `yarp::sig::PointCloud` from depth images: - `utils::depthToPC` - `utils::depthRgbToPC` +* Deprecated `getIplImage` and `wrapIplImage` in favour of the new utilities of + `YARP_cv`. + +#### `YARP_cv` + +* Added `YARP_cv`, a conversion library from YARP images to cv::Mat and viceversa. ### Devices * Added `fakeBattery` device From 514e13b07af5966eada76acbc4496f7eaa7183db Mon Sep 17 00:00:00 2001 From: Nicolo' Genesio Date: Wed, 19 Dec 2018 12:40:40 +0100 Subject: [PATCH 6/6] yarpdataplayer: port the code to from/toCvMat utilities. --- src/yarpdataplayer/CMakeLists.txt | 2 +- src/yarpdataplayer/include/worker.h | 5 +++-- src/yarpdataplayer/src/worker.cpp | 25 ++++++++++++++----------- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/yarpdataplayer/CMakeLists.txt b/src/yarpdataplayer/CMakeLists.txt index 539f405fb87..8e05293e9ab 100644 --- a/src/yarpdataplayer/CMakeLists.txt +++ b/src/yarpdataplayer/CMakeLists.txt @@ -94,7 +94,7 @@ if(CREATE_YARPDATAPLAYER) Qt5::Widgets) if(YARP_HAS_OPENCV) - target_link_libraries(yarpdataplayer ${OpenCV_LIBRARIES}) + target_link_libraries(yarpdataplayer ${OpenCV_LIBRARIES} YARP_cv) endif() install(TARGETS yarpdataplayer COMPONENT utilities DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/src/yarpdataplayer/include/worker.h b/src/yarpdataplayer/include/worker.h index a75a856a902..25d4f3b8d1b 100644 --- a/src/yarpdataplayer/include/worker.h +++ b/src/yarpdataplayer/include/worker.h @@ -32,8 +32,9 @@ #include #ifdef HAS_OPENCV - #include - #include +#include +#include +#include #endif diff --git a/src/yarpdataplayer/src/worker.cpp b/src/yarpdataplayer/src/worker.cpp index f75123602c5..6ceec47ff16 100644 --- a/src/yarpdataplayer/src/worker.cpp +++ b/src/yarpdataplayer/src/worker.cpp @@ -23,11 +23,12 @@ #endif #include -#include "yarp/os/Stamp.h" +#include #include "include/worker.h" #include "include/mainwindow.h" #include "include/log.h" + using namespace yarp::sig; using namespace yarp::sig::file; using namespace yarp::os; @@ -176,36 +177,38 @@ int WorkerClass::sendImages(int part, int frame) unique_ptr img_yarp = nullptr; #ifdef HAS_OPENCV - IplImage* img_ipl = nullptr; + cv::Mat cv_img; if (code==VOCAB_PIXEL_MONO_FLOAT) { img_yarp = unique_ptr(new ImageOf); fileValid = read(*static_cast*>(img_yarp.get()),tmpPath); } else { - img_ipl=cvLoadImage(tmpPath.c_str(),CV_LOAD_IMAGE_UNCHANGED); - if ( img_ipl!=nullptr ) { + cv_img = cv::imread(tmpPath, CV_LOAD_IMAGE_UNCHANGED); + if ( cv_img.data != nullptr ) { if (code==VOCAB_PIXEL_RGB) { img_yarp = unique_ptr(new ImageOf); - cvCvtColor(img_ipl,img_ipl,CV_BGR2RGB); + *img_yarp = yarp::cv::fromCvMat(cv_img); } else if (code==VOCAB_PIXEL_BGR) + { img_yarp = unique_ptr(new ImageOf); + *img_yarp = yarp::cv::fromCvMat(cv_img); + } else if (code==VOCAB_PIXEL_RGBA) { img_yarp = unique_ptr(new ImageOf); - cvCvtColor(img_ipl,img_ipl,CV_BGRA2RGBA); + *img_yarp = yarp::cv::fromCvMat(cv_img); } - else if (code==VOCAB_PIXEL_MONO) + else if (code==VOCAB_PIXEL_MONO){ img_yarp = unique_ptr(new ImageOf); + *img_yarp = yarp::cv::fromCvMat(cv_img); + } else { img_yarp = unique_ptr(new ImageOf); - cvCvtColor(img_ipl,img_ipl,CV_BGR2RGB); + *img_yarp = yarp::cv::fromCvMat(cv_img); } - img_yarp->resize(img_ipl->width, img_ipl->height); - cvCopy( img_ipl, (IplImage *) img_yarp->getIplImage()); - cvReleaseImage(&img_ipl); fileValid = true; } }