Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for bayer images to Ogre and Ogre2 #838

8 changes: 4 additions & 4 deletions include/gz/rendering/PixelFormat.hh
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ namespace gz
PF_BAYER_RGGB8 = 4,
/// < Bayer BGGR, 1-byte per channel
PF_BAYER_BGGR8 = 5,
/// < Bayer GBGR, 1-byte per channel
PF_BAYER_GBGR8 = 6,
/// < Bayer GRGB, 1-byte per channel
PF_BAYER_GRGB8 = 7,
/// < Bayer GBRG, 1-byte per channel
PF_BAYER_GBRG8 = 6,
/// < Bayer GRBG, 1-byte per channel
PF_BAYER_GRBG8 = 7,
Comment on lines -46 to +49
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @iche033, I have made the changes to the enum elements corresponding to bayer formats so that they are consistent with gazebo-classic. As you suggested, we could now review the outcomes of the ABI build.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update: The ABI compatibility failed :(

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes but looking closely at the report, the compatibility is 100%. It did catch the behavior change, which I'm leaning towards letting it slide since Bayer format was not working before.

// Float32 format one channel
PF_FLOAT32_R = 8,
// Float32 format and RGB
Expand Down
9 changes: 9 additions & 0 deletions include/gz/rendering/Utils.hh
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#define GZ_RENDERING_UTILS_HH_

#include <vector>
#include <memory>

#include <gz/math/Helpers.hh>
#include <gz/math/AxisAlignedBox.hh>
Expand All @@ -29,6 +30,7 @@
#include "gz/rendering/config.hh"
#include "gz/rendering/Export.hh"
#include "gz/rendering/RayQuery.hh"
#include "gz/rendering/Image.hh"


namespace gz
Expand Down Expand Up @@ -111,6 +113,13 @@ namespace gz
gz::math::Matrix3d projectionToCameraIntrinsic(
const gz::math::Matrix4d &_projectionMatrix,
double _width, double _height);

/// \brief convert an RGB image data into bayer image data
/// \param[in] _image Input RGB image
/// \param[in] _bayerFormat Bayer format to convert to
/// \return Image in bayer format
GZ_RENDERING_VISIBLE
Image convertRGBToBayer(const Image &_image, PixelFormat _bayerFormat);
}
}
}
Expand Down
45 changes: 39 additions & 6 deletions ogre/src/OgreRenderTarget.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
#include "gz/rendering/ogre/OgreScene.hh"
#include "gz/rendering/ogre/OgreCamera.hh"
#include "gz/rendering/ogre/OgreIncludes.hh"
#include "gz/rendering/Utils.hh"

#include <string.h>

using namespace gz;
using namespace rendering;
Expand All @@ -71,7 +74,6 @@ void OgreRenderTarget::Copy(Image &_image) const
if (nullptr == this->RenderTarget())
return;

// TODO(anyone): handle Bayer conversions
// TODO(anyone): handle ogre version differences

if (_image.Width() != this->width || _image.Height() != this->height)
Expand All @@ -80,10 +82,30 @@ void OgreRenderTarget::Copy(Image &_image) const
return;
}

void* data = _image.Data();
Ogre::PixelFormat imageFormat = OgreConversions::Convert(_image.Format());
Ogre::PixelBox ogrePixelBox(this->width, this->height, 1, imageFormat, data);
this->RenderTarget()->copyContentsToMemory(ogrePixelBox);
Ogre::PixelFormat imageFormat;
if ((_image.Format() == PF_BAYER_RGGB8) ||
(_image.Format() == PF_BAYER_BGGR8) ||
(_image.Format() == PF_BAYER_GBRG8) ||
(_image.Format() == PF_BAYER_GRBG8))
{
// create tmp color image to get data from gpu
imageFormat = OgreConversions::Convert(PF_R8G8B8);
Image colorImage(this->width, this->height, PF_R8G8B8);
void *data = colorImage.Data();
Ogre::PixelBox ogrePixelBox(
this->width, this->height, 1, imageFormat, data);
this->RenderTarget()->copyContentsToMemory(ogrePixelBox);
// convert color image to bayer image
_image = gz::rendering::convertRGBToBayer(colorImage, _image.Format());
}
else
{
imageFormat = OgreConversions::Convert(_image.Format());
void *data = _image.Data();
Ogre::PixelBox ogrePixelBox(
this->width, this->height, 1, imageFormat, data);
this->RenderTarget()->copyContentsToMemory(ogrePixelBox);
}
}

//////////////////////////////////////////////////
Expand Down Expand Up @@ -361,7 +383,18 @@ void OgreRenderTexture::DestroyTarget()
void OgreRenderTexture::BuildTarget()
{
Ogre::TextureManager &manager = Ogre::TextureManager::getSingleton();
Ogre::PixelFormat ogreFormat = OgreConversions::Convert(this->format);
Ogre::PixelFormat ogreFormat;
if ((this->format == PF_BAYER_RGGB8) ||
(this->format == PF_BAYER_BGGR8) ||
(this->format == PF_BAYER_GBRG8) ||
(this->format == PF_BAYER_GRBG8))
{
ogreFormat = OgreConversions::Convert(PF_R8G8B8);
}
else
{
ogreFormat = OgreConversions::Convert(this->format);
}

// check if target fsaa is supported
unsigned int fsaa = 0;
Expand Down
38 changes: 34 additions & 4 deletions ogre2/src/Ogre2RenderTarget.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
#include "gz/rendering/ogre2/Ogre2Material.hh"
#include "gz/rendering/ogre2/Ogre2RenderTarget.hh"
#include "gz/rendering/ogre2/Ogre2Scene.hh"
#include "gz/rendering/Utils.hh"

#include <string.h>

namespace gz
{
Expand Down Expand Up @@ -360,7 +363,18 @@ void Ogre2RenderTarget::Copy(Image &_image) const
return;
}

Ogre::PixelFormatGpu dstOgrePf = Ogre2Conversions::Convert(_image.Format());
Ogre::PixelFormatGpu dstOgrePf;
if ((_image.Format() == PF_BAYER_RGGB8) ||
(_image.Format() == PF_BAYER_BGGR8) ||
(_image.Format() == PF_BAYER_GBRG8) ||
(_image.Format() == PF_BAYER_GRBG8))
{
dstOgrePf = Ogre2Conversions::Convert(PF_R8G8B8);
}
else
{
dstOgrePf = Ogre2Conversions::Convert(_image.Format());
}
Ogre::TextureGpu *texture = this->RenderTarget();

if (Ogre::PixelFormatGpuUtils::isSRgb(dstOgrePf) !=
Expand All @@ -385,10 +399,26 @@ void Ogre2RenderTarget::Copy(Image &_image) const
static_cast<uint32_t>(Ogre::PixelFormatGpuUtils::getSizeBytes(
texture->getInternalWidth(), texture->getInternalHeight(), 1u, 1u,
dstOgrePf, 1u)));
dstBox.data = _image.Data();

Ogre::Image2::copyContentsToMemory(texture, texture->getEmptyBox(0u), dstBox,
dstOgrePf);
if ((_image.Format() == PF_BAYER_RGGB8) ||
(_image.Format() == PF_BAYER_BGGR8) ||
(_image.Format() == PF_BAYER_GBRG8) ||
(_image.Format() == PF_BAYER_GRBG8))
{
// create tmp color image to get data from gpu
Image colorImage(this->width, this->height, PF_R8G8B8);
dstBox.data = colorImage.Data();
Ogre::Image2::copyContentsToMemory(
texture, texture->getEmptyBox(0u), dstBox, dstOgrePf);
// convert color image to bayer image
_image = gz::rendering::convertRGBToBayer(colorImage, _image.Format());
}
else
{
dstBox.data = _image.Data();
Ogre::Image2::copyContentsToMemory(
texture, texture->getEmptyBox(0u), dstBox, dstOgrePf);
}
}

//////////////////////////////////////////////////
Expand Down
20 changes: 10 additions & 10 deletions src/PixelFormat.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ const char *PixelUtil::names[PF_COUNT] =
"B8G8R8",
"BAYER_RGGB8",
"BAYER_BGGR8",
"BAYER_GBGR8",
"BAYER_GRGB8",
"BAYER_GBRG8",
"BAYER_GRBG8",
"FLOAT32_R",
"FLOAT32_RGBA",
"FLOAT32_RGB",
Expand All @@ -52,13 +52,13 @@ const unsigned char PixelUtil::channelCounts[PF_COUNT] =
// B8G8R8
3,
// BAYER_RGGB8
4,
1,
// BAYER_BGGR8
4,
// BAYER_GBGR8
4,
// BAYER_GRGB8
4,
1,
// BAYER_GBRG8
1,
// BAYER_GRBG8
1,
// PF_FLOAT32_R
1,
// PF_FLOAT32_RGBA
Expand Down Expand Up @@ -86,9 +86,9 @@ const unsigned char PixelUtil::channelByteCounts[PF_COUNT] =
1,
// BAYER_BGGR8
1,
// BAYER_GBGR8
// BAYER_GBRG8
1,
// BAYER_GRGB8
// BAYER_GRBG8
1,
// PF_FLOAT32_R
4,
Expand Down
145 changes: 145 additions & 0 deletions src/Utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@

#include "gz/rendering/Camera.hh"
#include "gz/rendering/RayQuery.hh"
#include "gz/rendering/PixelFormat.hh"
#include "gz/rendering/Utils.hh"


namespace gz
{
namespace rendering
Expand Down Expand Up @@ -248,6 +250,149 @@ gz::math::AxisAlignedBox transformAxisAlignedBox(
}
return gz::math::AxisAlignedBox(min, max);
}

/////////////////////////////////////////////////
Image convertRGBToBayer(const Image &_image, PixelFormat _bayerFormat)
{
const unsigned char *sourceImageData = _image.Data<unsigned char>();

unsigned int width = _image.Width();
unsigned int height = _image.Height();

Image destImage(width, height, _bayerFormat);
unsigned char *destImageData = destImage.Data<unsigned char>();

if (_bayerFormat == PF_BAYER_RGGB8)
{
for (unsigned int i=0; i < width; i++)
{
for (unsigned int j=0; j < height; j++)
{
if (j%2)
{
if (i%2)
{
destImageData[i+j*width] = sourceImageData[i*3+j*width*3+2];
}
else
{
destImageData[i+j*width] = sourceImageData[i*3+j*width*3+1];
}
}
else
{
if (i%2)
{
destImageData[i+j*width] = sourceImageData[i*3+j*width*3+1];
}
else
{
destImageData[i+j*width] = sourceImageData[i*3+j*width*3+0];
}
}
}
}
}

else if (_bayerFormat == PF_BAYER_BGGR8)
{
for (unsigned int i=0; i < width; i++)
{
for (unsigned int j=0; j < height; j++)
{
if (j%2)
{
if (i%2)
{
destImageData[i+j*width] = sourceImageData[i*3+j*width*3+0];
}
else
{
destImageData[i+j*width] = sourceImageData[i*3+j*width*3+1];
}
}
else
{
if (i%2)
{
destImageData[i+j*width] = sourceImageData[i*3+j*width*3+1];
}
else
{
destImageData[i+j*width] = sourceImageData[i*3+j*width*3+2];
}
}
}
}
}

else if (_bayerFormat == PF_BAYER_GBRG8)
{
for (unsigned int i=0; i < width; i++)
{
for (unsigned int j=0; j < height; j++)
{
if (j%2)
{
if (i%2)
{
destImageData[i+j*width] = sourceImageData[i*3+j*width*3+1];
}
else
{
destImageData[i+j*width] = sourceImageData[i*3+j*width*3+2];
}
}
else
{
if (i%2)
{
destImageData[i+j*width] = sourceImageData[i*3+j*width*3+0];
}
else
{
destImageData[i+j*width] = sourceImageData[i*3+j*width*3+1];
}
}
}
}
}

else if (_bayerFormat == PF_BAYER_GRBG8)
{
for (unsigned int i=0; i < width; i++)
{
for (unsigned int j=0; j < height; j++)
{
if (j%2)
{
if (i%2)
{
destImageData[i+j*width] = sourceImageData[i*3+j*width*3+1];
}
else
{
destImageData[i+j*width] = sourceImageData[i*3+j*width*3+0];
}
}
else
{
if (i%2)
{
destImageData[i+j*width] = sourceImageData[i*3+j*width*3+2];
}
else
{
destImageData[i+j*width] = sourceImageData[i*3+j*width*3+1];
}
}
}
}
}

return destImage;
}

}
}
}