00001 #include "InterpolatingImageComposer.hpp" 00002 00003 namespace virtual_camera { 00004 00005 /*PUBLIC METHODS*/ 00006 00007 InterpolatingImageComposer::InterpolatingImageComposer( 00008 const RealCameraPtrListPtr & realCameras) { 00009 this->realCameras = realCameras; 00010 this->cacheSize = 0; 00011 } 00012 00013 00014 void InterpolatingImageComposer::refreshCache(uint rows, uint cols) { 00015 std::list<RealCameraPtr>::iterator it = this->realCameras->begin(); 00016 uint cams = this->realCameras->size(); 00017 this->camsPos.clear(); 00018 this->camsPos.reserve(cams); 00019 while (it != this->realCameras->end()) { 00020 this->camsPos.push_back((*it)->getCachedPositions()); 00021 ++it; 00022 } 00023 if (rows*cols*cams != this->cacheSize) { 00024 this->weightCache.reset(new float[rows*cols*cams]); 00025 } 00026 float totalSum; 00027 std::vector<float> buffer(cams); 00028 this->camsImg.reserve(cams); 00029 this->camsNeeded.reserve(cams); 00030 for (uint i=0; i<cams; i++) { this->camsNeeded[i] = false; } 00031 for (uint i=0; i<rows; i++) { 00032 for (uint j=0; j<cols; j++) { 00033 uint k = 0; 00034 totalSum = 0; 00035 it = this->realCameras->begin(); 00036 while (it != this->realCameras->end()) { 00037 float w = (*it)->getWeight(i, j); 00038 buffer[k] = w; 00039 totalSum += w; 00040 ++it; 00041 ++k; 00042 } 00043 for (k=0; k<cams; k++) { 00044 float w = buffer[k]/totalSum; 00045 this->weightCache[i*cols*cams+j*cams+k] = w; 00046 if (w > 0.000001){ 00047 this->camsNeeded[k] = true; 00048 } 00049 } 00050 } 00051 } 00052 //ROS_INFO("Weight cache refreshed."); 00053 } 00054 00055 00056 void InterpolatingImageComposer::compose( 00057 const cv_bridge::CvImagePtr & target, const std::string & encoding) { 00058 this->prepareRealCameraImages(encoding); 00059 uint cams = this->realCameras->size(); 00060 uint nChannels = target->image.channels(); 00061 uint nRows = target->image.rows; 00062 uint nCols = target->image.cols; 00063 uchar *vP; 00064 const uchar * rP; 00065 for (uint i=0; i < nRows; i++) { 00066 vP = target->image.ptr<uchar>(i); 00067 for (uint j=0; j < nCols; j++) { 00068 for(uint k=0; k < cams; k++) { 00069 float weight = this->weightCache[i*nCols*cams+j*cams+k]; 00070 if (weight > 0) { 00071 const Point2D & pt = (*(this->camsPos[k]))[i][j]; 00072 rP = this->camsImg[k]->image.ptr(pt.y, pt.x); 00073 for (uint l=0; l < nChannels; l++) { 00074 vP[nChannels*j+l] += static_cast<uchar>(weight*rP[l]); 00075 } 00076 } 00077 } 00078 } 00079 } 00080 } 00081 00082 00083 /*PUBLIC METHODS END*/ 00084 /*PRIVATE METHODS*/ 00085 void InterpolatingImageComposer::prepareRealCameraImages(const std::string & enc) { 00086 std::list<RealCameraPtr>::iterator cam = this->realCameras->begin(); 00087 std::list<RealCameraPtr>::iterator end = this->realCameras->end(); 00088 int i = 0; 00089 this->camsImg.clear(); 00090 //ROS_INFO("new image composition"); 00091 for (; cam != end; ++cam, ++i){ 00092 if (this->camsNeeded[i]) { 00093 this->camsImg.push_back(cv_bridge::toCvShare((*cam)->getImage(), enc)); 00094 //ROS_INFO_STREAM((*cam)->getImage()->header.stamp.toNSec()); 00095 }else { 00096 this->camsImg.push_back(cv_bridge::CvImageConstPtr()); 00097 } 00098 } 00099 } 00100 /*PRIVATE METHODS END*/ 00101 00102 00103 } 00104 00105 00106