Не могу использовать Emgu Mat.CopyTo для записи в подматрицу - PullRequest
0 голосов
/ 25 февраля 2020

У меня никогда не было проблем с этим в C ++ при написании с OpenCV, но я признаю, что я не пробовал это точно, поэтому я могу упустить что-то очевидное или это может быть связано с Эмгу.

Я пытаюсь записать матрицу в субмат, используя мат. Метод CopyTo, но, кажется, всегда создает новую Матрицу. Вот рабочий пример:

    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);
    }

В результате я получаю маркер ArUco в marker и marker8U, marker8U копируется в раздел, но при этом раздел получает новый заголовок Mat и больше не является субмат в fullImage. FullImage получает синий прямоугольник в углу.

Я пытаюсь скопировать содержимое матрицы с маркером ArUco в раздел fullImage.

Любая помощь будет принята!

1 Ответ

0 голосов
/ 26 февраля 2020

К сожалению. Как это часто бывает, проблема была не там, где я думал. Проблема была с преобразованием:

    // 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 изменяет только глубину, а не количество каналов. Вместо репликации одного канала на 3 канала в marker8u он просто создал новый Mat с 1 каналом - по сути, ничего не делая.

Исправление было просто; замените вызов на ConvertTo на вызов на CvtColor следующим образом:

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

Это просто реплицирует канал на три канала, и на этот раз вызов на CopyTo работал, потому что каналы и глубина соответствует.

...