将 OGRE::Image 转换为 cv::Mat
Convert OGRE::Image to cv::Mat
我是 OGRE library 的新手。我在 OGRE 中有一个人体模型,我在 'orginalImage' 变量中得到模型的投影。我想使用 openCV 执行一些图像处理。所以我试图实现 OGRE::Image 到 cv::Mat 的转换。
Ogre::Image orginalImage = get2dProjection();
//This is an attempt to convert the image
cv::Mat destinationImage(orginalImage.getHeight(), orginalImage.getWidth(), CV_8UC3, orginalImage.getData());
imwrite("out.png", destinationImage);
我收到以下错误:
realloc(): invalid pointer: 0x00007f9e2ca13840 ***
在类似的说明中,我尝试了以下作为我的第二次尝试
cv::Mat cvtImgOGRE2MAT(Ogre::Image imgIn) {
//Result image intialisation:
int imgHeight = imgIn.getHeight();
int imgWidth = imgIn.getWidth();
cv::Mat imgOut(imgHeight, imgWidth, CV_32FC1);
Ogre::ColourValue color;
float gray;
cout << "Converting " << endl;
for(int r = 0; r < imgHeight; r++){
for(int c = 0; c < imgWidth; c++){
color = imgIn.getColourAt(r,c,0);
gray = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
imgOut.at<float>(r,c) = gray;
}
}
return imgOut;
}
当我执行以下操作之一时出现相同的错误:
imshow("asdfasd", imgOut);
imwrite("asdfasd.png", imgOut);
不幸的是,我没有使用 OGRE 的经验,所以我只能谈谈 OpenCV 以及我在 Ogre 文档和发帖者评论中看到的内容。
首先要提到的是 Ogre 图像'PixelFormat is PF_BYTE_RGBA
(来自评论)(根据 OGRE 文档)是一种 4 字节像素格式,因此 cv::Mat 类型应该是 CV_8UC4
如果图像数据应该由指针给出。此外,openCV 最好支持 BGR 图像,因此颜色转换可能最好 save/display.
请尝试:
Ogre::Image orginalImage = get2dProjection();
//This is an attempt to convert the image
cv::Mat destinationImage(orginalImage.getHeight(), orginalImage.getWidth(), CV_8UC4, orginalImage.getData());
cv::Mat resultBGR;
cv::cvtColor(destinationImage, resultBGR, CV_RGBA2BGR);
imwrite("out.png", resultBGR);
在你的第二个例子中,我想知道那里出了什么问题,直到我看到 color = imgIn.getColourAt(r,c,0);
这可能是错误的,因为大多数图像 API 使用 .getPixel(x,y)
所以我确认这对 OGRE 来说是一样的。请试试这个:
cv::Mat cvtImgOGRE2MAT(Ogre::Image imgIn)
{
//Result image intialisation:
int imgHeight = imgIn.getHeight();
int imgWidth = imgIn.getWidth();
cv::Mat imgOut(imgHeight, imgWidth, CV_32FC1);
Ogre::ColourValue color;
float gray;
cout << "Converting " << endl;
for(int r = 0; r < imgHeight; r++)
{
for(int c = 0; c < imgWidth; c++)
{
// next line was changed
color = imgIn.getColourAt(c,r,0);
gray = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
// this access is right
imgOut.at<float>(r,c) = gray;
}
}
return imgOut;
// depending of what you want to do with the image, "float" Mat type assumes what image intensity values are within 0..1 (displaying) or 0..255 (imwrite)
}
如果您仍然遇到 realloc 错误,能否请您尝试找到它发生的确切代码行?
我还没有考虑的一件事是OGRE图像的真实内存布局。他们可能使用某种对齐的内存,其中每个像素行对齐到内存大小为 4 或 16 或 sth 的倍数。 (这可能更有效,例如使用 SSE 指令或某事。)如果是这种情况,您不能使用第一种方法,但您必须将其更改为 cv::Mat destinationImage(orginalImage.getHeight(), orginalImage.getWidth(), CV_8UC4, orginalImage.getData(), STEPSIZE);
,其中 STEPSIZE
是每个像素行的字节数!但是第二个版本应该可以了!
我是 OGRE library 的新手。我在 OGRE 中有一个人体模型,我在 'orginalImage' 变量中得到模型的投影。我想使用 openCV 执行一些图像处理。所以我试图实现 OGRE::Image 到 cv::Mat 的转换。
Ogre::Image orginalImage = get2dProjection();
//This is an attempt to convert the image
cv::Mat destinationImage(orginalImage.getHeight(), orginalImage.getWidth(), CV_8UC3, orginalImage.getData());
imwrite("out.png", destinationImage);
我收到以下错误:
realloc(): invalid pointer: 0x00007f9e2ca13840 ***
在类似的说明中,我尝试了以下作为我的第二次尝试
cv::Mat cvtImgOGRE2MAT(Ogre::Image imgIn) {
//Result image intialisation:
int imgHeight = imgIn.getHeight();
int imgWidth = imgIn.getWidth();
cv::Mat imgOut(imgHeight, imgWidth, CV_32FC1);
Ogre::ColourValue color;
float gray;
cout << "Converting " << endl;
for(int r = 0; r < imgHeight; r++){
for(int c = 0; c < imgWidth; c++){
color = imgIn.getColourAt(r,c,0);
gray = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
imgOut.at<float>(r,c) = gray;
}
}
return imgOut;
}
当我执行以下操作之一时出现相同的错误:
imshow("asdfasd", imgOut);
imwrite("asdfasd.png", imgOut);
不幸的是,我没有使用 OGRE 的经验,所以我只能谈谈 OpenCV 以及我在 Ogre 文档和发帖者评论中看到的内容。
首先要提到的是 Ogre 图像'PixelFormat is PF_BYTE_RGBA
(来自评论)(根据 OGRE 文档)是一种 4 字节像素格式,因此 cv::Mat 类型应该是 CV_8UC4
如果图像数据应该由指针给出。此外,openCV 最好支持 BGR 图像,因此颜色转换可能最好 save/display.
请尝试:
Ogre::Image orginalImage = get2dProjection();
//This is an attempt to convert the image
cv::Mat destinationImage(orginalImage.getHeight(), orginalImage.getWidth(), CV_8UC4, orginalImage.getData());
cv::Mat resultBGR;
cv::cvtColor(destinationImage, resultBGR, CV_RGBA2BGR);
imwrite("out.png", resultBGR);
在你的第二个例子中,我想知道那里出了什么问题,直到我看到 color = imgIn.getColourAt(r,c,0);
这可能是错误的,因为大多数图像 API 使用 .getPixel(x,y)
所以我确认这对 OGRE 来说是一样的。请试试这个:
cv::Mat cvtImgOGRE2MAT(Ogre::Image imgIn)
{
//Result image intialisation:
int imgHeight = imgIn.getHeight();
int imgWidth = imgIn.getWidth();
cv::Mat imgOut(imgHeight, imgWidth, CV_32FC1);
Ogre::ColourValue color;
float gray;
cout << "Converting " << endl;
for(int r = 0; r < imgHeight; r++)
{
for(int c = 0; c < imgWidth; c++)
{
// next line was changed
color = imgIn.getColourAt(c,r,0);
gray = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
// this access is right
imgOut.at<float>(r,c) = gray;
}
}
return imgOut;
// depending of what you want to do with the image, "float" Mat type assumes what image intensity values are within 0..1 (displaying) or 0..255 (imwrite)
}
如果您仍然遇到 realloc 错误,能否请您尝试找到它发生的确切代码行?
我还没有考虑的一件事是OGRE图像的真实内存布局。他们可能使用某种对齐的内存,其中每个像素行对齐到内存大小为 4 或 16 或 sth 的倍数。 (这可能更有效,例如使用 SSE 指令或某事。)如果是这种情况,您不能使用第一种方法,但您必须将其更改为 cv::Mat destinationImage(orginalImage.getHeight(), orginalImage.getWidth(), CV_8UC4, orginalImage.getData(), STEPSIZE);
,其中 STEPSIZE
是每个像素行的字节数!但是第二个版本应该可以了!