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, std::uint32_t part)
00047 {
00048   if (buffer->getImagePresent(part))
00049   {
00050     timestamp=buffer->getTimestampNS();
00051 
00052     width=buffer->getWidth(part);
00053     height=buffer->getHeight(part);
00054     xoffset=buffer->getXOffset(part);
00055     yoffset=buffer->getYOffset(part);
00056     xpadding=buffer->getXPadding(part);
00057     ypadding=buffer->getYPadding();
00058     frameid=buffer->getFrameID();
00059     pixelformat=buffer->getPixelFormat(part);
00060     bigendian=buffer->isBigEndian();
00061 
00062     const size_t size=buffer->getSize(part);
00063 
00064     pixel.reset(new uint8_t [size]);
00065 
00066     memcpy(pixel.get(), reinterpret_cast<uint8_t *>(buffer->getBase(part)), size);
00067   }
00068   else
00069   {
00070     throw GenTLException("Image::Image(): Now image available.");
00071   }
00072 }
00073 
00074 namespace
00075 {
00076 
00081 inline unsigned char clamp8(int v)
00082 {
00083   const int v2=v<0 ? 0:v;
00084   return static_cast<unsigned char>(v2>255 ? 255:v2);
00085 }
00086 
00087 }
00088 
00089 void convYCbCr411toRGB(uint8_t rgb[3], const uint8_t *row, int i)
00090 {
00091   const uint32_t j=static_cast<uint32_t>((i>>2)*6);
00092   const uint32_t js=static_cast<uint32_t>(i&0x3);
00093 
00094   int Y=row[j+js];
00095   if (js > 1)
00096   {
00097     Y=row[j+js+1];
00098   }
00099 
00100   const int Cb=static_cast<int>(row[j+2])-128;
00101   const int Cr=static_cast<int>(row[j+5])-128;
00102 
00103   const int rc=(90*Cr+32)>>6;
00104   const int gc=(-22*Cb-46*Cr+32)>>6;
00105   const int bc=(113*Cb+32)>>6;
00106 
00107   rgb[0]=clamp8(Y+rc);
00108   rgb[1]=clamp8(Y+gc);
00109   rgb[2]=clamp8(Y+bc);
00110 }
00111 
00112 void convYCbCr411toQuadRGB(uint8_t rgb[12], const uint8_t *row, int i)
00113 {
00114   i=(i>>2)*6;
00115 
00116   const int Y[4]={row[i], row[i+1], row[i+3], row[i+4]};
00117   const int Cb=static_cast<int>(row[i+2])-128;
00118   const int Cr=static_cast<int>(row[i+5])-128;
00119 
00120   const int rc=(90*Cr+32)>>6;
00121   const int gc=(-22*Cb-46*Cr+32)>>6;
00122   const int bc=(113*Cb+32)>>6;
00123 
00124   for (int j=0; j<4; j++)
00125   {
00126     *rgb++=clamp8(Y[j]+rc);
00127     *rgb++=clamp8(Y[j]+gc);
00128     *rgb++=clamp8(Y[j]+bc);
00129   }
00130 }
00131 
00132 void getColor(uint8_t rgb[3], const std::shared_ptr<const rcg::Image> &img,
00133               uint32_t ds, uint32_t i, uint32_t k)
00134 {
00135   i*=ds;
00136   k*=ds;
00137 
00138   if (img->getPixelFormat() == Mono8) // convert from monochrome
00139   {
00140     size_t lstep=img->getWidth()+img->getXPadding();
00141     const uint8_t *p=img->getPixels()+k*lstep+i;
00142 
00143     uint32_t g=0, n=0;
00144 
00145     for (uint32_t kk=0; kk<ds; kk++)
00146     {
00147       for (uint32_t ii=0; ii<ds; ii++)
00148       {
00149         g+=p[ii];
00150         n++;
00151       }
00152 
00153       p+=lstep;
00154     }
00155 
00156     rgb[2]=rgb[1]=rgb[0]=static_cast<uint8_t>(g/n);
00157   }
00158   else if (img->getPixelFormat() == YCbCr411_8) // convert from YUV
00159   {
00160     size_t lstep=(img->getWidth()>>2)*6+img->getXPadding();
00161     const uint8_t *p=img->getPixels()+k*lstep;
00162 
00163     uint32_t r=0;
00164     uint32_t g=0;
00165     uint32_t b=0;
00166     uint32_t n=0;
00167 
00168     for (uint32_t kk=0; kk<ds; kk++)
00169     {
00170       for (uint32_t ii=0; ii<ds; ii++)
00171       {
00172         uint8_t v[3];
00173         rcg::convYCbCr411toRGB(v, p, static_cast<int>(i+ii));
00174 
00175         r+=v[0];
00176         g+=v[1];
00177         b+=v[2];
00178         n++;
00179       }
00180 
00181       p+=lstep;
00182     }
00183 
00184     rgb[0]=static_cast<uint8_t>(r/n);
00185     rgb[1]=static_cast<uint8_t>(g/n);
00186     rgb[2]=static_cast<uint8_t>(b/n);
00187   }
00188 }
00189 
00190 }


rc_genicam_api
Author(s): Heiko Hirschmueller
autogenerated on Thu Jun 6 2019 18:42:47