Skip to content

Commit

Permalink
Merge branch '224-compute-entropy-mi' into 'release'
Browse files Browse the repository at this point in the history
Resolve "IM: Calcul de l'entropie et de l'IM en cpp"

See merge request 3d/PandoraBox/pandora2d!187
  • Loading branch information
lecontm committed Dec 16, 2024
2 parents 1f97c00 + a29b555 commit ca5ad34
Show file tree
Hide file tree
Showing 5 changed files with 549 additions and 1 deletion.
75 changes: 75 additions & 0 deletions pandora2d/matching_cost_cpp/include/mutual_information.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/* Copyright (c) 2024 Centre National d'Etudes Spatiales (CNES).
*
* This file is part of PANDORA2D
*
* https://github.com/CNES/Pandora2D
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/*
This module contains functions associated to the mutual information in cpp.
*/

#ifndef MUTUAL_INFORMATION_HPP
#define MUTUAL_INFORMATION_HPP

#include "histogram1D.hpp"
#include "histogram2D.hpp"

/**
* @brief Compute entropy
*
* @tparam T hist1D or hist2D
* @param nb_pixel of the image
* @param hist to iterate
* @return double entropy
*/
template <typename T>
double get_entropy(const double nb_pixel, const T &hist);

/**
* @brief Compute entropy 1D of an image
*
* Entropy1D(img) = - sum(bin_value/nb_pixel * log2(bin_value/nb_pixel))
* for each bin_value in Hist1D(img)
*
* @param img
* @return double entropy1D value
*/
double calculate_entropy1D(const Eigen::MatrixXd &img);

/**
* @brief Compute entropy 2D of two images
*
* Entropy2D(img_l, img_r) = - sum(bin_value/nb_pixel * log2(bin_value/nb_pixel))
* for each bin_value in Hist2D(img_l, img_r)
*
* @param img_l left image
* @param img_r right image
* @return double entropy 2D value
*/
double calculate_entropy2D(const Eigen::MatrixXd &img_l, const Eigen::MatrixXd &img_r);

/**
* @brief Compute mutual information between two images
*
* MutualInformation(img_l,img_r) = Entropy1D(img_l) + Entropy1D(img_r) - Entropy2D(img_l, img_r)
*
* @param img_l left image
* @param img_r right image
* @return double mutual information value
*/
double calculate_mutual_information(const Eigen::MatrixXd &img_l, const Eigen::MatrixXd &img_r);

#endif
3 changes: 2 additions & 1 deletion pandora2d/matching_cost_cpp/meson.build
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
matching_cost_includes = include_directories('include')
matching_cost_src = files('src/histogram1D.cpp', 'src/histogram2D.cpp', 'src/operation.cpp', 'src/bin.cpp')
matching_cost_src = files('src/histogram1D.cpp', 'src/histogram2D.cpp', 'src/operation.cpp', 'src/bin.cpp',
'src/mutual_information.cpp')

py.extension_module(
'matching_cost_cpp',
Expand Down
106 changes: 106 additions & 0 deletions pandora2d/matching_cost_cpp/src/mutual_information.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/* Copyright (c) 2024 Centre National d'Etudes Spatiales (CNES).
*
* This file is part of PANDORA2D
*
* https://github.com/CNES/Pandora2D
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/*
This module contains functions associated to the mutual information in cpp.
*/

#include "mutual_information.hpp"

/**
* @brief Compute entropy
*
* @tparam T hist1D or hist2D
* @param nb_pixel of the image
* @param hist to iterate
* @return double entropy
*/
template <typename T>
double get_entropy(const double nb_pixel, const T &hist){

double entropy = 0.0 ;

for (auto bin_value : hist.values().reshaped())
{
if (bin_value != 0.)
{
entropy -= bin_value / nb_pixel * std::log2(bin_value / nb_pixel);
}
};

// Entropy cannot be negative
return entropy < 0. ? 0. : entropy ;

};

/**
* @brief Compute entropy 1D of an image
*
* Entropy1D(img) = - sum(bin_value/nb_pixel * log2(bin_value/nb_pixel))
* for each bin_value in Hist1D(img)
*
* @param img
* @return double entropy1D
*/
double calculate_entropy1D(const Eigen::MatrixXd &img)
{

auto nb_pixel = static_cast<double>(img.size());
auto hist_1D = calculate_histogram1D(img);

return get_entropy<Histogram1D>(nb_pixel, hist_1D);
};

/**
* @brief Compute entropy 2D of two images
*
* Entropy2D(img_l, img_r) = - sum(bin_value/nb_pixel * log2(bin_value/nb_pixel))
* for each bin_value in Hist2D(img_l, img_r)
*
* @param img_l left image
* @param img_r right image
* @return double entropy 2D
*/
double calculate_entropy2D(const Eigen::MatrixXd &img_l, const Eigen::MatrixXd &img_r)
{

// same size for left and right images
auto nb_pixel = static_cast<double>(img_l.size());
auto hist_2D = calculate_histogram2D(img_l, img_r);

return get_entropy<Histogram2D>(nb_pixel, hist_2D);
};

/**
* @brief Compute mutual information between two images
*
* MutualInformation(img_l,img_r) = Entropy1D(img_l) + Entropy1D(img_r) - Entropy2D(img_l, img_r)
*
* @param img_l left image
* @param img_r right image
* @return double mutual information value
*/
double calculate_mutual_information(const Eigen::MatrixXd &img_l, const Eigen::MatrixXd &img_r)
{

double mutual_information = calculate_entropy1D(img_l) + calculate_entropy1D(img_r)
- calculate_entropy2D(img_l, img_r);

return mutual_information;
}
10 changes: 10 additions & 0 deletions tests/unit_tests/test_cpp/test_matching_cost/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,14 @@ test(
include_directories:matching_cost_includes,
dependencies: [eigen_dep, doctest_dep],
),
)

test(
'MutualInformation',
executable(
'test_mutual_information',
['test_mutual_information.cpp', matching_cost_src],
include_directories:matching_cost_includes,
dependencies: [eigen_dep, doctest_dep],
),
)
Loading

0 comments on commit ca5ad34

Please sign in to comment.