nareshmlx/opencv-pr huggingface dataset:
**File:** modules/imgcodecs/test/test_animation.cpp
**Change Type:** modified
**Context:** PR #27113: Fixing imread() function 16 bit reading png problem with libspng

**Code Changes:**
```diff
@@ -676,7 +676,7 @@ TEST(Imgcodecs_APNG, imread_animation_16u)
     img = imread(filename, IMREAD_ANYDEPTH);
     ASSERT_FALSE(img.empty());
     EXPECT_TRUE(img.type() == CV_16UC1);
-    EXPECT_EQ(19519, img.at<ushort>(0, 0));
+    EXPECT_EQ(19517, img.at<ushort>(0, 0));
 
     img = imread(filename, IMREAD_COLOR | IMREAD_ANYDEPTH);
     ASSERT_FALSE(img.empty());
```

Review comment:
last commit is temporarily to show that the spng conversion code is the same as libpng. i temporarily used `if (m_frame_count > 5)` that means the difference caused by cvtColor which i used in apng decoding. ``` [ RUN ] Imgcodecs_APNG.imread_animation_16u /build/precommit_linux64/4.x/opencv/modules/imgcodecs/test/test_animation.cpp:680: Failure Expected equality of these values: 19519 img.at<ushort>(0, 0) Which is: 19517 [ FAILED ] Imgcodecs_APNG.imread_animation_16u (2 ms) ```
**File:** modules/imgcodecs/test/test_animation.cpp
**Change Type:** modified
**Context:** PR #27113: Fixing imread() function 16 bit reading png problem with libspng

**Code Changes:**
```diff
@@ -676,7 +676,7 @@ TEST(Imgcodecs_APNG, imread_animation_16u)
     img = imread(filename, IMREAD_ANYDEPTH);
     ASSERT_FALSE(img.empty());
     EXPECT_TRUE(img.type() == CV_16UC1);
-    EXPECT_EQ(19519, img.at<ushort>(0, 0));
+    EXPECT_EQ(19517, img.at<ushort>(0, 0));
 
     img = imread(filename, IMREAD_COLOR | IMREAD_ANYDEPTH);
     ASSERT_FALSE(img.empty());
```

Review comment:
If you find it appropriate, I can add a to-do note and let's merge this. I'll work on apng and try to find a solution for this difference later.
**File:** modules/imgcodecs/test/test_png.cpp
**Change Type:** modified
**Context:** PR #27113: Fixing imread() function 16 bit reading png problem with libspng
**Review Line:** 197

**Code Changes:**
```diff
+    EXPECT_PRED_FORMAT2(cvtest::MatComparator(1, 0), imread(filename, IMREAD_COLOR_RGB), gt_256);
+    EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), imread(filename, IMREAD_COLOR_RGB | IMREAD_ANYDEPTH), gt_258);
+
+// Uncomment this block to write out the decoded images for visual/manual inspection
+// or for regenerating expected ground truth PNGs (for example, after changing decoder logic).
+#if 0
+    imwrite(filename + "_0.png", imread(filename, IMREAD_GRAYSCALE));
+    imwrite(filename + "_1.png", imread(filename, IMREAD_COLOR));
+    imwrite(filename + "_2.png", imread(filename, IMREAD_ANYDEPTH));
+    imwrite(filename + "_3.png", imread(filename, IMREAD_COLOR | IMREAD_ANYDEPTH));
+    imwrite(filename + "_256.png", imread(filename, IMREAD_COLOR_RGB));
```

Review comment:
I forgot to mention that i used this commented blocks to be sure libspng and libpng loads exact same data. first i set 1 the upper block with OpenCV compiled with libpng. and for each pngsuite file saved what loaded with each flag. then set 0 the upper block and set 1 the lower block with OpenCV compiled with libspng...
**File:** modules/imgcodecs/src/grfmt_avif.cpp
**Change Type:** modified
**Context:** PR #27506: Fix XMP write and discarded return value.

**Code Changes:**
```diff
@@ -116,12 +116,27 @@ AvifImageUniquePtr ConvertToAvif(const cv::Mat &img, bool lossless, int bit_dept
     const std::vector<uchar>& metadata_exif = metadata[IMAGE_METADATA_EXIF];
     const std::vector<uchar>& metadata_xmp = metadata[IMAGE_METADATA_XMP];
     const std::vector<uchar>& metadata_iccp = metadata[IMAGE_METADATA_ICCP];
+#if AVIF_VERSION_MAJOR >= 1
+    if ((!metadata_exif.empty() &&
+         avifImageSetMetadataExif(result, (const uint8_t *)metadata_exif.data(),
+                                  metadata_exif.size()) != AVIF_RESULT_OK) ||
+        (!metadata_xmp.empty() &&
+         avifImageSetMetadataXMP(result, (const uint8_t *)metadata_xmp.data(),
```

Review comment:
Looks like a typo: metadata_xmp.data() should be used
**File:** modules/imgcodecs/src/grfmt_avif.cpp
**Change Type:** modified
**Context:** PR #27506: Fix XMP write and discarded return value.

**Code Changes:**
```diff
@@ -116,12 +116,27 @@ AvifImageUniquePtr ConvertToAvif(const cv::Mat &img, bool lossless, int bit_dept
     const std::vector<uchar>& metadata_exif = metadata[IMAGE_METADATA_EXIF];
     const std::vector<uchar>& metadata_xmp = metadata[IMAGE_METADATA_XMP];
     const std::vector<uchar>& metadata_iccp = metadata[IMAGE_METADATA_ICCP];
+#if AVIF_VERSION_MAJOR >= 1
+    if ((!metadata_exif.empty() &&
+         avifImageSetMetadataExif(result, (const uint8_t *)metadata_exif.data(),
+                                  metadata_exif.size()) != AVIF_RESULT_OK) ||
+        (!metadata_xmp.empty() &&
+         avifImageSetMetadataXMP(result, (const uint8_t *)metadata_xmp.data(),
```

Review comment:
Looks like a typo: metadata_iccp.data() should be used
**File:** modules/imgproc/src/geometry.cpp
**Change Type:** modified
**Context:** PR #26974: Issue 26972: Proper treatment of float values in intersectConvexConvex

**Code Changes:**
```diff
@@ -330,20 +330,20 @@ static LineSegmentIntersection parallelInt( Point2f a, Point2f b, Point2f c, Poi
 static LineSegmentIntersection intersectLineSegments( Point2f a, Point2f b, Point2f c,
                                                       Point2f d, Point2f& p, Point2f& q )
 {
-    double denom = (a.x - b.x) * (double)(d.y - c.y) - (a.y - b.y) * (double)(d.x - c.x);
+    double denom = ((double)a.x - b.x) * ((double)d.y - c.y) - ((double)a.y - b.y) * ((double)d.x - c.x);
 
     // If denom is zero, then segments are parallel: handle separately.
     if( denom == 0. )
         return parallelInt(a, b, c, d, p, q);
```

Review comment:
I agree that it's not correct to compare floats/doubles on equality, but why do you change the first line of conditions? I would say that the correct check is: ``` return s < 0. || s > 1. || t < 0. || t > 1. ? LS_NO_INTERSECTION : fabs(num) < eps || fabs(s-1.) < eps || fabs(t) < eps || fabs(t-1.) < eps ? LS_ENDPOINT_INTERSECTION : LS_SINGLE_INTERSECTION; ```
**File:** modules/imgproc/src/geometry.cpp
**Change Type:** modified
**Context:** PR #26974: Issue 26972: Proper treatment of float values in intersectConvexConvex

**Code Changes:**
```diff
@@ -330,20 +330,20 @@ static LineSegmentIntersection parallelInt( Point2f a, Point2f b, Point2f c, Poi
 static LineSegmentIntersection intersectLineSegments( Point2f a, Point2f b, Point2f c,
                                                       Point2f d, Point2f& p, Point2f& q )
 {
-    double denom = (a.x - b.x) * (double)(d.y - c.y) - (a.y - b.y) * (double)(d.x - c.x);
+    double denom = ((double)a.x - b.x) * ((double)d.y - c.y) - ((double)a.y - b.y) * ((double)d.x - c.x);
 
     // If denom is zero, then segments are parallel: handle separately.
     if( denom == 0. )
         return parallelInt(a, b, c, d, p, q);
```

Review comment:
The numerical error can happen on both sides, and in particular the one "outside" the line actually caused the problem that the polygon intersection was not detected (see unit test). The one on the inside is probably harmless and could be treated either way, as endpoint and single intersection are "intersections". For symmetry reasons I also updated the second check.
**File:** modules/imgproc/src/geometry.cpp
**Change Type:** modified
**Context:** PR #26974: Issue 26972: Proper treatment of float values in intersectConvexConvex

**Code Changes:**
```diff
@@ -330,20 +330,20 @@ static LineSegmentIntersection parallelInt( Point2f a, Point2f b, Point2f c, Poi
 static LineSegmentIntersection intersectLineSegments( Point2f a, Point2f b, Point2f c,
                                                       Point2f d, Point2f& p, Point2f& q )
 {
-    double denom = (a.x - b.x) * (double)(d.y - c.y) - (a.y - b.y) * (double)(d.x - c.x);
+    double denom = ((double)a.x - b.x) * ((double)d.y - c.y) - ((double)a.y - b.y) * ((double)d.x - c.x);
 
     // If denom is zero, then segments are parallel: handle separately.
     if( denom == 0. )
         return parallelInt(a, b, c, d, p, q);
```

Review comment:
With 1e-5 the unit test was still failing, so I went up to 1e-4. To keep it as small as possible, not more than that.
**File:** modules/imgcodecs/include/opencv2/imgcodecs.hpp
**Change Type:** modified
**Context:** PR #27127: Changes about when APNG has a hidden frame

**Code Changes:**
```diff
@@ -277,6 +277,8 @@ struct CV_EXPORTS_W_SIMPLE Animation
     CV_PROP_RW std::vector<int> durations;
     //! Vector of frames, where each Mat represents a single frame.
     CV_PROP_RW std::vector<Mat> frames;
+    //! image that can be used for the format in addition to the animation or if animation is not supported in the reader (like in PNG).
+    CV_PROP_RW Mat still_image;
 
     /** @brief Constructs an Animation object with optional loop count and background color.
 
```

Review comment:
Maybe: ``` //! image that can be used for the format in addition to the animation or if animation is not supported in the reader (like in PNG). CV_PROP_RW cv::Mat still_image; ```
**File:** modules/imgcodecs/src/grfmt_png.cpp
**Change Type:** modified
**Context:** PR #27127: Changes about when APNG has a hidden frame
**Review Line:** 1653

**Code Changes:**
```diff
+            APNGFrame apngFrame;
+            Mat tmp;
+            if (animation.still_image.depth() == CV_16U)
+            {
+                animation.still_image.convertTo(tmp, CV_8U, 1.0 / 255);
+            }
+            else
+                tmp = animation.still_image;
+
+            cvtColor(tmp, tmp, COLOR_BGRA2RGBA);
+            apngFrame.setMat(tmp);
```

Review comment:
Most probably the conversion is not needed, if the animation patch in 16-bit too.
**File:** modules/imgcodecs/test/test_animation.cpp
**Change Type:** modified
**Context:** PR #27127: Changes about when APNG has a hidden frame

**Code Changes:**
```diff
@@ -636,6 +636,51 @@ TEST(Imgcodecs_APNG, imencode_animation)
     }
 }
 
+TEST(Imgcodecs_APNG, animation_has_hidden_frame)
+{
+    // Set the path to the test image directory and filename for loading.
+    const string root = cvtest::TS::ptr()->get_data_path();
+    const string filename = root + "readwrite/033.png";
+    Animation animation1, animation2, animation3;
```

Review comment:
Was it alpha blending overflow issue?
**File:** modules/imgcodecs/src/grfmt_png.cpp
**Change Type:** modified
**Context:** PR #27127: Changes about when APNG has a hidden frame
**Review Line:** 1653

**Code Changes:**
```diff
+            APNGFrame apngFrame;
+            Mat tmp;
+            if (animation.still_image.depth() == CV_16U)
+            {
+                animation.still_image.convertTo(tmp, CV_8U, 1.0 / 255);
+            }
+            else
+                tmp = animation.still_image;
+
+            cvtColor(tmp, tmp, COLOR_BGRA2RGBA);
+            apngFrame.setMat(tmp);
```

Review comment:
currently APNG encoder converts 16U Mats to 8U before saving. no support for writing 16 bit APNG yet.
**File:** modules/imgcodecs/test/test_animation.cpp
**Change Type:** modified
**Context:** PR #27127: Changes about when APNG has a hidden frame

**Code Changes:**
```diff
@@ -636,6 +636,51 @@ TEST(Imgcodecs_APNG, imencode_animation)
     }
 }
 
+TEST(Imgcodecs_APNG, animation_has_hidden_frame)
+{
+    // Set the path to the test image directory and filename for loading.
+    const string root = cvtest::TS::ptr()->get_data_path();
+    const string filename = root + "readwrite/033.png";
+    Animation animation1, animation2, animation3;
```

Review comment:
the old values was for the first frame before. now the first frame is `still_image `in the test file.
**File:** modules/imgcodecs/test/test_animation.cpp
**Change Type:** modified
**Context:** PR #27127: Changes about when APNG has a hidden frame

**Code Changes:**
```diff
@@ -636,6 +636,51 @@ TEST(Imgcodecs_APNG, imencode_animation)
     }
 }
 
+TEST(Imgcodecs_APNG, animation_has_hidden_frame)
+{
+    // Set the path to the test image directory and filename for loading.
+    const string root = cvtest::TS::ptr()->get_data_path();
+    const string filename = root + "readwrite/033.png";
+    Animation animation1, animation2, animation3;
```

Review comment:
the test was comparing correct values before. and comparing correct values now.
**File:** modules/imgcodecs/src/grfmt_png.cpp
**Change Type:** modified
**Context:** PR #27127: Changes about when APNG has a hidden frame

**Code Changes:**
```diff
@@ -156,7 +156,7 @@ bool APNGFrame::setMat(const cv::Mat& src, unsigned delayNum, unsigned delayDen)
 
     if (!src.empty())
     {
-        png_uint_32 rowbytes = src.depth() == CV_16U ? src.cols * src.channels() * 2 : src.cols * src.channels();
+        png_uint_32 rowbytes = src.cols * (uint32_t)src.elemSize();
         _width = src.cols;
         _height = src.rows;
         _colorType = src.channels() == 1 ? PNG_COLOR_TYPE_GRAY : src.channels() == 3 ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA;
@@ -416,14 +416,17 @@ bool  PngDecoder::readData( Mat& img )
```

Review comment:
The line changes simple imread behavior, right? I propose to return still image in case if user reads animation as single frame. It's APNG design decision and also presumes current OpenCV behaviour.
**File:** modules/imgcodecs/src/grfmt_png.cpp
**Change Type:** modified
**Context:** PR #27127: Changes about when APNG has a hidden frame
**Review Line:** 436

**Code Changes:**
```diff
-                m_buf_pos -= 8;
         }
         else
             m_mat_next.copyTo(mat_cur);
@@ -433,9 +436,6 @@ bool  PngDecoder::readData( Mat& img )
         if (!processing_start((void*)&frameRaw, mat_cur))
             return false;
 
-        if(setjmp(png_jmpbuf(m_png_ptr)))
-            return false;
-
```

Review comment:
i think we can delete this line which called in `processing_start()` ``` bool PngDecoder::processing_start(void* frame_ptr, const Mat& img) { if (!InitPngPtr()) return false; if (setjmp(png_jmpbuf(m_png_ptr))) return false; . . . } ```
**File:** modules/imgcodecs/src/grfmt_png.cpp
**Change Type:** modified
**Context:** PR #27127: Changes about when APNG has a hidden frame
**Review Line:** 1653

**Code Changes:**
```diff
+            APNGFrame apngFrame;
+            Mat tmp;
+            if (animation.still_image.depth() == CV_16U)
+            {
+                animation.still_image.convertTo(tmp, CV_8U, 1.0 / 255);
+            }
+            else
+                tmp = animation.still_image;
+
+            cvtColor(tmp, tmp, COLOR_BGRA2RGBA);
+            apngFrame.setMat(tmp);
```

Review comment:
Added issue to our tracker to make the limitation more obvious.
**File:** modules/imgproc/src/phasecorr.cpp
**Change Type:** modified
**Context:** PR #27368: imgproc: vectorize cv::createHanningWindow

**Code Changes:**
```diff
@@ -38,6 +38,7 @@
 
 #include "precomp.hpp"
 #include <vector>
+#include "opencv2/core/hal/intrin.hpp"
 
 namespace cv
 {
@@ -614,16 +615,45 @@ void cv::createHanningWindow(OutputArray _dst, cv::Size winSize, int type)
     double* const wc = _wc.data();
```

Review comment:
What if drop the condition and just use scalar tail for it? IMHO it should fix small performance degradation on arm.
**File:** samples/dnn/deblurring.cpp
**Change Type:** added
**Context:** PR #27349: Added DNN based deblurring samples

**Code Changes:**
```diff
@@ -0,0 +1,136 @@
+/*
+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.
+
+This sample deblurs the given blurry image.
+
+Copyright (C) 2025, Bigvision LLC.
+
```

Review comment:
You can get rid of the conversion, if merge channels in proper order.
**File:** samples/dnn/deblurring.cpp
**Change Type:** added
**Context:** PR #27349: Added DNN based deblurring samples

**Code Changes:**
```diff
@@ -0,0 +1,136 @@
+/*
+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.
+
+This sample deblurs the given blurry image.
+
+Copyright (C) 2025, Bigvision LLC.
+
```

Review comment:
``` vector<Mat> channels = { Mat(output_transposed.size[1], output_transposed.size[2], CV_32F, output_transposed.ptr<float>(0)), Mat(output_transposed.size[1], output_transposed.size[2], CV_32F, output_transposed.ptr<float>(1)), Mat(output_transposed.size[1], output_transposed.size[2], CV_32F, output_transposed.ptr<float>(2)) }; ```
**File:** modules/imgcodecs/src/grfmt_webp.cpp
**Change Type:** modified
**Context:** PR #27457: fix for the issue #27456

**Code Changes:**
```diff
@@ -155,14 +155,16 @@ bool WebPDecoder::readHeader()
         webp_data.size = data.total();
 
         WebPAnimDecoderOptions dec_options;
-        WebPAnimDecoderOptionsInit(&dec_options);
+        if (!WebPAnimDecoderOptionsInit(&dec_options))
+            CV_Error(Error::StsInternal, "Failed to initialize animated WebP decoding options");
 
         dec_options.color_mode = m_use_rgb ? MODE_RGBA : MODE_BGRA;
         anim_decoder.reset(WebPAnimDecoderNew(&webp_data, &dec_options));
```

Review comment:
That encode is actually useless right?
**File:** modules/photo/src/ccm/color.cpp
**Change Type:** added
**Context:** PR #27051: Adding color correction module to photo module from opencv_contrib

**Code Changes:**
```diff
@@ -0,0 +1,391 @@
+// 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.
+//
+// Author: Longbu Wang <wanglongbu@huawei.com.com>
+//         Jinheng Zhang <zhangjinheng1@huawei.com>
+//         Chenqi Shan <shanchenqi@huawei.com>
+
+#include "color.hpp"
```

Review comment:
Modern copyright header
**File:** modules/photo/src/ccm/distance.hpp
**Change Type:** added
**Context:** PR #27051: Adding color correction module to photo module from opencv_contrib

**Code Changes:**
```diff
@@ -0,0 +1,80 @@
+// 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.
+//
+// Author: Longbu Wang <wanglongbu@huawei.com.com>
+//         Jinheng Zhang <zhangjinheng1@huawei.com>
+//         Chenqi Shan <shanchenqi@huawei.com>
+
+#ifndef __OPENCV_CCM_DISTANCE_HPP__
```

Review comment:
Should we move it to public API?
**File:** modules/photo/include/opencv2/photo/ccm.hpp
**Change Type:** added
**Context:** PR #27051: Adding color correction module to photo module from opencv_contrib

**Code Changes:**
```diff
@@ -0,0 +1,322 @@
+// 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.
+//
+// Author: Longbu Wang <wanglongbu@huawei.com.com>
+//         Jinheng Zhang <zhangjinheng1@huawei.com>
+//         Chenqi Shan <shanchenqi@huawei.com>
+
+#ifndef OPENCV_PHOTO_CCM_HPP
```

Review comment:
use ColorSpace
**File:** modules/photo/include/opencv2/photo/ccm.hpp
**Change Type:** added
**Context:** PR #27051: Adding color correction module to photo module from opencv_contrib

**Code Changes:**
```diff
@@ -0,0 +1,322 @@
+// 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.
+//
+// Author: Longbu Wang <wanglongbu@huawei.com.com>
+//         Jinheng Zhang <zhangjinheng1@huawei.com>
+//         Chenqi Shan <shanchenqi@huawei.com>
+
+#ifndef OPENCV_PHOTO_CCM_HPP
```

Review comment:
use LinearizationType
**File:** modules/photo/include/opencv2/photo/ccm.hpp
**Change Type:** added
**Context:** PR #27051: Adding color correction module to photo module from opencv_contrib

**Code Changes:**
```diff
@@ -0,0 +1,322 @@
+// 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.
+//
+// Author: Longbu Wang <wanglongbu@huawei.com.com>
+//         Jinheng Zhang <zhangjinheng1@huawei.com>
+//         Chenqi Shan <shanchenqi@huawei.com>
+
+#ifndef OPENCV_PHOTO_CCM_HPP
```

Review comment:
setLinearization
**File:** modules/photo/include/opencv2/photo/ccm.hpp
**Change Type:** added
**Context:** PR #27051: Adding color correction module to photo module from opencv_contrib

**Code Changes:**
```diff
@@ -0,0 +1,322 @@
+// 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.
+//
+// Author: Longbu Wang <wanglongbu@huawei.com.com>
+//         Jinheng Zhang <zhangjinheng1@huawei.com>
+//         Chenqi Shan <shanchenqi@huawei.com>
+
+#ifndef OPENCV_PHOTO_CCM_HPP
```

Review comment:
please rename it to computeColorCorrectionMatrix() to avoid confusion with another "ccm" - "color correction model", make it return matrix: ``` CV_WRAP Mat compute(); ```
**File:** modules/photo/include/opencv2/photo/ccm.hpp
**Change Type:** added
**Context:** PR #27051: Adding color correction module to photo module from opencv_contrib

**Code Changes:**
```diff
@@ -0,0 +1,322 @@
+// 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.
+//
+// Author: Longbu Wang <wanglongbu@huawei.com.com>
+//         Jinheng Zhang <zhangjinheng1@huawei.com>
+//         Chenqi Shan <shanchenqi@huawei.com>
+
+#ifndef OPENCV_PHOTO_CCM_HPP
```

Review comment:
rename to `CV_WRAP Mat getColorCorrectionMatrix() const;`
**File:** modules/photo/include/opencv2/photo/ccm.hpp
**Change Type:** added
**Context:** PR #27051: Adding color correction module to photo module from opencv_contrib

**Code Changes:**
```diff
@@ -0,0 +1,322 @@
+// 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.
+//
+// Author: Longbu Wang <wanglongbu@huawei.com.com>
+//         Jinheng Zhang <zhangjinheng1@huawei.com>
+//         Chenqi Shan <shanchenqi@huawei.com>
+
+#ifndef OPENCV_PHOTO_CCM_HPP
```

Review comment:
probably rename to ``` CV_WRAP void correctImage(InputArray src, OutputArray dst, bool islinear = false); ```
**File:** modules/photo/include/opencv2/photo/ccm.hpp
**Change Type:** added
**Context:** PR #27051: Adding color correction module to photo module from opencv_contrib

**Code Changes:**
```diff
@@ -0,0 +1,322 @@
+// 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.
+//
+// Author: Longbu Wang <wanglongbu@huawei.com.com>
+//         Jinheng Zhang <zhangjinheng1@huawei.com>
+//         Chenqi Shan <shanchenqi@huawei.com>
+
+#ifndef OPENCV_PHOTO_CCM_HPP
```

Review comment:
==> `CV_WRAP ColorCorrectionModel(const Mat& src, const Mat& colors, COLOR_SPACE ref_cs, const Mat& colored);`
**File:** modules/photo/include/opencv2/photo/ccm.hpp
**Change Type:** added
**Context:** PR #27051: Adding color correction module to photo module from opencv_contrib

**Code Changes:**
```diff
@@ -0,0 +1,322 @@
+// 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.
+//
+// Author: Longbu Wang <wanglongbu@huawei.com.com>
+//         Jinheng Zhang <zhangjinheng1@huawei.com>
+//         Chenqi Shan <shanchenqi@huawei.com>
+
+#ifndef OPENCV_PHOTO_CCM_HPP
```

Review comment:
==> `CV_WRAP ColorCorrectionModel(const Mat& src, const Mat& colors, COLOR_SPACE ref_cs);`