From 7f8e6c72620fe051abc2d70ded9fa5b1d6ef88a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20=C3=89corchard?= Date: Tue, 14 Apr 2020 15:27:30 +0200 Subject: [PATCH 1/5] Add the intensity histogram app MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gaël Écorchard --- CMakeLists.txt | 2 +- launch/intensity_histogram.launch | 16 ++ nodelet_plugins.xml | 4 + src/nodelet/intensity_histogram.cpp | 221 ++++++++++++++++++++++++++++ 4 files changed, 242 insertions(+), 1 deletion(-) create mode 100644 launch/intensity_histogram.launch create mode 100644 src/nodelet/intensity_histogram.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index e4f8f6ff..4bdd4a53 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -263,7 +263,7 @@ opencv_apps_add_nodelet(camshift src/nodelet/camshift_nodelet.cpp) # ./camshiftd # ./create_mask.cpp # ./dbt_face_detection.cpp # ./delaunay2.cpp -# ./demhist.cpp +opencv_apps_add_nodelet(intensity_histogram src/nodelet/intensity_histogram.cpp) # ./demhist.cpp # ./detect_blob.cpp # ./detect_mser.cpp # ./dft.cpp diff --git a/launch/intensity_histogram.launch b/launch/intensity_histogram.launch new file mode 100644 index 00000000..9eb8185c --- /dev/null +++ b/launch/intensity_histogram.launch @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/nodelet_plugins.xml b/nodelet_plugins.xml index 62f76e3d..9620bb73 100644 --- a/nodelet_plugins.xml +++ b/nodelet_plugins.xml @@ -127,6 +127,10 @@ Nodelet for histogram equalization + + Nodelet of intensity histogram + + diff --git a/src/nodelet/intensity_histogram.cpp b/src/nodelet/intensity_histogram.cpp new file mode 100644 index 00000000..b8f0df91 --- /dev/null +++ b/src/nodelet/intensity_histogram.cpp @@ -0,0 +1,221 @@ +/********************************************************************* +* Software License Agreement (BSD License) +* +* Copyright (c) 2020, Gaël Écorchard, Czech Technical University. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above +* copyright notice, this list of conditions and the following +* disclaimer in the documentation and/or other materials provided +* with the distribution. +* * Neither the name of the Gaël Écorchard nor the names of its +* contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*********************************************************************/ +/** + * Compute the histogram of intensities and publish it as an image. + */ + +#include + +#include +//#include +#include +#include +#include +#include +#include +#include +#include + +namespace opencv_apps +{ + +namespace intensity_histogram +{ + +static const std::string OPENCV_WINDOW = "Image histogram"; + +cv::Mat grayHistogram(cv_bridge::CvImageConstPtr img) +{ + /* Inspired by https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/Histograms_Matching/calcHist_Demo.cpp. */ + constexpr bool uniform = true; + constexpr bool accumulate = false; + constexpr int bin_count = 256; + + float range[] = {0, 256}; //the upper boundary is exclusive + const float* hist_range = {range}; + cv::Mat intensity_hist; + cv::calcHist(&img->image, 1, 0, cv::Mat(), intensity_hist, 1, &bin_count, &hist_range, uniform, accumulate); + int hist_w = 512; + int hist_h = 400; + int bin_w = cvRound(static_cast(hist_w / bin_count)); + cv::Mat hist_image(hist_h, hist_w, CV_8UC1, cv::Scalar(0)); + cv::normalize(intensity_hist, intensity_hist, 0, hist_image.rows, cv::NORM_MINMAX, -1, cv::Mat()); + for (unsigned int i = 1; i < bin_count; i++) + { + cv::line(hist_image, + cv::Point(bin_w * (i-1), hist_h - cvRound(intensity_hist.at(i-1))), + cv::Point(bin_w * (i), hist_h - cvRound(intensity_hist.at(i))), + cv::Scalar(255), 2, 8, 0); + } + return hist_image; +} + +cv::Mat bgrHistogram(cv_bridge::CvImageConstPtr img) +{ + /* Inspired by https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/Histograms_Matching/calcHist_Demo.cpp. */ + constexpr bool uniform = true; + constexpr bool accumulate = false; + constexpr int bin_count = 256; + + std::vector bgr_planes; + cv::split(img->image, bgr_planes); + + float range[] = {0, 256}; //the upper boundary is exclusive + const float* hist_range = {range}; + cv::Mat b_hist; + cv::Mat g_hist; + cv::Mat r_hist; + cv::calcHist(&bgr_planes[0], 1, 0, cv::Mat(), b_hist, 1, &bin_count, &hist_range, uniform, accumulate); + cv::calcHist(&bgr_planes[1], 1, 0, cv::Mat(), g_hist, 1, &bin_count, &hist_range, uniform, accumulate); + cv::calcHist(&bgr_planes[2], 1, 0, cv::Mat(), r_hist, 1, &bin_count, &hist_range, uniform, accumulate); + int hist_w = 512; + int hist_h = 400; + int bin_w = cvRound(static_cast(hist_w / bin_count)); + cv::Mat hist_image(hist_h, hist_w, CV_8UC3, cv::Scalar(0, 0, 0)); + cv::normalize(b_hist, b_hist, 0, hist_image.rows, cv::NORM_MINMAX, -1, cv::Mat()); + cv::normalize(g_hist, g_hist, 0, hist_image.rows, cv::NORM_MINMAX, -1, cv::Mat()); + cv::normalize(r_hist, r_hist, 0, hist_image.rows, cv::NORM_MINMAX, -1, cv::Mat()); + for (unsigned int i = 1; i < bin_count; i++) + { + cv::line(hist_image, + cv::Point(bin_w * (i-1), hist_h - cvRound(b_hist.at(i-1))), + cv::Point(bin_w * (i), hist_h - cvRound(b_hist.at(i))), + cv::Scalar(255, 0, 0), 2, 8, 0); + cv::line(hist_image, + cv::Point(bin_w * (i-1), hist_h - cvRound(g_hist.at(i-1))), + cv::Point(bin_w * (i), hist_h - cvRound(g_hist.at(i))), + cv::Scalar(0, 255, 0), 2, 8, 0); + cv::line(hist_image, + cv::Point(bin_w * (i-1), hist_h - cvRound(r_hist.at(i-1))), + cv::Point(bin_w * (i), hist_h - cvRound(r_hist.at(i))), + cv::Scalar(0, 0, 255), 2, 8, 0); + } + return hist_image; +} + +class IntensityHistogram +{ + + public: + + IntensityHistogram() : + it_(nh_) + { + image_sub_ = it_.subscribe("image", queue_size_, &IntensityHistogram::imageCallback, this); + hist_pub_ = it_.advertise("image_hist", 1); + + ros::NodeHandle private_nh("~"); + private_nh.param("queue_size", queue_size_, 1); + private_nh.param("debug_view", debug_view_, false); + if (debug_view_) + { + cv::namedWindow(OPENCV_WINDOW); + } + } + + ~IntensityHistogram() + { + if (debug_view_) + { + cv::destroyWindow(OPENCV_WINDOW); + } + } + + void imageCallback(const sensor_msgs::ImageConstPtr& msg) + { + cv_bridge::CvImageConstPtr cv_ptr; + try + { + cv_ptr = cv_bridge::toCvShare(msg); + } + catch (cv_bridge::Exception& e) + { + ROS_ERROR("cv_bridge exception: %s", e.what()); + return; + } + + cv::Mat out_img; + sensor_msgs::Image::Ptr out_img_msg; + if (cv_ptr->image.channels() == 1) + { + out_img = grayHistogram(cv_ptr); + out_img_msg = cv_bridge::CvImage( + msg->header, sensor_msgs::image_encodings::MONO8, out_img).toImageMsg(); + + } + else + { + out_img = bgrHistogram(cv_ptr); + out_img_msg = cv_bridge::CvImage( + msg->header, sensor_msgs::image_encodings::RGB8, out_img).toImageMsg(); + } + + if (debug_view_) + { + // Update GUI Window + cv::imshow(OPENCV_WINDOW, out_img); + cv::waitKey(3); + } + + hist_pub_.publish(out_img_msg); + } + + private: + + ros::NodeHandle nh_; + image_transport::ImageTransport it_; + image_transport::Subscriber image_sub_; + image_transport::Publisher hist_pub_; + int queue_size_; + bool debug_view_; +}; + +} /* namespace intensity_histogram. */ + +class IntensityHistogramNodelet : public nodelet::Nodelet +{ + + public: + + virtual void onInit() // NOLINT(modernize-use-override) + { + intensity_histogram::IntensityHistogram ih; + ros::spin(); + } +}; + +} /* namespace opencv_apps. */ + +#include +PLUGINLIB_EXPORT_CLASS(opencv_apps::IntensityHistogramNodelet, nodelet::Nodelet); From 5c2b2253cb6b30d0422915debd2d52fe9e0444c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20=C3=89corchard?= Date: Wed, 15 Apr 2020 14:46:42 +0200 Subject: [PATCH 2/5] Try to satisfy clang-format and clang-tidy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gaël Écorchard --- src/nodelet/intensity_histogram.cpp | 177 ++++++++++++++-------------- 1 file changed, 90 insertions(+), 87 deletions(-) diff --git a/src/nodelet/intensity_histogram.cpp b/src/nodelet/intensity_histogram.cpp index b8f0df91..567aa697 100644 --- a/src/nodelet/intensity_histogram.cpp +++ b/src/nodelet/intensity_histogram.cpp @@ -55,17 +55,18 @@ namespace intensity_histogram static const std::string OPENCV_WINDOW = "Image histogram"; -cv::Mat grayHistogram(cv_bridge::CvImageConstPtr img) +cv::Mat grayHistogram(const cv_bridge::CvImageConstPtr& img) { - /* Inspired by https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/Histograms_Matching/calcHist_Demo.cpp. */ + /* Inspired by + * https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/Histograms_Matching/calcHist_Demo.cpp. */ constexpr bool uniform = true; constexpr bool accumulate = false; constexpr int bin_count = 256; - float range[] = {0, 256}; //the upper boundary is exclusive - const float* hist_range = {range}; + float range[] = { 0, 256 }; //the upper boundary is exclusive + const float* hist_range = { range }; cv::Mat intensity_hist; - cv::calcHist(&img->image, 1, 0, cv::Mat(), intensity_hist, 1, &bin_count, &hist_range, uniform, accumulate); + cv::calcHist(&img->image, 1, nullptr, cv::Mat(), intensity_hist, 1, &bin_count, &hist_range, uniform, accumulate); int hist_w = 512; int hist_h = 400; int bin_w = cvRound(static_cast(hist_w / bin_count)); @@ -74,16 +75,17 @@ cv::Mat grayHistogram(cv_bridge::CvImageConstPtr img) for (unsigned int i = 1; i < bin_count; i++) { cv::line(hist_image, - cv::Point(bin_w * (i-1), hist_h - cvRound(intensity_hist.at(i-1))), - cv::Point(bin_w * (i), hist_h - cvRound(intensity_hist.at(i))), + cv::Point(bin_w * (i - 1), hist_h - cvRound(intensity_hist.at(i - 1))), + cv::Point(bin_w * i, hist_h - cvRound(intensity_hist.at(i))), cv::Scalar(255), 2, 8, 0); } return hist_image; } -cv::Mat bgrHistogram(cv_bridge::CvImageConstPtr img) +cv::Mat bgrHistogram(const cv_bridge::CvImageConstPtr& img) { - /* Inspired by https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/Histograms_Matching/calcHist_Demo.cpp. */ + /* Inspired by + * https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/Histograms_Matching/calcHist_Demo.cpp. */ constexpr bool uniform = true; constexpr bool accumulate = false; constexpr int bin_count = 256; @@ -96,9 +98,9 @@ cv::Mat bgrHistogram(cv_bridge::CvImageConstPtr img) cv::Mat b_hist; cv::Mat g_hist; cv::Mat r_hist; - cv::calcHist(&bgr_planes[0], 1, 0, cv::Mat(), b_hist, 1, &bin_count, &hist_range, uniform, accumulate); - cv::calcHist(&bgr_planes[1], 1, 0, cv::Mat(), g_hist, 1, &bin_count, &hist_range, uniform, accumulate); - cv::calcHist(&bgr_planes[2], 1, 0, cv::Mat(), r_hist, 1, &bin_count, &hist_range, uniform, accumulate); + cv::calcHist(&bgr_planes[0], 1, nullptr, cv::Mat(), b_hist, 1, &bin_count, &hist_range, uniform, accumulate); + cv::calcHist(&bgr_planes[1], 1, nullptr, cv::Mat(), g_hist, 1, &bin_count, &hist_range, uniform, accumulate); + cv::calcHist(&bgr_planes[2], 1, nullptr, cv::Mat(), r_hist, 1, &bin_count, &hist_range, uniform, accumulate); int hist_w = 512; int hist_h = 400; int bin_w = cvRound(static_cast(hist_w / bin_count)); @@ -109,16 +111,16 @@ cv::Mat bgrHistogram(cv_bridge::CvImageConstPtr img) for (unsigned int i = 1; i < bin_count; i++) { cv::line(hist_image, - cv::Point(bin_w * (i-1), hist_h - cvRound(b_hist.at(i-1))), - cv::Point(bin_w * (i), hist_h - cvRound(b_hist.at(i))), + cv::Point(bin_w * (i - 1), hist_h - cvRound(b_hist.at(i - 1))), + cv::Point(bin_w * i, hist_h - cvRound(b_hist.at(i))), cv::Scalar(255, 0, 0), 2, 8, 0); cv::line(hist_image, - cv::Point(bin_w * (i-1), hist_h - cvRound(g_hist.at(i-1))), - cv::Point(bin_w * (i), hist_h - cvRound(g_hist.at(i))), + cv::Point(bin_w * (i - 1), hist_h - cvRound(g_hist.at(i - 1))), + cv::Point(bin_w * i, hist_h - cvRound(g_hist.at(i))), cv::Scalar(0, 255, 0), 2, 8, 0); cv::line(hist_image, - cv::Point(bin_w * (i-1), hist_h - cvRound(r_hist.at(i-1))), - cv::Point(bin_w * (i), hist_h - cvRound(r_hist.at(i))), + cv::Point(bin_w * (i - 1), hist_h - cvRound(r_hist.at(i - 1))), + cv::Point(bin_w * i, hist_h - cvRound(r_hist.at(i))), cv::Scalar(0, 0, 255), 2, 8, 0); } return hist_image; @@ -127,95 +129,96 @@ cv::Mat bgrHistogram(cv_bridge::CvImageConstPtr img) class IntensityHistogram { - public: +public: + + IntensityHistogram() : + it_(nh_) + { + ros::NodeHandle private_nh("~"); + private_nh.param("queue_size", queue_size_, 1); + private_nh.param("debug_view", debug_view_, false); + + image_sub_ = it_.subscribe("image", queue_size_, &IntensityHistogram::imageCallback, this); + hist_pub_ = it_.advertise("image_hist", queue_size_); + + if (debug_view_) + { + cv::namedWindow(OPENCV_WINDOW); + } + } + + ~IntensityHistogram() + { + if (debug_view_) + { + cv::destroyWindow(OPENCV_WINDOW); + } + } - IntensityHistogram() : - it_(nh_) + void imageCallback(const sensor_msgs::ImageConstPtr& msg) + { + cv_bridge::CvImageConstPtr cv_ptr; + try + { + cv_ptr = cv_bridge::toCvShare(msg); + } + catch (cv_bridge::Exception& e) { - image_sub_ = it_.subscribe("image", queue_size_, &IntensityHistogram::imageCallback, this); - hist_pub_ = it_.advertise("image_hist", 1); - - ros::NodeHandle private_nh("~"); - private_nh.param("queue_size", queue_size_, 1); - private_nh.param("debug_view", debug_view_, false); - if (debug_view_) - { - cv::namedWindow(OPENCV_WINDOW); - } + ROS_ERROR("cv_bridge exception: %s", e.what()); + return; } - ~IntensityHistogram() + cv::Mat out_img; + sensor_msgs::Image::Ptr out_img_msg; + if (cv_ptr->image.channels() == 1) + { + out_img = grayHistogram(cv_ptr); + out_img_msg = cv_bridge::CvImage( + msg->header, sensor_msgs::image_encodings::MONO8, out_img).toImageMsg(); + + } + else { - if (debug_view_) - { - cv::destroyWindow(OPENCV_WINDOW); - } + out_img = bgrHistogram(cv_ptr); + out_img_msg = cv_bridge::CvImage( + msg->header, sensor_msgs::image_encodings::RGB8, out_img).toImageMsg(); } - void imageCallback(const sensor_msgs::ImageConstPtr& msg) + if (debug_view_) { - cv_bridge::CvImageConstPtr cv_ptr; - try - { - cv_ptr = cv_bridge::toCvShare(msg); - } - catch (cv_bridge::Exception& e) - { - ROS_ERROR("cv_bridge exception: %s", e.what()); - return; - } - - cv::Mat out_img; - sensor_msgs::Image::Ptr out_img_msg; - if (cv_ptr->image.channels() == 1) - { - out_img = grayHistogram(cv_ptr); - out_img_msg = cv_bridge::CvImage( - msg->header, sensor_msgs::image_encodings::MONO8, out_img).toImageMsg(); - - } - else - { - out_img = bgrHistogram(cv_ptr); - out_img_msg = cv_bridge::CvImage( - msg->header, sensor_msgs::image_encodings::RGB8, out_img).toImageMsg(); - } - - if (debug_view_) - { - // Update GUI Window - cv::imshow(OPENCV_WINDOW, out_img); - cv::waitKey(3); - } - - hist_pub_.publish(out_img_msg); + // Update GUI Window + cv::imshow(OPENCV_WINDOW, out_img); + cv::waitKey(3); } - private: + hist_pub_.publish(out_img_msg); + } + +private: - ros::NodeHandle nh_; - image_transport::ImageTransport it_; - image_transport::Subscriber image_sub_; - image_transport::Publisher hist_pub_; - int queue_size_; - bool debug_view_; + ros::NodeHandle nh_; + image_transport::ImageTransport it_; + image_transport::Subscriber image_sub_; + image_transport::Publisher hist_pub_; + int queue_size_; + bool debug_view_; }; -} /* namespace intensity_histogram. */ +} /* namespace intensity_histogram. */ class IntensityHistogramNodelet : public nodelet::Nodelet { - public: +public: - virtual void onInit() // NOLINT(modernize-use-override) - { - intensity_histogram::IntensityHistogram ih; - ros::spin(); - } + virtual void onInit() // NOLINT(modernize-use-override) + { + intensity_histogram::IntensityHistogram ih; + ros::spin(); + } }; -} /* namespace opencv_apps. */ +} /* namespace opencv_apps. */ #include PLUGINLIB_EXPORT_CLASS(opencv_apps::IntensityHistogramNodelet, nodelet::Nodelet); From 44d39941c56d4595be2684e39e1c1622cc18dfbd Mon Sep 17 00:00:00 2001 From: Kei Okada Date: Mon, 14 Feb 2022 16:07:31 +0900 Subject: [PATCH 3/5] add CalcHist, CompareHist example, rewrited from #104 --- CMakeLists.txt | 5 +- cfg/CompareHistogram.cfg | 53 ++++ ...togram.launch => compare_histogram.launch} | 8 +- nodelet_plugins.xml | 8 +- src/nodelet/compare_histogram_nodelet.cpp | 299 ++++++++++++++++++ src/nodelet/intensity_histogram.cpp | 224 ------------- test/CMakeLists.txt | 1 + test/test-compare_histogram.test | 66 ++++ 8 files changed, 433 insertions(+), 231 deletions(-) create mode 100755 cfg/CompareHistogram.cfg rename launch/{intensity_histogram.launch => compare_histogram.launch} (59%) create mode 100644 src/nodelet/compare_histogram_nodelet.cpp delete mode 100644 src/nodelet/intensity_histogram.cpp create mode 100644 test/test-compare_histogram.test diff --git a/CMakeLists.txt b/CMakeLists.txt index 4bdd4a53..ce3e3e2d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,6 +52,7 @@ generate_dynamic_reconfigure_options( cfg/GoodfeatureTrack.cfg cfg/CornerHarris.cfg # + cfg/CompareHistogram.cfg cfg/EqualizeHistogram.cfg cfg/CamShift.cfg cfg/FBackFlow.cfg @@ -169,7 +170,7 @@ opencv_apps_add_nodelet(discrete_fourier_transform src/nodelet/discrete_fourier_ # ./tutorial_code/Histograms_Matching/calcBackProject_Demo1.cpp # ./tutorial_code/Histograms_Matching/calcBackProject_Demo2.cpp # ./tutorial_code/Histograms_Matching/calcHist_Demo.cpp - # ./tutorial_code/Histograms_Matching/compareHist_Demo.cpp + opencv_apps_add_nodelet(compare_histogram src/nodelet/compare_histogram_nodelet.cpp) # ./tutorial_code/Histograms_Matching/compareHist_Demo.cpp opencv_apps_add_nodelet(equalize_histogram src/nodelet/equalize_histogram_nodelet.cpp) # ./tutorial_code/Histograms_Matching/EqualizeHist_Demo.cpp # ./tutorial_code/Histograms_Matching/MatchTemplate_Demo.cpp @@ -263,7 +264,7 @@ opencv_apps_add_nodelet(camshift src/nodelet/camshift_nodelet.cpp) # ./camshiftd # ./create_mask.cpp # ./dbt_face_detection.cpp # ./delaunay2.cpp -opencv_apps_add_nodelet(intensity_histogram src/nodelet/intensity_histogram.cpp) # ./demhist.cpp +# ./demhist.cpp # ./detect_blob.cpp # ./detect_mser.cpp # ./dft.cpp diff --git a/cfg/CompareHistogram.cfg b/cfg/CompareHistogram.cfg new file mode 100755 index 00000000..769ffc72 --- /dev/null +++ b/cfg/CompareHistogram.cfg @@ -0,0 +1,53 @@ +#! /usr/bin/env python +# Software License Agreement (BSD License) +# +# Copyright (c) 2022, Kei Okada +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of Kei Okada nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + + +PACKAGE = "opencv_apps" + +from dynamic_reconfigure.parameter_generator_catkin import * + +gen = ParameterGenerator() +gen.add("use_camera_info", bool_t, 0, "Indicates that the camera_info topic should be subscribed to to get the default input_frame_id. Otherwise the frame from the image message will be used.", False) + +histogram_comparison_type = gen.enum([ gen.const("Correlation", int_t, 0, "Correlation"), + gen.const("Chi_Square", int_t, 1, "Chi-Square"), + gen.const("Intersection", int_t, 2, "Intersection"), + gen.const("Bhattacharyya", int_t, 3, "Bhattacharyya distance")], + "Histogram Comparison method") +gen.add("histogram_comparison_type", int_t, 1, "Histogram Comparison method", 0, 0, 3, edit_method=histogram_comparison_type) + +gen.add("histogram_size", int_t, 2, "Array of histogram sizes in each dimension", 256, 1, 1024) +gen.add("uniform", bool_t, 3, "Flag indicating whether the histogram is uniform or not", True) +gen.add("accumulate", bool_t, 4, "Accumulation flag. If it is set, the histogram is not cleared in the beginning when it is allocated", False) + +exit(gen.generate(PACKAGE, "compare_histogram", "CompareHistogram")) diff --git a/launch/intensity_histogram.launch b/launch/compare_histogram.launch similarity index 59% rename from launch/intensity_histogram.launch rename to launch/compare_histogram.launch index 9eb8185c..3b729369 100644 --- a/launch/intensity_histogram.launch +++ b/launch/compare_histogram.launch @@ -5,12 +5,18 @@ + + - + + + + $(arg reference_histogram) + diff --git a/nodelet_plugins.xml b/nodelet_plugins.xml index 9620bb73..430ac892 100644 --- a/nodelet_plugins.xml +++ b/nodelet_plugins.xml @@ -123,12 +123,12 @@ Nodelet to demonstrate the famous watershed segmentation algorithm in OpenCV: watershed() - - Nodelet for histogram equalization + + Nodelet of compare histogram - - Nodelet of intensity histogram + + Nodelet for histogram equalization + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 49e4e7241033a30a319b3d92ad6942b75f9f04d0 Mon Sep 17 00:00:00 2001 From: Kei Okada Date: Wed, 16 Feb 2022 10:51:00 +0900 Subject: [PATCH 4/5] HISTCMP_CORREL only available since OpenCV 3.0 (https://github.com/opencv/opencv/pull/785) --- CMakeLists.txt | 4 +++- test/CMakeLists.txt | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ce3e3e2d..3c41f2dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -170,8 +170,10 @@ opencv_apps_add_nodelet(discrete_fourier_transform src/nodelet/discrete_fourier_ # ./tutorial_code/Histograms_Matching/calcBackProject_Demo1.cpp # ./tutorial_code/Histograms_Matching/calcBackProject_Demo2.cpp # ./tutorial_code/Histograms_Matching/calcHist_Demo.cpp +if(OpenCV_VERSION VERSION_GREATER "3.0") opencv_apps_add_nodelet(compare_histogram src/nodelet/compare_histogram_nodelet.cpp) # ./tutorial_code/Histograms_Matching/compareHist_Demo.cpp - opencv_apps_add_nodelet(equalize_histogram src/nodelet/equalize_histogram_nodelet.cpp) # ./tutorial_code/Histograms_Matching/EqualizeHist_Demo.cpp +endif() +opencv_apps_add_nodelet(equalize_histogram src/nodelet/equalize_histogram_nodelet.cpp) # ./tutorial_code/Histograms_Matching/EqualizeHist_Demo.cpp # ./tutorial_code/Histograms_Matching/MatchTemplate_Demo.cpp # imagecodecs diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0276c333..da616de7 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -56,7 +56,9 @@ add_rostest(test-hls_color_filter.test ARGS gui:=false) add_rostest(test-hsv_color_filter.test ARGS gui:=false) add_rostest(test-lab_color_filter.test ARGS gui:=false) add_rostest(test-edge_detection.test ARGS gui:=false) -add_rostest(test-compare_histogram.test ARGS gui:=false) +if(OpenCV_VERSION VERSION_GREATER "3.0") + add_rostest(test-compare_histogram.test ARGS gui:=false) +endif() add_rostest(test-equalize_histogram.test ARGS gui:=false) add_rostest(test-hough_lines.test ARGS gui:=false) From 5f9777b77e2c267192fe3c77b4d7e2cb0cd5bebe Mon Sep 17 00:00:00 2001 From: Kei Okada Date: Fri, 18 Feb 2022 14:25:55 +0900 Subject: [PATCH 5/5] OpenCV < 3 : remove compare_histogram from roslaunch_add_file_check --- CMakeLists.txt | 3 +++ test/CMakeLists.txt | 3 +++ 2 files changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c41f2dd..af543659 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -390,6 +390,9 @@ if(CATKIN_ENABLE_TESTING) message(WARNING "roslaunch_add_file check fails with unsupported doc attributes ${roslaunch_VERSION}") else() file(GLOB LAUNCH_FILES launch/*.launch) + if(NOT OpenCV_VERSION VERSION_GREATER "3.0") + list(REMOVE_ITEM LAUNCH_FILES ${CMAKE_CURRENT_SOURCE_DIR}/launch/compare_histogram.launch) + endif() foreach(LAUNCH_FILE ${LAUNCH_FILES}) roslaunch_add_file_check(${LAUNCH_FILE}) endforeach() diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index da616de7..3cd329b9 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -108,6 +108,9 @@ if(roslaunch_VERSION VERSION_LESS "1.11.1") message(WARNING "roslaunch_add_file check fails with unsupported doc attributes ${roslaunch_VERSION}") else() file(GLOB LAUNCH_FILES *.test) + if(NOT OpenCV_VERSION VERSION_GREATER "3.0") + list(REMOVE_ITEM LAUNCH_FILES ${CMAKE_CURRENT_SOURCE_DIR}/test-compare_histogram.test) + endif() foreach(LAUNCH_FILE ${LAUNCH_FILES}) roslaunch_add_file_check(${LAUNCH_FILE}) endforeach()