image.cc
Go to the documentation of this file.
00001 /*
00002  * This file is part of the rc_genicam_api package.
00003  *
00004  * Copyright (c) 2017 Roboception GmbH
00005  * All rights reserved
00006  *
00007  * Author: Heiko Hirschmueller
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions are met:
00011  *
00012  * 1. Redistributions of source code must retain the above copyright notice,
00013  * this list of conditions and the following disclaimer.
00014  *
00015  * 2. Redistributions in binary form must reproduce the above copyright notice,
00016  * this list of conditions and the following disclaimer in the documentation
00017  * and/or other materials provided with the distribution.
00018  *
00019  * 3. Neither the name of the copyright holder nor the names of its contributors
00020  * may be used to endorse or promote products derived from this software without
00021  * specific prior written permission.
00022  *
00023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033  * POSSIBILITY OF SUCH DAMAGE.
00034  */
00035 
00036 #include "image.h"
00037 
00038 #include "exception.h"
00039 #include "pixel_formats.h"
00040 
00041 #include <cstring>
00042 
00043 namespace rcg
00044 {
00045 
00046 Image::Image(const Buffer *buffer)
00047 {
00048   if (buffer->getImagePresent())
00049   {
00050     timestamp=buffer->getTimestampNS();
00051 
00052     width=buffer->getWidth();
00053     height=buffer->getHeight();
00054     xoffset=buffer->getXOffset();
00055     yoffset=buffer->getYOffset();
00056     xpadding=buffer->getXPadding();
00057     ypadding=buffer->getYPadding();
00058     frameid=buffer->getFrameID();
00059     pixelformat=buffer->getPixelFormat();
00060     bigendian=buffer->isBigEndian();
00061 
00062     const size_t size=buffer->getSizeFilled();
00063     const size_t offset=buffer->getImageOffset();
00064 
00065     pixel.reset(new uint8_t [size-offset]);
00066 
00067     memcpy(pixel.get(), reinterpret_cast<uint8_t *>(buffer->getBase())+offset, size-offset);
00068   }
00069   else
00070   {
00071     throw GenTLException("Image::Image(): Now image available.");
00072   }
00073 }
00074 
00075 namespace
00076 {
00077 
00082 inline unsigned char clamp8(int v)
00083 {
00084   const int v2=v<0 ? 0:v;
00085   return static_cast<unsigned char>(v2>255 ? 255:v2);
00086 }
00087 
00088 }
00089 
00090 void convYCbCr411toRGB(uint8_t rgb[3], const uint8_t *row, int i)
00091 {
00092   const uint32_t j=(i>>2)*6;
00093   const uint32_t js=i&0x3;
00094 
00095   int Y=row[j+js];
00096   if (js > 1)
00097   {
00098     Y=row[j+js+1];
00099   }
00100 
00101   const int Cb=static_cast<int>(row[j+2])-128;
00102   const int Cr=static_cast<int>(row[j+5])-128;
00103 
00104   const int rc=(90*Cr+32)>>6;
00105   const int gc=(-22*Cb-46*Cr+32)>>6;
00106   const int bc=(113*Cb+32)>>6;
00107 
00108   rgb[0]=clamp8(Y+rc);
00109   rgb[1]=clamp8(Y+gc);
00110   rgb[2]=clamp8(Y+bc);
00111 }
00112 
00113 void convYCbCr411toQuadRGB(uint8_t rgb[12], const uint8_t *row, int i)
00114 {
00115   i=(i>>2)*6;
00116 
00117   const int Y[4]={row[i], row[i+1], row[i+3], row[i+4]};
00118   const int Cb=static_cast<int>(row[i+2])-128;
00119   const int Cr=static_cast<int>(row[i+5])-128;
00120 
00121   const int rc=(90*Cr+32)>>6;
00122   const int gc=(-22*Cb-46*Cr+32)>>6;
00123   const int bc=(113*Cb+32)>>6;
00124 
00125   for (int j=0; j<4; j++)
00126   {
00127     *rgb++=clamp8(Y[j]+rc);
00128     *rgb++=clamp8(Y[j]+gc);
00129     *rgb++=clamp8(Y[j]+bc);
00130   }
00131 }
00132 
00133 void getColor(uint8_t rgb[3], const std::shared_ptr<const rcg::Image> &img,
00134               uint32_t ds, uint32_t i, uint32_t k)
00135 {
00136   i*=ds;
00137   k*=ds;
00138 
00139   if (img->getPixelFormat() == Mono8) // convert from monochrome
00140   {
00141     size_t lstep=img->getWidth()+img->getXPadding();
00142     const uint8_t *p=img->getPixels()+k*lstep+i;
00143 
00144     uint32_t g=0, n=0;
00145 
00146     for (uint32_t kk=0; kk<ds; kk++)
00147     {
00148       for (uint32_t ii=0; ii<ds; ii++)
00149       {
00150         g+=p[ii];
00151         n++;
00152       }
00153 
00154       p+=lstep;
00155     }
00156 
00157     rgb[2]=rgb[1]=rgb[0]=g/n;
00158   }
00159   else if (img->getPixelFormat() == YCbCr411_8) // convert from YUV
00160   {
00161     size_t lstep=(img->getWidth()>>2)*6+img->getXPadding();
00162     const uint8_t *p=img->getPixels()+k*lstep;
00163 
00164     uint32_t r=0;
00165     uint32_t g=0;
00166     uint32_t b=0;
00167     uint32_t n=0;
00168 
00169     for (uint32_t kk=0; kk<ds; kk++)
00170     {
00171       for (uint32_t ii=0; ii<ds; ii++)
00172       {
00173         uint8_t v[3];
00174         rcg::convYCbCr411toRGB(v, p, i+ii);
00175 
00176         r+=v[0];
00177         g+=v[1];
00178         b+=v[2];
00179         n++;
00180       }
00181 
00182       p+=lstep;
00183     }
00184 
00185     rgb[0]=r/n;
00186     rgb[1]=g/n;
00187     rgb[2]=b/n;
00188   }
00189 }
00190 
00191 }


rc_visard_driver
Author(s): Heiko Hirschmueller , Christian Emmerich , Felix Ruess
autogenerated on Thu Jun 6 2019 20:43:05