diff --git a/modules/ccm/CMakeLists.txt b/modules/ccm/CMakeLists.txt new file mode 100644 index 00000000000..f2ff0532b20 --- /dev/null +++ b/modules/ccm/CMakeLists.txt @@ -0,0 +1,9 @@ +set(the_description "Color Correction Module") +ocv_define_module(ccm + opencv_core + opencv_imgproc + opencv_3d + opencv_dnn + WRAP + python +) diff --git a/modules/mcc/include/opencv2/mcc/ccm.hpp b/modules/ccm/include/opencv2/ccm.hpp similarity index 99% rename from modules/mcc/include/opencv2/mcc/ccm.hpp rename to modules/ccm/include/opencv2/ccm.hpp index a3686db473d..b44ac657af0 100644 --- a/modules/mcc/include/opencv2/mcc/ccm.hpp +++ b/modules/ccm/include/opencv2/ccm.hpp @@ -25,8 +25,8 @@ // Jinheng Zhang // Chenqi Shan -#ifndef __OPENCV_MCC_CCM_HPP__ -#define __OPENCV_MCC_CCM_HPP__ +#ifndef __OPENCV_CCM_HPP__ +#define __OPENCV_CCM_HPP__ #include #include @@ -35,7 +35,8 @@ namespace cv { namespace ccm { -/** @addtogroup color_correction + +/** @defgroup ccm Color Correction module @{ Introduction diff --git a/modules/ccm/perf/perf_ccm.cpp b/modules/ccm/perf/perf_ccm.cpp new file mode 100644 index 00000000000..0d523e3478c --- /dev/null +++ b/modules/ccm/perf/perf_ccm.cpp @@ -0,0 +1,41 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#include "perf_precomp.hpp" +#include "opencv2/ccm.hpp" + +namespace opencv_test +{ +namespace +{ + +using namespace std; +using namespace cv::ccm; + +PERF_TEST(CV_mcc_perf, infer) { + // read gold chartsRGB + string path = cvtest::findDataFile("cv/mcc/mcc_ccm_test.yml"); + FileStorage fs(path, FileStorage::READ); + Mat chartsRGB; + FileNode node = fs["chartsRGB"]; + node >> chartsRGB; + fs.release(); + + // compute CCM + ColorCorrectionModel model(chartsRGB.col(1).clone().reshape(3, chartsRGB.rows/3) / 255., COLORCHECKER_Macbeth); + model.run(); + + Mat img(1000, 4000, CV_8UC3); + randu(img, 0, 255); + img.convertTo(img, CV_64F, 1. / 255.); + + TEST_CYCLE() { + model.infer(img); + } + + SANITY_CHECK_NOTHING(); +} + +} // namespace +} // namespace opencv_test diff --git a/modules/ccm/perf/perf_main.cpp b/modules/ccm/perf/perf_main.cpp new file mode 100644 index 00000000000..a5b36b66913 --- /dev/null +++ b/modules/ccm/perf/perf_main.cpp @@ -0,0 +1,3 @@ +#include "perf_precomp.hpp" + +CV_PERF_TEST_MAIN(ccm) diff --git a/modules/ccm/perf/perf_precomp.hpp b/modules/ccm/perf/perf_precomp.hpp new file mode 100644 index 00000000000..e494ddca5e6 --- /dev/null +++ b/modules/ccm/perf/perf_precomp.hpp @@ -0,0 +1,13 @@ +#ifndef __OPENCV_PERF_PRECOMP_HPP__ +#define __OPENCV_PERF_PRECOMP_HPP__ + +#include "opencv2/ts.hpp" +#include "opencv2/ccm.hpp" + +namespace opencv_test +{ +using namespace cv::ccm; +using namespace perf; +} + +#endif diff --git a/modules/ccm/samples/color_correction_model.cpp b/modules/ccm/samples/color_correction_model.cpp new file mode 100644 index 00000000000..02dd62e73a8 --- /dev/null +++ b/modules/ccm/samples/color_correction_model.cpp @@ -0,0 +1,158 @@ +//! [tutorial] +#include + +#include +#include +#include +#include + +using namespace std; +using namespace cv; +using namespace ccm; + +const char *about = "Basic chart detection"; +const char *keys = + "{ help h | | show this message }" + "{ f | 1 | Path of the file to process (-v) }"; + +int main(int argc, char *argv[]) +{ + + + // ---------------------------------------------------------- + // Scroll down a bit (~40 lines) to find actual relevant code + // ---------------------------------------------------------- + //! [get_messages_of_image] + CommandLineParser parser(argc, argv, keys); + parser.about(about); + if (argc==1 || parser.has("help")) + { + parser.printMessage(); + return 0; + } + + string filepath = parser.get("f"); + + if (!parser.check()) + { + parser.printErrors(); + return 0; + } + + Mat image = imread(filepath, IMREAD_COLOR); + if (!image.data) + { + cout << "Invalid Image!" << endl; + return 1; + } + //! [get_messages_of_image] + + Mat src(24, 1, CV_64FC3); + + // Hardcoded values. Image used: opencv_extra/testdata/cv/mcc/mcc_ccm_test.jpg + double values[24][3] = { + {0.380463, 0.31696, 0.210053}, + {0.649781, 0.520561, 0.452553}, + {0.323114, 0.37593, 0.50123}, + {0.314785, 0.396522, 0.258116}, + {0.452971, 0.418602, 0.578767}, + {0.34908, 0.608649, 0.652283}, + {0.691127, 0.517818, 0.144984}, + {0.208668, 0.224391, 0.485851}, + {0.657849, 0.378126, 0.304115}, + {0.285762, 0.229671, 0.31913}, + {0.513422, 0.685031, 0.337381}, + {0.786459, 0.676133, 0.246303}, + {0.11751, 0.135079, 0.383441}, + {0.190745, 0.470513, 0.296844}, + {0.587832, 0.299132, 0.196117}, + {0.783908, 0.746261, 0.294357}, + {0.615481, 0.359983, 0.471403}, + {0.107095, 0.370516, 0.573142}, + {0.708598, 0.718936, 0.740915}, + {0.593812, 0.612474, 0.63222}, + {0.489774, 0.510077, 0.521757}, + {0.380591, 0.398499, 0.393662}, + {0.27461, 0.293267, 0.275244}, + {0.180753, 0.194968, 0.145006} + }; + + // Assign values to src + for (int i = 0; i < 24; i++) { + src.at(i, 0) = cv::Vec3d(values[i][0], values[i][1], values[i][2]); + } + + //compte color correction matrix + //! [get_ccm_Matrix] + ColorCorrectionModel model1(src, COLORCHECKER_Macbeth); + model1.run(); + Mat ccm = model1.getCCM(); + std::cout<<"ccm "<(18, 1) << + // Vec3d(100, 0.00520000001, -0.0104), + // Vec3d(73.0833969, -0.819999993, -2.02099991), + // Vec3d(62.493, 0.425999999, -2.23099995), + // Vec3d(50.4640007, 0.446999997, -2.32399988), + // Vec3d(37.7970009, 0.0359999985, -1.29700005), + // Vec3d(0, 0, 0), + // Vec3d(51.5880013, 73.5179977, 51.5690002), + // Vec3d(93.6989975, -15.7340002, 91.9420013), + // Vec3d(69.4079971, -46.5940018, 50.4869995), + // Vec3d(66.61000060000001, -13.6789999, -43.1720009), + // Vec3d(11.7110004, 16.9799995, -37.1759987), + // Vec3d(51.973999, 81.9440002, -8.40699959), + // Vec3d(40.5489998, 50.4399986, 24.8490009), + // Vec3d(60.8160019, 26.0690002, 49.4420013), + // Vec3d(52.2529984, -19.9500008, -23.9960003), + // Vec3d(51.2859993, 48.4700012, -15.0579996), + // Vec3d(68.70700069999999, 12.2959995, 16.2129993), + // Vec3d(63.6839981, 10.2930002, 16.7639999)); + + // ColorCorrectionModel model8(src,ref,COLOR_SPACE_Lab_D50_2); + // model8.run(); + //! [reference_color_values] + + //! [make_color_correction] + Mat img_; + cvtColor(image, img_, COLOR_BGR2RGB); + img_.convertTo(img_, CV_64F); + const int inp_size = 255; + const int out_size = 255; + img_ = img_ / inp_size; + Mat calibratedImage= model1.infer(img_); + Mat out_ = calibratedImage * out_size; + //! [make_color_correction] + + //! [Save_calibrated_image] + // Save the calibrated image to {FILE_NAME}.calibrated.{FILE_EXT} + out_.convertTo(out_, CV_8UC3); + Mat img_out = min(max(out_, 0), out_size); + Mat out_img; + cvtColor(img_out, out_img, COLOR_RGB2BGR); + string filename = filepath.substr(filepath.find_last_of('/')+1); + size_t dotIndex = filename.find_last_of('.'); + string baseName = filename.substr(0, dotIndex); + string ext = filename.substr(dotIndex+1, filename.length()-dotIndex); + string calibratedFilePath = baseName + ".calibrated." + ext; + imwrite(calibratedFilePath, out_img); + //! [Save_calibrated_image] + + return 0; +} +//! [tutorial] \ No newline at end of file diff --git a/modules/mcc/src/ccm.cpp b/modules/ccm/src/ccm.cpp similarity index 99% rename from modules/mcc/src/ccm.cpp rename to modules/ccm/src/ccm.cpp index aec535e05b4..27c3728a661 100644 --- a/modules/mcc/src/ccm.cpp +++ b/modules/ccm/src/ccm.cpp @@ -25,7 +25,7 @@ // Jinheng Zhang // Chenqi Shan -#include "opencv2/mcc/ccm.hpp" +#include "opencv2/ccm.hpp" #include "linearize.hpp" namespace cv { namespace ccm { diff --git a/modules/mcc/src/color.cpp b/modules/ccm/src/color.cpp similarity index 100% rename from modules/mcc/src/color.cpp rename to modules/ccm/src/color.cpp diff --git a/modules/mcc/src/color.hpp b/modules/ccm/src/color.hpp similarity index 97% rename from modules/mcc/src/color.hpp rename to modules/ccm/src/color.hpp index 57ead3558c7..858fd428010 100644 --- a/modules/mcc/src/color.hpp +++ b/modules/ccm/src/color.hpp @@ -25,12 +25,12 @@ // Jinheng Zhang // Chenqi Shan -#ifndef __OPENCV_MCC_COLOR_HPP__ -#define __OPENCV_MCC_COLOR_HPP__ +#ifndef __OPENCV_CCM_COLOR_HPP__ +#define __OPENCV_CCM_COLOR_HPP__ #include "distance.hpp" #include "colorspace.hpp" -#include "opencv2/mcc/ccm.hpp" +#include "opencv2/ccm.hpp" namespace cv { namespace ccm { diff --git a/modules/mcc/src/colorspace.cpp b/modules/ccm/src/colorspace.cpp similarity index 100% rename from modules/mcc/src/colorspace.cpp rename to modules/ccm/src/colorspace.cpp diff --git a/modules/mcc/src/colorspace.hpp b/modules/ccm/src/colorspace.hpp similarity index 98% rename from modules/mcc/src/colorspace.hpp rename to modules/ccm/src/colorspace.hpp index 572fea38781..f4e70c36ddb 100644 --- a/modules/mcc/src/colorspace.hpp +++ b/modules/ccm/src/colorspace.hpp @@ -25,12 +25,12 @@ // Jinheng Zhang // Chenqi Shan -#ifndef __OPENCV_MCC_COLORSPACE_HPP__ -#define __OPENCV_MCC_COLORSPACE_HPP__ +#ifndef __OPENCV_CCM_COLORSPACE_HPP__ +#define __OPENCV_CCM_COLORSPACE_HPP__ #include "operations.hpp" #include "io.hpp" -#include "opencv2/mcc/ccm.hpp" +#include "opencv2/ccm.hpp" namespace cv { namespace ccm { diff --git a/modules/mcc/src/distance.cpp b/modules/ccm/src/distance.cpp similarity index 100% rename from modules/mcc/src/distance.cpp rename to modules/ccm/src/distance.cpp diff --git a/modules/mcc/src/distance.hpp b/modules/ccm/src/distance.hpp similarity index 96% rename from modules/mcc/src/distance.hpp rename to modules/ccm/src/distance.hpp index 5acfc93cdb6..0fbc533778a 100644 --- a/modules/mcc/src/distance.hpp +++ b/modules/ccm/src/distance.hpp @@ -25,11 +25,11 @@ // Jinheng Zhang // Chenqi Shan -#ifndef __OPENCV_MCC_DISTANCE_HPP__ -#define __OPENCV_MCC_DISTANCE_HPP__ +#ifndef __OPENCV_CCM_DISTANCE_HPP__ +#define __OPENCV_CCM_DISTANCE_HPP__ #include "utils.hpp" -#include "opencv2/mcc/ccm.hpp" +#include "opencv2/ccm.hpp" namespace cv { namespace ccm { diff --git a/modules/mcc/src/io.cpp b/modules/ccm/src/io.cpp similarity index 100% rename from modules/mcc/src/io.cpp rename to modules/ccm/src/io.cpp diff --git a/modules/mcc/src/io.hpp b/modules/ccm/src/io.hpp similarity index 96% rename from modules/mcc/src/io.hpp rename to modules/ccm/src/io.hpp index c79864e3c41..4fa9dce4665 100644 --- a/modules/mcc/src/io.hpp +++ b/modules/ccm/src/io.hpp @@ -25,8 +25,8 @@ // Jinheng Zhang // Chenqi Shan -#ifndef __OPENCV_MCC_IO_HPP__ -#define __OPENCV_MCC_IO_HPP__ +#ifndef __OPENCV_CCM_IO_HPP__ +#define __OPENCV_CCM_IO_HPP__ #include #include diff --git a/modules/mcc/src/linearize.cpp b/modules/ccm/src/linearize.cpp similarity index 100% rename from modules/mcc/src/linearize.cpp rename to modules/ccm/src/linearize.cpp diff --git a/modules/mcc/src/linearize.hpp b/modules/ccm/src/linearize.hpp similarity index 97% rename from modules/mcc/src/linearize.hpp rename to modules/ccm/src/linearize.hpp index a703b5c5293..7f5d516dce5 100644 --- a/modules/mcc/src/linearize.hpp +++ b/modules/ccm/src/linearize.hpp @@ -25,13 +25,13 @@ // Jinheng Zhang // Chenqi Shan -#ifndef __OPENCV_MCC_LINEARIZE_HPP__ -#define __OPENCV_MCC_LINEARIZE_HPP__ +#ifndef __OPENCV_CCM_LINEARIZE_HPP__ +#define __OPENCV_CCM_LINEARIZE_HPP__ #include #include #include "color.hpp" -#include "opencv2/mcc/ccm.hpp" +#include "opencv2/ccm.hpp" namespace cv { namespace ccm { diff --git a/modules/mcc/src/operations.cpp b/modules/ccm/src/operations.cpp similarity index 100% rename from modules/mcc/src/operations.cpp rename to modules/ccm/src/operations.cpp diff --git a/modules/mcc/src/operations.hpp b/modules/ccm/src/operations.hpp similarity index 97% rename from modules/mcc/src/operations.hpp rename to modules/ccm/src/operations.hpp index ae3b39b6019..994c4b1c39a 100644 --- a/modules/mcc/src/operations.hpp +++ b/modules/ccm/src/operations.hpp @@ -25,8 +25,8 @@ // Jinheng Zhang // Chenqi Shan -#ifndef __OPENCV_MCC_OPERATIONS_HPP__ -#define __OPENCV_MCC_OPERATIONS_HPP__ +#ifndef __OPENCV_CCM_OPERATIONS_HPP__ +#define __OPENCV_CCM_OPERATIONS_HPP__ #include "utils.hpp" diff --git a/modules/ccm/src/precomp.hpp b/modules/ccm/src/precomp.hpp new file mode 100644 index 00000000000..3cbd7bfd5e6 --- /dev/null +++ b/modules/ccm/src/precomp.hpp @@ -0,0 +1,44 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +/* + * MIT License + * + * Copyright (c) 2018 Pedro Diamel Marrero Fernández + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _CCM_PRECOMP_HPP +#define _CCM_PRECOMP_HPP + +#include + +#include +#include +#include +#include + +#include +#include + +#include "opencv2/ccm.hpp" + +#endif //_CCM_PRECOMP_HPP diff --git a/modules/mcc/src/utils.cpp b/modules/ccm/src/utils.cpp similarity index 100% rename from modules/mcc/src/utils.cpp rename to modules/ccm/src/utils.cpp diff --git a/modules/mcc/src/utils.hpp b/modules/ccm/src/utils.hpp similarity index 98% rename from modules/mcc/src/utils.hpp rename to modules/ccm/src/utils.hpp index 07ca65cb968..c7823c8b721 100644 --- a/modules/mcc/src/utils.hpp +++ b/modules/ccm/src/utils.hpp @@ -25,8 +25,8 @@ // Jinheng Zhang // Chenqi Shan -#ifndef __OPENCV_MCC_UTILS_HPP__ -#define __OPENCV_MCC_UTILS_HPP__ +#ifndef __OPENCV_CCM_UTILS_HPP__ +#define __OPENCV_CCM_UTILS_HPP__ #include diff --git a/modules/mcc/test/test_ccm.cpp b/modules/ccm/test/test_ccm.cpp similarity index 78% rename from modules/mcc/test/test_ccm.cpp rename to modules/ccm/test/test_ccm.cpp index cd6498f1b6e..71bd5b7c528 100644 --- a/modules/mcc/test/test_ccm.cpp +++ b/modules/ccm/test/test_ccm.cpp @@ -162,5 +162,66 @@ TEST(CV_ccmRunColorCorrection, test_masks_weights_2) ASSERT_MAT_NEAR(model2.getMask(), mask, 0.0); } +TEST(CV_mcc_ccm_test, compute_ccm) +{ + // read gold chartsRGB + string path = cvtest::findDataFile("mcc/mcc_ccm_test.yml"); + FileStorage fs(path, FileStorage::READ); + Mat chartsRGB; + FileNode node = fs["chartsRGB"]; + node >> chartsRGB; + + // compute CCM + ColorCorrectionModel model(chartsRGB.col(1).clone().reshape(3, chartsRGB.rows/3) / 255., COLORCHECKER_Macbeth); + model.run(); + + // read gold CCM + node = fs["ccm"]; + ASSERT_FALSE(node.empty()); + Mat gold_ccm; + node >> gold_ccm; + fs.release(); + + // check CCM + Mat ccm = model.getCCM(); + EXPECT_MAT_NEAR(gold_ccm, ccm, 1e-8); + + const double gold_loss = 4.6386569120323129; + // check loss + const double loss = model.getLoss(); + EXPECT_NEAR(gold_loss, loss, 1e-8); +} + +TEST(CV_mcc_ccm_test, infer) +{ + string path = cvtest::findDataFile("mcc/mcc_ccm_test.jpg"); + Mat img = imread(path, IMREAD_COLOR); + // read gold calibrate img + path = cvtest::findDataFile("mcc/mcc_ccm_test_res.png"); + Mat gold_img = imread(path); + + // read gold chartsRGB + path = cvtest::findDataFile("mcc/mcc_ccm_test.yml"); + FileStorage fs(path, FileStorage::READ); + Mat chartsRGB; + FileNode node = fs["chartsRGB"]; + node >> chartsRGB; + fs.release(); + + // compute CCM + ColorCorrectionModel model(chartsRGB.col(1).clone().reshape(3, chartsRGB.rows/3) / 255., COLORCHECKER_Macbeth); + model.run(); + + // compute calibrate image + Mat calibratedImage; + cvtColor(img, calibratedImage, COLOR_BGR2RGB); + calibratedImage.convertTo(calibratedImage, CV_64F, 1. / 255.); + calibratedImage = model.infer(calibratedImage); + calibratedImage.convertTo(calibratedImage, CV_8UC3, 255.); + cvtColor(calibratedImage, calibratedImage, COLOR_RGB2BGR); + // check calibrated image + EXPECT_MAT_NEAR(gold_img, calibratedImage, 0.1); +} + } // namespace } // namespace opencv_test diff --git a/modules/ccm/test/test_main.cpp b/modules/ccm/test/test_main.cpp new file mode 100644 index 00000000000..556b026ac58 --- /dev/null +++ b/modules/ccm/test/test_main.cpp @@ -0,0 +1,7 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#include "test_precomp.hpp" + +CV_TEST_MAIN("cv") diff --git a/modules/ccm/test/test_precomp.hpp b/modules/ccm/test/test_precomp.hpp new file mode 100644 index 00000000000..b6be71df3fd --- /dev/null +++ b/modules/ccm/test/test_precomp.hpp @@ -0,0 +1,17 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef __OPENCV_TEST_PRECOMP_HPP__ +#define __OPENCV_TEST_PRECOMP_HPP__ + +#include "opencv2/ts.hpp" +#include "opencv2/ts/cuda_test.hpp" +#include "opencv2/ccm.hpp" + +namespace opencv_test +{ +using namespace cv::ccm; +} + +#endif diff --git a/modules/mcc/tutorials/basic_ccm/color_correction_model.markdown b/modules/ccm/tutorials/basic_ccm/color_correction_model.markdown similarity index 87% rename from modules/mcc/tutorials/basic_ccm/color_correction_model.markdown rename to modules/ccm/tutorials/basic_ccm/color_correction_model.markdown index 76b98cd3f4b..03d1cb9d130 100644 --- a/modules/mcc/tutorials/basic_ccm/color_correction_model.markdown +++ b/modules/ccm/tutorials/basic_ccm/color_correction_model.markdown @@ -17,13 +17,13 @@ When building OpenCV, run the following command to build all the contrib modules cmake -D OPENCV_EXTRA_MODULES_PATH=/modules/ ``` -Or only build the mcc module: +Or only build the ccm module: ```make -cmake -D OPENCV_EXTRA_MODULES_PATH=/modules/mcc +cmake -D OPENCV_EXTRA_MODULES_PATH=/modules/ccm ``` -Or make sure you check the mcc module in the GUI version of CMake: cmake-gui. +Or make sure you check the ccm module in the GUI version of CMake: cmake-gui. Source Code of the sample ----------- @@ -101,13 +101,7 @@ Here are the parameters for ColorCorrectionModel ## Explanation -The first part is to detect the ColorChecker position. -@snippet samples/color_correction_model.cpp get_color_checker -@snippet samples/color_correction_model.cpp get_messages_of_image -Preparation for ColorChecker detection to get messages for the image. - -@snippet samples/color_correction_model.cpp create -The CCheckerDetectorobject is created and uses getListColorChecker function to get ColorChecker message. +The first part is to detect the ColorChecker position which can be done with the help of MCC module. @snippet samples/color_correction_model.cpp get_ccm_Matrix For every ColorChecker, we can compute a ccm matrix for color correction. Model1 is an object of ColorCorrectionModel class. The parameters should be changed to get the best effect of color correction. See other parameters' detail at the Parameters. diff --git a/modules/mcc/tutorials/table_of_content_ccm.markdown b/modules/ccm/tutorials/table_of_content_ccm.markdown similarity index 100% rename from modules/mcc/tutorials/table_of_content_ccm.markdown rename to modules/ccm/tutorials/table_of_content_ccm.markdown diff --git a/modules/mcc/include/opencv2/mcc.hpp b/modules/mcc/include/opencv2/mcc.hpp index e49f3053ffa..4a264a7eefd 100644 --- a/modules/mcc/include/opencv2/mcc.hpp +++ b/modules/mcc/include/opencv2/mcc.hpp @@ -32,15 +32,9 @@ #include "mcc/checker_detector.hpp" #include "mcc/checker_model.hpp" -#include "mcc/ccm.hpp" /** @defgroup mcc Macbeth Chart module @{ - @defgroup color_correction Color Correction Model -@} - - -@addtogroup mcc Introduction ------------ @@ -54,6 +48,7 @@ colors that are present in the image, based on this information we can apply any suitable algorithm to find the actual color of all the objects present in the image. +@} */ #endif diff --git a/modules/mcc/perf/perf_mcc.cpp b/modules/mcc/perf/perf_mcc.cpp index f5e721074b7..b9a7ec1d095 100644 --- a/modules/mcc/perf/perf_mcc.cpp +++ b/modules/mcc/perf/perf_mcc.cpp @@ -23,29 +23,5 @@ PERF_TEST(CV_mcc_perf, detect) { SANITY_CHECK_NOTHING(); } -PERF_TEST(CV_mcc_perf, infer) { - // read gold chartsRGB - string path = cvtest::findDataFile("cv/mcc/mcc_ccm_test.yml"); - FileStorage fs(path, FileStorage::READ); - Mat chartsRGB; - FileNode node = fs["chartsRGB"]; - node >> chartsRGB; - fs.release(); - - // compute CCM - ColorCorrectionModel model(chartsRGB.col(1).clone().reshape(3, chartsRGB.rows/3) / 255., COLORCHECKER_Macbeth); - model.run(); - - Mat img(1000, 4000, CV_8UC3); - randu(img, 0, 255); - img.convertTo(img, CV_64F, 1. / 255.); - - TEST_CYCLE() { - model.infer(img); - } - - SANITY_CHECK_NOTHING(); -} - } // namespace } // namespace opencv_test diff --git a/modules/mcc/perf/perf_precomp.hpp b/modules/mcc/perf/perf_precomp.hpp index 5ef54694959..447d2c164b1 100644 --- a/modules/mcc/perf/perf_precomp.hpp +++ b/modules/mcc/perf/perf_precomp.hpp @@ -7,7 +7,6 @@ namespace opencv_test { using namespace cv::mcc; -using namespace cv::ccm; using namespace perf; } diff --git a/modules/mcc/samples/color_correction_model.cpp b/modules/mcc/samples/color_correction_model.cpp deleted file mode 100644 index 20df704370e..00000000000 --- a/modules/mcc/samples/color_correction_model.cpp +++ /dev/null @@ -1,158 +0,0 @@ -//! [tutorial] -#include - -#include -#include -#include -#include - -using namespace std; -using namespace cv; -using namespace mcc; -using namespace ccm; -using namespace std; - -const char *about = "Basic chart detection"; -const char *keys = - "{ help h | | show this message }" - "{t | | chartType: 0-Standard, 1-DigitalSG, 2-Vinyl }" - "{v | | Input from video file, if ommited, input comes from camera }" - "{ci | 0 | Camera id if input doesnt come from video (-v) }" - "{f | 1 | Path of the file to process (-v) }" - "{nc | 1 | Maximum number of charts in the image }"; - -int main(int argc, char *argv[]) -{ - - - // ---------------------------------------------------------- - // Scroll down a bit (~40 lines) to find actual relevant code - // ---------------------------------------------------------- - //! [get_messages_of_image] - CommandLineParser parser(argc, argv, keys); - parser.about(about); - if (argc==1 || parser.has("help")) - { - parser.printMessage(); - return 0; - } - - int t = parser.get("t"); - int nc = parser.get("nc"); - string filepath = parser.get("f"); - - CV_Assert(0 <= t && t <= 2); - TYPECHART chartType = TYPECHART(t); - - - if (!parser.check()) - { - parser.printErrors(); - return 0; - } - - Mat image = imread(filepath, IMREAD_COLOR); - if (!image.data) - { - cout << "Invalid Image!" << endl; - return 1; - } - //! [get_messages_of_image] - - Mat imageCopy = image.clone(); - Ptr detector = CCheckerDetector::create(); - // Marker type to detect - if (!detector->process(image, chartType, nc)) - { - printf("ChartColor not detected \n"); - return 2; - } - //! [get_color_checker] - vector> checkers = detector->getListColorChecker(); - //! [get_color_checker] - for (Ptr checker : checkers) - { - //! [create] - Ptr cdraw = CCheckerDraw::create(checker); - cdraw->draw(image); - Mat chartsRGB = checker->getChartsRGB(); - Mat src = chartsRGB.col(1).clone().reshape(3, chartsRGB.rows/3); - src /= 255.0; - //! [create] - - //compte color correction matrix - //! [get_ccm_Matrix] - ColorCorrectionModel model1(src, COLORCHECKER_Vinyl); - model1.run(); - Mat ccm = model1.getCCM(); - std::cout<<"ccm "<(18, 1) << - // Vec3d(100, 0.00520000001, -0.0104), - // Vec3d(73.0833969, -0.819999993, -2.02099991), - // Vec3d(62.493, 0.425999999, -2.23099995), - // Vec3d(50.4640007, 0.446999997, -2.32399988), - // Vec3d(37.7970009, 0.0359999985, -1.29700005), - // Vec3d(0, 0, 0), - // Vec3d(51.5880013, 73.5179977, 51.5690002), - // Vec3d(93.6989975, -15.7340002, 91.9420013), - // Vec3d(69.4079971, -46.5940018, 50.4869995), - // Vec3d(66.61000060000001, -13.6789999, -43.1720009), - // Vec3d(11.7110004, 16.9799995, -37.1759987), - // Vec3d(51.973999, 81.9440002, -8.40699959), - // Vec3d(40.5489998, 50.4399986, 24.8490009), - // Vec3d(60.8160019, 26.0690002, 49.4420013), - // Vec3d(52.2529984, -19.9500008, -23.9960003), - // Vec3d(51.2859993, 48.4700012, -15.0579996), - // Vec3d(68.70700069999999, 12.2959995, 16.2129993), - // Vec3d(63.6839981, 10.2930002, 16.7639999)); - - // ColorCorrectionModel model8(src,ref,COLOR_SPACE_Lab_D50_2); - // model8.run(); - //! [reference_color_values] - - //! [make_color_correction] - Mat img_; - cvtColor(image, img_, COLOR_BGR2RGB); - img_.convertTo(img_, CV_64F); - const int inp_size = 255; - const int out_size = 255; - img_ = img_ / inp_size; - Mat calibratedImage= model1.infer(img_); - Mat out_ = calibratedImage * out_size; - //! [make_color_correction] - - //! [Save_calibrated_image] - // Save the calibrated image to {FILE_NAME}.calibrated.{FILE_EXT} - out_.convertTo(out_, CV_8UC3); - Mat img_out = min(max(out_, 0), out_size); - Mat out_img; - cvtColor(img_out, out_img, COLOR_RGB2BGR); - string filename = filepath.substr(filepath.find_last_of('/')+1); - size_t dotIndex = filename.find_last_of('.'); - string baseName = filename.substr(0, dotIndex); - string ext = filename.substr(dotIndex+1, filename.length()-dotIndex); - string calibratedFilePath = baseName + ".calibrated." + ext; - imwrite(calibratedFilePath, out_img); - //! [Save_calibrated_image] - - } - - return 0; -} -//! [tutorial] \ No newline at end of file diff --git a/modules/mcc/test/test_mcc.cpp b/modules/mcc/test/test_mcc.cpp index 37bd1f11fc7..1e4a425e683 100644 --- a/modules/mcc/test/test_mcc.cpp +++ b/modules/mcc/test/test_mcc.cpp @@ -117,67 +117,5 @@ TEST(CV_mcc_ccm_test, detect_Macbeth) EXPECT_MAT_NEAR(goldChartsRGB.col(1), chartsRGB.col(1), 0.3); // diff 0.292077 on Ubuntu 20.04 ARM64 } -TEST(CV_mcc_ccm_test, compute_ccm) -{ - // read gold chartsRGB - string path = cvtest::findDataFile("mcc/mcc_ccm_test.yml"); - FileStorage fs(path, FileStorage::READ); - Mat chartsRGB; - FileNode node = fs["chartsRGB"]; - node >> chartsRGB; - - // compute CCM - ColorCorrectionModel model(chartsRGB.col(1).clone().reshape(3, chartsRGB.rows/3) / 255., COLORCHECKER_Macbeth); - model.run(); - - // read gold CCM - node = fs["ccm"]; - ASSERT_FALSE(node.empty()); - Mat gold_ccm; - node >> gold_ccm; - fs.release(); - - // check CCM - Mat ccm = model.getCCM(); - EXPECT_MAT_NEAR(gold_ccm, ccm, 1e-8); - - const double gold_loss = 4.6386569120323129; - // check loss - const double loss = model.getLoss(); - EXPECT_NEAR(gold_loss, loss, 1e-8); -} - -TEST(CV_mcc_ccm_test, infer) -{ - string path = cvtest::findDataFile("mcc/mcc_ccm_test.jpg"); - Mat img = imread(path, IMREAD_COLOR); - // read gold calibrate img - path = cvtest::findDataFile("mcc/mcc_ccm_test_res.png"); - Mat gold_img = imread(path); - - // read gold chartsRGB - path = cvtest::findDataFile("mcc/mcc_ccm_test.yml"); - FileStorage fs(path, FileStorage::READ); - Mat chartsRGB; - FileNode node = fs["chartsRGB"]; - node >> chartsRGB; - fs.release(); - - // compute CCM - ColorCorrectionModel model(chartsRGB.col(1).clone().reshape(3, chartsRGB.rows/3) / 255., COLORCHECKER_Macbeth); - model.run(); - - // compute calibrate image - Mat calibratedImage; - cvtColor(img, calibratedImage, COLOR_BGR2RGB); - calibratedImage.convertTo(calibratedImage, CV_64F, 1. / 255.); - calibratedImage = model.infer(calibratedImage); - calibratedImage.convertTo(calibratedImage, CV_8UC3, 255.); - cvtColor(calibratedImage, calibratedImage, COLOR_RGB2BGR); - // check calibrated image - EXPECT_MAT_NEAR(gold_img, calibratedImage, 0.1); -} - - } // namespace } // namespace opencv_test diff --git a/modules/mcc/test/test_precomp.hpp b/modules/mcc/test/test_precomp.hpp index c4d81a348c5..20722f60844 100644 --- a/modules/mcc/test/test_precomp.hpp +++ b/modules/mcc/test/test_precomp.hpp @@ -8,12 +8,10 @@ #include "opencv2/ts.hpp" #include "opencv2/ts/cuda_test.hpp" #include "opencv2/mcc.hpp" -#include "opencv2/mcc/ccm.hpp" namespace opencv_test { using namespace cv::mcc; -using namespace cv::ccm; } #endif