不能使用 Emgu Mat.CopyTo 写入子矩阵

Can't use Emgu Mat.CopyTo to write into a submatrix

在使用 OpenCV 编写时,我在 C++ 中从未遇到过这个问题,但我承认我没有完全尝试过,所以我可能遗漏了一些明显的东西,或者它可能与 Emgu 相关。

我正在尝试使用 Mat 将矩阵写入子垫。 CopyTo 方法,但它似乎总是创建一个新的 Matrix。这是一个工作示例:

    public static void ExampleOne()
    {
        // Create the full image
        Mat fullImage = new Mat(100, 100, DepthType.Cv8U, 3);
        fullImage.SetTo(new Bgr(255, 255, 255).MCvScalar);

        // Create an ArUco marker
        Mat marker = new Mat(40, 40, DepthType.Cv8U, 3);
        Dictionary arucoDictionary = new Dictionary(Dictionary.PredefinedDictionaryName.Dict6X6_250);
        ArucoInvoke.DrawMarker(arucoDictionary, 1, 20, marker);

        // Create a section of the full image for the ArUco Marker to sit in
        Mat section = new Mat(fullImage, new Rectangle(new Point(0, 0), marker.Size));
        section.SetTo(new Bgr(255, 0, 0).MCvScalar); // Set to blue for testing

        // Debug stuff
        bool sectionIsSubMatrix1 = section.IsSubmatrix;
        IntPtr sectionDataPointer1 = section.DataPointer;

        // Convert the ArUco marker to the same depth and channels as the original
        Mat marker8U = new Mat(marker.Size, section.Depth, section.NumberOfChannels);
        marker.ConvertTo(marker8U, marker8U.Depth);

        // Copy the marker into the section
        marker8U.CopyTo(section);

        // Debug stuff
        bool sectionIsSubMatrix2 = section.IsSubmatrix;
        IntPtr sectionDataPointer2 = section.DataPointer;

        Debug.WriteLine("Section 1 {0} 0x{1:X}", sectionIsSubMatrix1, (long)sectionDataPointer1);
        Debug.WriteLine("Section 2 {0} 0x{1:X}", sectionIsSubMatrix2, (long)sectionDataPointer2);
    }

结果是我在marker和marker8U中得到一个ArUco marker,marker8U被复制到setion,但是这样做section得到了一个新的Mat header,不再是fullImage中的submat。 fullImage 在角落里有一个蓝色框。

我正在尝试将带有 ArUco 标记的矩阵的内容复制到 fullImage 的部分。

如有任何帮助,我们将不胜感激!

糟糕。通常情况下,问题不在我认为的地方。问题在于转换:

    // Convert the ArUco marker to the same depth and channels as the original
    Mat marker8U = new Mat(marker.Size, section.Depth, section.NumberOfChannels);
    marker.ConvertTo(marker8U, marker8U.Depth);

在此,marker8u创建了3个通道,marker创建了1个通道;但是 ConvertTo 只会改变深度,不会改变通道数。它没有在 marker8u 中的 3 个通道中复制单个通道,而是简单地用 1 个通道创建了一个新的 Mat - 基本上什么都不做。

修复很简单;将对 ConvertTo 的调用替换为对 CvtColor 的调用,如下所示:

    CvInvoke.CvtColor(marker, marker8U, ColorConversion.Gray2Bgr);

这只是跨三个通道复制了通道,这一次,对 CopyTo 的调用成功了,因为通道和深度匹配。