Skip to content

Commit

Permalink
Add support for bayer images to Ogre and Ogre2 (#838)
Browse files Browse the repository at this point in the history

Signed-off-by: tejalbarnwal <tejalbarnwal@gmail.com>
Signed-off-by: Ian Chen <ichen@openrobotics.org>
Co-authored-by: Ian Chen <ichen@openrobotics.org>
  • Loading branch information
tejalbarnwal and iche033 committed May 1, 2023
1 parent 7091c94 commit 7dc64e5
Show file tree
Hide file tree
Showing 6 changed files with 241 additions and 24 deletions.
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,
// 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;
}

}
}
}

0 comments on commit 7dc64e5

Please sign in to comment.