Blender.cpp
Go to the documentation of this file.
00001 /*
00002  * Blender.cpp
00003  *
00004  *  Created on: Jun 18, 2010
00005  *      Author: ethan
00006  */
00007 
00008 #include "pano_core/Blender.h"
00009 #include "pano_core/ModelFitter.h"
00010 #include "pano_core/panoutils.h"
00011 #if 0
00012 #include "wavelet2d/wavelet2d.h"
00013 #endif
00014 #include "opencv2/highgui/highgui.hpp"
00015 #include <iomanip>
00016 
00017 using namespace cv;
00018 using std::cout;
00019 using std::endl;
00020 using namespace pano;
00021 namespace pano
00022 {
00023 
00024 BlenderAlpha::BlenderAlpha(int feather_edge) : cbe(0),
00025   feather_edge(feather_edge)
00026 {
00027 
00028 }
00029 
00030 using namespace cv;
00031 void initAlphaMat(const Size& sz, Mat& alpha, int feather_width)
00032 {
00033   if (alpha.size() != sz || alpha.type() != CV_8UC3)
00034   {
00035     alpha = Mat::zeros(sz, CV_8UC3);
00036   }
00037   vector<uchar> _feather(feather_width);
00038   for (int i = 0; i < feather_width; i++)
00039   {
00040     _feather[i] = 1 + 254 * sin(i * CV_PI / (2 * feather_width));
00041   }
00042 
00043   for (int y = 0; y < alpha.rows; y++)
00044   {
00045     for (int x = 0; x < alpha.cols; x++)
00046     {
00047       int feather = min(min(x, y), min(alpha.cols - x, alpha.rows - y));
00048       uchar val = feather < feather_width ? _feather[feather] : 255;
00049       alpha.at<Vec3b> (y, x) = Vec3b(val, val, val);
00050     }
00051   }
00052 
00053 }
00054 BlenderAlpha::BlenderAlpha(int feather_edge, Size outputsize, Size inputsize) : cbe(0),
00055   feather_edge(feather_edge), outputsize(outputsize), projector(outputsize, Size(10, 5))
00056 {
00057   setInputSize(inputsize);
00058 }
00059 
00060 void BlenderAlpha::setOutputSize(cv::Size size)
00061 {
00062   if (outputsize != size)
00063   {
00064     outputsize = size;
00065     projector = SparseProjector(outputsize, Size(10, 5));
00066 
00067   }
00068 }
00069 
00070 void BlenderAlpha::setInputSize(cv::Size size)
00071 {
00072   if (inputSize != size)
00073   {
00074     inputSize = size;
00075     initAlphaMat(inputSize, alpha, feather_edge);
00076     subtract(Scalar::all(255), alpha, one_minus_alpha);
00077   }
00078 }
00079 
00080 void BlenderAlpha::blendMolecule(const ImageMolecule& mol, cv::Size outputsize, const std::string& name_prefix)
00081 {
00082   setOutputSize(outputsize);
00083   std::set<Ptr<ImageAtom> >::const_iterator atom = mol.getAtoms().begin();
00084 
00085   huge_image_.setSize(outputsize);
00086   output_prefix = name_prefix;
00087   for (; atom != mol.getAtoms().end(); ++atom)
00088   {
00089 
00090     Mat m;
00091     blendIncremental(**atom, m);
00092   }
00093   huge_image_.serialize("huge.yaml");
00094   //  Mat image = huge_image_.loadAll();
00095   //  //imshow("huge",image);
00096   //  imwrite("huge.jpg",image);
00097   // waitKey();
00098 }
00099 
00100 BlenderAlpha::~BlenderAlpha()
00101 {
00102 
00103 }
00104 
00105 void alphaCompose(Mat& rgb1, const Mat& alpha, const Mat& one_minus_alpha, Mat& rgb_dest/*, const Mat &  mask = Mat()*/)
00106 {
00107   multiply(rgb_dest, one_minus_alpha, rgb_dest, 1. / 255);
00108   multiply(rgb1, alpha, rgb1, 1. / 255);
00109   rgb_dest += rgb1;
00110 }
00111 
00112 void BlenderAlpha::blendIncremental(const ImageAtom& atom, cv::Mat& outimage)
00113 {
00114   // assert(outimage.type() == atom.getImageraw().type());
00115   setOutputSize(outimage.size());
00116   assert((outimage.empty() && output_prefix.size() ) || outimage.type() == CV_8UC3);
00117   Mat img;
00118   if (atom.images().src().empty())
00119   {
00120     Images images = atom.images();
00121     images.restore();
00122     img = images.src();
00123   }
00124   else
00125     img = atom.images().src();
00126 
00127   if (cbe)
00128   {
00129     cbe->callBack(atom, 0);
00130   }
00131   setInputSize(img.size());
00132 
00133   Mat _img = img;
00134   Mat _R = atom.extrinsics().mat(Extrinsics::R);
00135 
00136   std::vector<int> roi_ids;
00137 
00138   //setup the projector
00139   projector.setSRandK(inputSize, _R, atom.camera().K(), roi_ids);
00140 
00141   std::string roi_name;
00142   for (int i = 0; i < (int)roi_ids.size(); i++)
00143   {
00144 
00145     int roi_id = roi_ids[i];
00146     Rect roi = projector.getRoi(roi_id);
00147     Mat roi_out;
00148     if (outimage.empty())
00149     {
00150       roi_name = huge_image_.addName(roi_id, output_prefix);
00151       huge_image_.addRoi(roi_id, roi);
00152       roi_out = imread(roi_name);
00153       if (roi_out.empty())
00154         roi_out = cv::Mat::zeros(roi.size(), CV_8UC3);
00155     }
00156     else
00157       roi_out = outimage(roi);
00158 
00159     //project the image onto a clean slate
00160     projector.projectMat(roi_id, _img, in_img, cv::BORDER_CONSTANT);
00161 
00162     projector.projectMat(roi_id, alpha, in_alpha, cv::BORDER_CONSTANT);
00163 
00164     projector.projectMat(roi_id, one_minus_alpha, in_one_minus_alpha, cv::BORDER_CONSTANT, Scalar::all(255));
00165 
00166     alphaCompose(in_img, in_alpha, in_one_minus_alpha, roi_out);
00167     if (outimage.empty())
00168     {
00169       imwrite(roi_name, roi_out);
00170     }
00171 #if 0
00172     stringstream ss;
00173     ss << "roi" << roi_id;
00174 
00175     imshow(ss.str(), roi_out);
00176     waitKey(10);
00177 #endif
00178   }
00179 
00180 }
00181 
00182 void BlenderAlpha::BlendMolecule(const ImageMolecule& molecule, cv::Mat& outimage)
00183 {
00184   // will look ok with equalize pair... I think...
00185 
00186   // assert(outimage.type() == molecule.getAnchor()->getImageraw().type());
00187 
00188   assert(outimage.type() == CV_8UC3);
00189   setOutputSize(outimage.size());
00190   outimage = Scalar(0);
00191 
00192   std::set<cv::Ptr<ImageAtom> >::const_iterator atom = molecule.getAtoms().begin();
00193 
00194   for (; atom != molecule.getAtoms().end(); ++atom)
00195   {
00196 
00197     blendIncremental(**atom, outimage);
00198   }
00199 
00200 }
00201 
00202 
00203 void Blender::fillWeightsGaussian32(cv::Mat& weights, float sigma_squared)
00204 {
00205   for (int y = 0; y < weights.rows; y++)
00206   {
00207     for (int x = 0; x < weights.cols; x++)
00208     {
00209       float y_h = ((float)y) / (weights.rows - 1.0) - 0.5;
00210       float x_h = ((float)x) / (weights.cols - 1.0) - 0.5;
00211       x_h *= 2; //x goes from -1 to 1
00212       y_h *= 2; //y "" ""
00213       double val = max((abs(x_h)), (abs((y_h))));
00214       val = exp(-(val) / (2 * sigma_squared)) * 1000.0;
00215       weights.at<float> (y, x) = val;
00216     }
00217   }
00218   double dmin, dmax;
00219   cv::minMaxLoc(weights, &dmin, &dmax);
00220   weights = weights - dmin;
00221   weights = (weights) / (dmax - dmin);
00222 }
00223 
00224 void Blender::fillWeightsGaussian64(cv::Mat& weights, double sigma_squared)
00225 {
00226   for (int y = 0; y < weights.rows; y++)  {
00227     for (int x = 0; x < weights.cols; x++)   {
00228       double y_h = ((float)y) / (weights.rows - 1.0) - 0.5;
00229       double x_h = ((float)x) / (weights.cols - 1.0) - 0.5;
00230       x_h *= 2; //x goes from -1 to 1
00231       y_h *= 2; //y "" ""
00232       double val = max( ( abs(x_h) ), ( abs( ( y_h ) ) ) );
00233       val = exp(-(val) / (2 * sigma_squared) ) * 255.0;
00234       weights.at<double> (y, x) = val;
00235     }
00236   }
00237   double dmin, dmax;
00238   cv::minMaxLoc(weights, &dmin, &dmax);
00239   weights = weights - dmin;
00240   weights = (weights) / (dmax - dmin);
00241 }
00242 }
00243 


pano_core
Author(s): Ethan Rublee
autogenerated on Wed Aug 26 2015 16:34:01