我正在尝试将一组 iplimage 从 OpenCV 传递给另一个不使用 iplimage 但使用字节 [] 列表而不是通过 c++/cli 的程序(.net)。知道如何将 iplimage 添加/转换到 byte[] 列表吗?
谢谢。
如果要从 iplimage.imageData 复制精确的像素,可以使用Marshal.Copy
将数据从IntPtr
(imageData) 复制到托管数组 (byte[])。
但由于 imageData 未压缩,您可能希望使用imencode
或将其压缩到中间缓冲区,然后使用上述代码cvEncodeImage
将其复制到 a中。byte[]
在做任何其他事情之前,花点时间了解anIplImage
是如何创建的,以及它存储了什么样的信息。
然后,注意图像的像素可以通过成员 访问imageData
,这是一个unsigned char*
:
IplImage* image = cvLoadImage("starwars.jpg", 0);
int img_sz = image->width * image->height * image->nChannels;
unsigned char* data = (unsigned char*) malloc(img_sz);
memcopy(data, image->imageData, img_sz);
您必须执行类似的过程才能将其转换为byte[]
. 顺便说一句,这篇文章] 2展示了(除其他外)如何将 an 转换IplImage*
为 a SDL_Surface*
。
首先,我建议您尽可能切换到 OpenCV 的 C++ API - 与旧的 C 接口相比,它提供了更多的灵活性和功能。
在 C++ 接口中,执行上述任务的代码片段是:
cv::Mat image = cv::imread(imname);
uchar *ptr = (uchar*)image.data
您可以在任何地方使用您的 ptr(一个 8 位无符号字节数据) - 请记住修改此数据将修改实际图像。如果您不希望发生这种情况,请使用 memcpy 获取数据的副本。
如果我理解正确,您可以搜索以下内容:
IplImage* image = cvLoadImage("image.bmp");
std::list<unsigned char*> bytes;
for (int i=0;i<image->height;i++)
{
bytes.push_back(image->imageData + image ->widthStep*i);
}
您可以测试它是否可以执行以下操作(我在此处访问第二行的第一个像素):
std::list<unsigned char*>::iterator it = bytes.begin();
it++;
*(*it) = 22;
int a = *((unsigned char*)(image->imageData + image->widthStep*1));
我没有找到用新的 cv::Mat 对象做这样的事情的方法。您可以将图像转换为 std::vectors,但无法将图像转换为一行 std::vector/std::list。但是,如果您仍然使用 cv::Mat 类,您可以尝试该类也可以cv::Ptr<Pixelformat>
访问行指针。