不能使用 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
的调用成功了,因为通道和深度匹配。
在使用 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
的调用成功了,因为通道和深度匹配。