20 #include <vigra/stdimage.hxx>
21 #include <vigra/resizeimage.hxx>
22 #include <vigra/inspectimage.hxx>
23 #include <vigra/copyimage.hxx>
24 #include <vigra/transformimage.hxx>
25 #include <vigra/initimage.hxx>
26 #include "vigra/colorconversions.hxx"
27 #include <sys/types.h>
42 typedef vigra::BRGBImage::PixelType
RGB;
49 std::cout <<
"Couldn't load model file '" << model_file <<
"'" << std::endl << std::endl;
54 std::cout <<
"Loaded model file:\t" << model_file << std::endl;
66 void prepareCelesteImage(vigra::UInt16RGBImage& rgb,vigra::UInt16RGBImage& luv,
int& resize_dimension,
double& sizefactor,
bool verbose)
75 if (resize_dimension >= nw )
77 resize_dimension = nw;
82 if (resize_dimension >= nh)
84 resize_dimension = nh;
89 std::cout <<
"Image dimensions:\t" << rgb.width() <<
" x " << rgb.height() << std::endl;
92 vigra::UInt16RGBImage temp;
94 if (rgb.width() > resize_dimension || rgb.height() > resize_dimension)
96 if (rgb.width() >= rgb.height())
98 sizefactor = (double)resize_dimension/rgb.width();
100 nw = resize_dimension;
101 nh =
static_cast<int>(0.5 + (sizefactor*rgb.height()));
105 sizefactor = (double)resize_dimension/rgb.height();
107 nw =
static_cast<int>(0.5 + (sizefactor*rgb.width()));
108 nh = resize_dimension;
113 std::cout <<
"Scaling by:\t\t" << sizefactor << std::endl;
114 std::cout <<
"New dimensions:\t\t" << nw <<
" x " << nh << std::endl;
131 luv.resize(temp.width(),temp.height());
140 pixels =
CreateMatrix( (
float)0, luv.height(), luv.width() );
142 for (
int i = 0; i < luv.height(); i++ )
144 for (
int j = 0; j < luv.width(); j++ )
146 pixels[i][j] = luv(j,i)[0];
153 std::vector<double>
classifySVM(
struct svm_model* model,
int gNumLocs,
int**& gLocations,
int width,
int height,
int vector_length,
float*&
response,
int gRadius,vigra::UInt16RGBImage& luv,
bool needsMoreIndex=
false)
155 std::vector<double> svm_response;
157 int max_nr_attr = 56;
160 double *prob_estimates = (
double *) malloc(nr_class*
sizeof(
double));
162 for (
int j = 0; j < gNumLocs; j++)
164 unsigned int feature = 1;
168 if(j >= max_nr_attr - 1)
172 if(newPointer == NULL)
174 svm_response.clear();
175 free(gabor_responses);
176 free(prob_estimates);
179 gabor_responses=newPointer;
183 for (
int v = (j * vector_length); v < ((j + 1) * vector_length); v++)
185 gabor_responses[feature-1].
index = feature;
186 gabor_responses[feature-1].
value = response[v];
192 vigra::FindAverageAndVariance<vigra::UInt16RGBImage::PixelType> average;
193 vigra::inspectImage(srcIterRange(
194 luv.upperLeft()+vigra::Diff2D(gLocations[j][0]-gRadius,gLocations[j][1]-gRadius),
195 luv.upperLeft()+vigra::Diff2D(gLocations[j][0]+gRadius,gLocations[j][1]+gRadius)
199 gabor_responses[feature-1].
index = feature;
200 gabor_responses[feature-1].
value = average.average()[1];
203 gabor_responses[feature-1].
index = feature;
204 gabor_responses[feature-1].
value = sqrt(average.variance()[1]);
207 gabor_responses[feature-1].
index = feature;
208 gabor_responses[feature-1].
value = average.average()[2];
211 gabor_responses[feature-1].
index = feature;
212 gabor_responses[feature-1].
value = sqrt(average.variance()[2]);
215 gabor_responses[feature-1].
index = feature;
216 gabor_responses[feature-1].
value = luv(gLocations[j][0],gLocations[j][1])[1];
219 gabor_responses[feature-1].
index = feature;
220 gabor_responses[feature-1].
value = luv(gLocations[j][0],gLocations[j][1])[2];
222 gabor_responses[feature].
index = -1;
225 svm_response.push_back(prob_estimates[0]);
228 free(gabor_responses);
229 free(prob_estimates);
234 void createGrid(
int& gNumLocs,
int**& gLocations,
int gRadius,
int width,
int height)
236 int spacing=(gRadius*2)+1;
237 for (
int i = gRadius; i < height - gRadius; i += spacing )
239 for (
int j = gRadius; j < width - gRadius; j += spacing )
248 for (
int j = gRadius; j < width - gRadius; j += spacing )
256 for (
int i = gRadius; i < height - gRadius; i += spacing )
258 for (
int j = gRadius; j < width - gRadius; j += spacing )
260 gLocations[gNumLocs][0] = j;
261 gLocations[gNumLocs][1] = i;
269 gLocations[gNumLocs][0] = width - gRadius - 1;
270 gLocations[gNumLocs][1] = i;
277 if (height % spacing)
279 for (
int j = gRadius; j < width - gRadius; j += spacing )
281 gLocations[gNumLocs][0] = j;
282 gLocations[gNumLocs][1] = height - gRadius - 1;
290 void generateMask(vigra::BImage& mask,
int& gNumLocs,
int**& gLocations,std::vector<double> svm_responses,
int gRadius,
double threshold)
292 for (
int j = 0; j < gNumLocs; j++ )
294 if (svm_responses[j] >= threshold)
296 unsigned int sub_x0 = gLocations[j][0] - gRadius;
297 unsigned int sub_y0 = gLocations[j][1] - gRadius;
298 unsigned int sub_x1 = gLocations[j][0] + gRadius + 1;
299 unsigned int sub_y1 = gLocations[j][1] + gRadius + 1;
303 vigra::initImage(srcIterRange(mask.upperLeft() + vigra::Diff2D(sub_x0, sub_y0),
304 mask.upperLeft() + vigra::Diff2D(sub_x1, sub_y1)), 0);
315 vigra::UInt16RGBImage luv;
316 double sizefactor=1.0;
323 int** gLocations = NULL;
327 createGrid(gNumLocs,gLocations,radius,luv.width(),luv.height());
330 float* mask_response=NULL;
331 mask_response =
ProcessChannel(pixels,luv.width(),luv.height(),gNumLocs,gLocations,radius,mask_response,&len);
333 std::vector<double> svm_responses=
classifySVM(model,gNumLocs,gLocations,luv.width(),luv.height(),(int)len/gNumLocs,mask_response,radius,luv);
334 delete [] mask_response;
339 for(
unsigned int i=0;i<svm_responses.size();i++)
341 if(svm_responses[i]<minVal)
343 minVal=svm_responses[i];
348 threshold =
std::min(minVal + 0.1, 1.0);
352 vigra::BImage mask_out(luv.width(), luv.height(),255);
353 generateMask(mask_out,gNumLocs,gLocations,svm_responses,radius,threshold);
355 vigra::BImage* mask_resize =
new vigra::BImage(input.size());
359 mask_out.resize(0,0);
366 vigra::UInt16RGBImage luv;
367 double sizefactor=1.0;
374 int gNumLocs = cps.size();
376 for(
unsigned int j=0;j<cps.size();j++)
379 gLocations[j][0] = int(cp.
x1 * sizefactor);
380 gLocations[j][1] = int(cp.
y1 * sizefactor);
382 if (gLocations[j][0] <= radius)
384 gLocations[j][0] = radius + 1;
386 if (gLocations[j][1] <= radius)
388 gLocations[j][1] = radius + 1;
390 if (gLocations[j][0] >= luv.width() - radius)
392 gLocations[j][0] = luv.width() - radius - 1;
394 if (gLocations[j][1] >= luv.height() - radius)
396 gLocations[j][1] = luv.height() - radius - 1;
404 std::vector<double> svm_responses =
classifySVM(model, gNumLocs, gLocations, luv.width(), luv.height(), (int)len / gNumLocs, response, radius, luv);
407 for(
unsigned int i=0;i<svm_responses.size();i++)
409 if(svm_responses[i]>=threshold)
411 cloudCP.insert(cps[i].first);
void destroySVMmodel(struct svm_model *&model)
frees the resource of model
double svm_predict_probability(const svm_model *model, const svm_node *x, double *prob_estimates)
void transformImage(vigra::triple< SrcImageIterator, SrcImageIterator, SrcAccessor > src, vigra::triple< DestImageIterator, DestImageIterator, DestAccessor > dest, std::pair< AlphaImageIterator, AlphaAccessor > alpha, vigra::Diff2D destUL, TRANSFORM &transform, PixelTransform &pixelTransform, bool warparound, Interpolator interpol, AppBase::ProgressDisplay *progress, bool singleThreaded=false)
Transform an image into the panorama.
void createGrid(int &gNumLocs, int **&gLocations, int gRadius, int width, int height)
vigra::BImage * getCelesteMask(struct svm_model *model, vigra::UInt16RGBImage &input, int radius, float threshold, int resize_dimension, bool adaptThreshold, bool verbose)
calculates the mask using SVM
void generateMask(vigra::BImage &mask, int &gNumLocs, int **&gLocations, std::vector< double > svm_responses, int gRadius, double threshold)
represents a control point
std::vector< double > classifySVM(struct svm_model *model, int gNumLocs, int **&gLocations, int width, int height, int vector_length, float *&response, int gRadius, vigra::UInt16RGBImage &luv, bool needsMoreIndex=false)
std::set< unsigned int > UIntSet
void svm_free_and_destroy_model(svm_model **model_ptr_ptr)
void prepareCelesteImage(vigra::UInt16RGBImage &rgb, vigra::UInt16RGBImage &luv, int &resize_dimension, double &sizefactor, bool verbose)
svm_model * svm_load_model(const char *model_file_name)
bool loadSVMmodel(struct svm_model *&model, std::string &model_file)
loads the SVM model from file
float * ProcessChannel(float **image, int w, int h, int gNumLocs, int **&gLocations, int gRadius, float *response, int *len)
void DisposeMatrix(int **matrix, int row)
static deghosting::EMoR response(0.0f)
vigra::BRGBImage::PixelType RGB
int ** CreateMatrix(int val, int row, int col)
vigra::pair< typename ROIImage< Image, Alpha >::image_traverser, typename ROIImage< Image, Alpha >::ImageAccessor > destImage(ROIImage< Image, Alpha > &img)
vigra::triple< typename ROIImage< Image, Mask >::image_const_traverser, typename ROIImage< Image, Mask >::image_const_traverser, typename ROIImage< Image, Mask >::ImageConstAccessor > srcImageRange(const ROIImage< Image, Mask > &img)
helper function for ROIImages
std::vector< CPoint > CPointVector
int svm_get_nr_class(const svm_model *model)
std::vector< deghosting::BImagePtr > threshold(const std::vector< deghosting::FImagePtr > &inputImages, const double threshold, const uint16_t flags)
Threshold function used for creating alpha masks for images.
HuginBase::UIntSet getCelesteControlPoints(struct svm_model *model, vigra::UInt16RGBImage &input, HuginBase::CPointVector cps, int radius, float threshold, int resize_dimension, bool verbose)
vigra::triple< typename ROIImage< Image, Alpha >::image_traverser, typename ROIImage< Image, Alpha >::image_traverser, typename ROIImage< Image, Alpha >::ImageAccessor > destImageRange(ROIImage< Image, Alpha > &img)
void prepareGaborImage(vigra::UInt16RGBImage &luv, float **&pixels)
void copyImage(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor src_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc)