From: <bl...@us...> - 2009-05-07 23:16:32
|
Revision: 3835 http://hugin.svn.sourceforge.net/hugin/?rev=3835&view=rev Author: blimbo Date: 2009-05-07 23:16:26 +0000 (Thu, 07 May 2009) Log Message: ----------- Added more functions to take slices of image then extract (x,y) coordinates of lines Modified Paths: -------------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Makefile Added Paths: ----------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt 2009-05-07 21:37:41 UTC (rev 3834) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt 2009-05-07 23:16:26 UTC (rev 3835) @@ -1,3 +1,3 @@ -ADD_EXECUTABLE(calibrate_lens Main.cpp ) +ADD_EXECUTABLE(calibrate_lens Main.cpp Globals.cpp ProcessImage.cpp ) TARGET_LINK_LIBRARIES( calibrate_lens ${image_libs} ) INSTALL(TARGETS calibrate_lens DESTINATION ${BINDIR}) Added: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp (rev 0) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp 2009-05-07 23:16:26 UTC (rev 3835) @@ -0,0 +1,32 @@ +/*************************************************************************** + * Copyright (C) 2008 by Tim Nugent * + * tim...@gm... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "Globals.h" +#include <string> + +unsigned int resize_dimension = 800; +unsigned int detector = 0; +std::string path = ("output/"); +std::string format = (".jpg"); +double threshold = 8; +double scale = 2; +unsigned int vertical_slices = 12; +unsigned int horizontal_slices = 8; +unsigned int generate_images = 1; Added: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h (rev 0) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h 2009-05-07 23:16:26 UTC (rev 3835) @@ -0,0 +1,17 @@ +#ifndef GLOBALS_H +#define GLOBALS_H + +#include <string> + +extern unsigned int resize_dimension; +extern unsigned int detector; +extern std::string path; +extern std::string format; +extern double threshold; +extern double scale; +extern unsigned int horizontal_slices; +extern unsigned int vertical_slices; +extern unsigned int generate_images; + +#endif + Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp 2009-05-07 21:37:41 UTC (rev 3834) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp 2009-05-07 23:16:26 UTC (rev 3835) @@ -24,11 +24,9 @@ #include <sstream> #include <vector> #include <string> -#include "vigra/impex.hxx" -#include "vigra/stdimage.hxx" -#include "vigra/edgedetection.hxx" -#include "vigra/colorconversions.hxx" -#include "vigra/impex.hxx" +#include "vigra/stdimagefunctions.hxx" +#include "Globals.h" +#include "ProcessImage.h" using namespace vigra; using namespace std; @@ -42,65 +40,19 @@ cout << endl << "Version " << VERSION << endl; cout << endl << "Usage: calibrate_lens [options] image1 image2.." << endl << endl; cout << "Options:" << endl << endl; - cout << " -d <0|1> Edge detector. 0 = Canny (default) 1 = Shen-Castan." << endl; - cout << " -s <int> Maximum dimension for re-sized image prior to processing. Default 800." << endl; + cout << " -e <0|1> Edge detector. 0 = Canny (default) 1 = Shen-Castan." << endl; + cout << " -d <int> Maximum dimension for re-sized image prior to processing. Default 800." << endl; cout << " -f <string> Output file format. Default .JPG" << endl; cout << " -p <path> Output path. Default output/" << endl; + cout << " -s <float> Edge detector scale. Default 2" << endl; + cout << " -t <float> Edge detector threshold. Default 8" << endl; + cout << " -i <0|1> Generate intermediate images. Default 1" << endl; cout << " -h Print usage." << endl; cout << endl; exit(1); } -void detect_edge(vigra::BImage& image, string& file, string& path, string& format, unsigned int& detector, double& threshold, double& scale, unsigned int& resize_dimension){ - - try{ - - // Paint output image white - vigra::BImage out(image.width(), image.height()); - //cout << image.width() << " x " << image.height() << endl; - out = 255; - - if(detector){ - - // Call Shen-Castan detector algorithm - differenceOfExponentialEdgeImage(srcImageRange(image), destImage(out), - scale, threshold, 0); - }else{ - - // Call Canny detector algorithm - cannyEdgeImage(srcImageRange(image), destImage(out), - scale, threshold, 0); - } - - string output = path; - - // Create output file name - if (file.substr(file.length()-4,1) == (".")){ - output.append(file.substr(0,file.length()-4)); - }else{ - output.append(file.substr(0,file.length()-4)); - } - output.append("_threshold"); - stringstream dt; - dt << threshold; - output.append(dt.str()); - output.append("_scale"); - stringstream ds; - ds << scale; - output.append(ds.str()); - output.append(format); - - cout << "Writing " << output << endl; - - exportImage(srcImageRange(out), output.c_str()); - } - - catch (vigra::StdException & e){ - std::cout << e.what() << std::endl; - } -} - int main(int argc, const char* argv[]){ // Exit with usage unless filename given as argument @@ -108,15 +60,8 @@ usage(); } - unsigned int resize_dimension = 800; - unsigned int i = 1,detector = 0; + unsigned int i = 1; vector<string> images; - string path = ("output/"); - string format = (".jpg"); - - double scale_start = 0.1 ,scale_stop = 25; - double threshold_start = 0, threshold_stop = 10; - double scale_increment = 2, threshold_increment = 1; // Deal with arguments while(i < argc){ @@ -134,8 +79,11 @@ case 'h' : {usage();} case 'p' : {path = argv[i]; break;} case 'f' : {format = argv[i]; break;} - case 'd' : {detector = atoi(argv[i]); break;} - case 's' : {resize_dimension = atoi(argv[i]); break;} + case 'e' : {detector = atoi(argv[i]); break;} + case 'd' : {resize_dimension = atoi(argv[i]); break;} + case 's' : {scale = atof(argv[i]); break;} + case 't' : {threshold = atof(argv[i]); break;} + case 'i' : {generate_images = atoi(argv[i]); break;} } @@ -146,10 +94,20 @@ i++; } + if (!images.size()){ + usage(); + } + cout << endl << "Lens calibration tool" << endl; cout << endl << "Version " << VERSION << endl << endl; - for(i = 0; i < images.size();i++){ + for(i = 0; i < images.size();i++){ + + ifstream ifile(images[i].c_str()); + if (!ifile){ + cout << "File " << images[i] << " doesn't exist." << endl << endl; + exit(1); + } cout << "Processing image " << images[i].c_str() << endl << endl; @@ -200,14 +158,23 @@ copyImage(srcImageRange(in, RGBToGrayAccessor<RGBValue<UInt16> >()), destImage(grey)); //exportImage(srcImageRange(grey), ImageExportInfo("resized.jpg").setPixelType("UINT8")); - for (double threshold = threshold_start; threshold <= threshold_stop; threshold+=threshold_increment){ + // Uncomment this block to generate images at different scales/thresholds + // + //double scale_start = 0.1 ,scale_stop = 25; + //double threshold_start = 0, threshold_stop = 10; + //double scale_increment = 2, threshold_increment = 1; + // + //for (double threshold_test = threshold_start; threshold_test <= threshold_stop; threshold_test += threshold_increment){ + // + // for (double scale_test = scale_start;scale_test <= scale_stop; scale_test += scale_increment){ + // + // detect_edge(grey, images[i], path, format); + // + // } + //} + + detect_edge(grey, images[i], path, format); - for (double scale = scale_start;scale <= scale_stop; scale+=scale_increment){ - - detect_edge(grey, images[i], path, format, detector, threshold, scale, resize_dimension); - - } - } } cout << endl; Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Makefile =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Makefile 2009-05-07 21:37:41 UTC (rev 3834) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Makefile 2009-05-07 23:16:26 UTC (rev 3835) @@ -174,6 +174,21 @@ .PHONY : calibrate_lens/fast # target to build an object file +Globals.o: + cd /home/tnugent/src/gsoc2009_lenscalibration && $(MAKE) -f src/lens_calibrate/CMakeFiles/calibrate_lens.dir/build.make src/lens_calibrate/CMakeFiles/calibrate_lens.dir/Globals.o +.PHONY : Globals.o + +# target to preprocess a source file +Globals.i: + cd /home/tnugent/src/gsoc2009_lenscalibration && $(MAKE) -f src/lens_calibrate/CMakeFiles/calibrate_lens.dir/build.make src/lens_calibrate/CMakeFiles/calibrate_lens.dir/Globals.i +.PHONY : Globals.i + +# target to generate assembly for a file +Globals.s: + cd /home/tnugent/src/gsoc2009_lenscalibration && $(MAKE) -f src/lens_calibrate/CMakeFiles/calibrate_lens.dir/build.make src/lens_calibrate/CMakeFiles/calibrate_lens.dir/Globals.s +.PHONY : Globals.s + +# target to build an object file Main.o: cd /home/tnugent/src/gsoc2009_lenscalibration && $(MAKE) -f src/lens_calibrate/CMakeFiles/calibrate_lens.dir/build.make src/lens_calibrate/CMakeFiles/calibrate_lens.dir/Main.o .PHONY : Main.o @@ -188,6 +203,21 @@ cd /home/tnugent/src/gsoc2009_lenscalibration && $(MAKE) -f src/lens_calibrate/CMakeFiles/calibrate_lens.dir/build.make src/lens_calibrate/CMakeFiles/calibrate_lens.dir/Main.s .PHONY : Main.s +# target to build an object file +ProcessImage.o: + cd /home/tnugent/src/gsoc2009_lenscalibration && $(MAKE) -f src/lens_calibrate/CMakeFiles/calibrate_lens.dir/build.make src/lens_calibrate/CMakeFiles/calibrate_lens.dir/ProcessImage.o +.PHONY : ProcessImage.o + +# target to preprocess a source file +ProcessImage.i: + cd /home/tnugent/src/gsoc2009_lenscalibration && $(MAKE) -f src/lens_calibrate/CMakeFiles/calibrate_lens.dir/build.make src/lens_calibrate/CMakeFiles/calibrate_lens.dir/ProcessImage.i +.PHONY : ProcessImage.i + +# target to generate assembly for a file +ProcessImage.s: + cd /home/tnugent/src/gsoc2009_lenscalibration && $(MAKE) -f src/lens_calibrate/CMakeFiles/calibrate_lens.dir/build.make src/lens_calibrate/CMakeFiles/calibrate_lens.dir/ProcessImage.s +.PHONY : ProcessImage.s + # Help Target help: @echo "The following are some of the valid targets for this Makefile:" @@ -203,9 +233,15 @@ @echo "... package" @echo "... package_source" @echo "... rebuild_cache" + @echo "... Globals.o" + @echo "... Globals.i" + @echo "... Globals.s" @echo "... Main.o" @echo "... Main.i" @echo "... Main.s" + @echo "... ProcessImage.o" + @echo "... ProcessImage.i" + @echo "... ProcessImage.s" .PHONY : help Added: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp (rev 0) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-05-07 23:16:26 UTC (rev 3835) @@ -0,0 +1,207 @@ +/*************************************************************************** + * Copyright (C) 2008 by Tim Nugent * + * tim...@gm... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "vigra/impex.hxx" +#include "vigra/stdimage.hxx" +#include "vigra/edgedetection.hxx" +#include "vigra/stdimagefunctions.hxx" +#include "Globals.h" +#include "ProcessImage.h" + +using namespace vigra; +using namespace std; + +void extract_coords(vigra::BImage& image){ + + for (unsigned int h = 0; h < image.height(); h++){ + for (unsigned int w = 0; w < image.width(); w++){ + + RGBValue<int,0u,1u,2u> value = image(w,h); + if (value[0] != 255){ + cout << "(" << w << "," << h << ")" << endl; + } + } + } + cout << endl; +} + +void sub_image(vigra::BImage& image){ + + unsigned int vertical_slice_width = (double)image.width()/vertical_slices; + unsigned int horizontal_slice_height = (double)image.height()/horizontal_slices; + + //cout << "vertical_slice_width: " << vertical_slice_width << endl; + //cout << "horizontal_slice_height: " << horizontal_slice_height << endl; + + try{ + + cout << "Generate vertical slices..." << endl; + + int sub_y0 = 0; + int sub_y1 = image.height(); + + for (unsigned int i = 0; i <= vertical_slices; i++){ + + int sub_x0 = i * vertical_slice_width; + int sub_x1 = (i+1) * vertical_slice_width; + // Make the slices overlap by 50% + if (i){ + sub_x0 -= (double)vertical_slice_width/2; + sub_x1 -= (double)vertical_slice_width/2; + } + if (sub_x1 > image.width()) sub_x1 = image.width(); + + if (i){ + cout << "Vertical slice " << i << "\t: (" << sub_x0 << "," << sub_y0 << ")\t--->\t("; + cout << sub_x1 << "," << sub_y1 << ")" << endl; + }else{ + cout << "Vertical slice " << i << "\t: (" << sub_x0 << "," << sub_y0 << ")\t\t--->\t("; + cout << sub_x1 << "," << sub_y1 << ")" << endl; + } + + BImage out(sub_x1 - sub_x0, sub_y1 - sub_y0); + // Copy region of interest by moving the input + // iterators to the appropriate positions + copyImage(srcIterRange(image.upperLeft() + vigra::Diff2D(sub_x0, sub_y0), + image.upperLeft() + vigra::Diff2D(sub_x1, sub_y1)), + destImage(out)); + + // Get line coordinates + extract_coords(out); + + if (generate_images){ + // Export slice to file + string output = path; + output.append("vertical_slice_"); + stringstream ii; + ii << i; + output.append(ii.str()); + output.append(".jpg"); + exportImage(srcImageRange(out), output.c_str()); + } + } + + int sub_x0 = 0; + int sub_x1 = image.width(); + + cout << endl << "Generate horiztonal slices..." << endl; + + for (unsigned int i = 0; i <= horizontal_slices; i++){ + + int sub_y0 = i * horizontal_slice_height; + int sub_y1 = (i+1) * horizontal_slice_height; + // Make the slices overlap by 50% + if (i){ + sub_y0 -= (double)horizontal_slice_height/2; + sub_y1 -= (double)horizontal_slice_height/2; + } + if (sub_y1 > image.height()) sub_y1 = image.height(); + + if (i){ + cout << "Horizontal slice " << i << "\t: (" << sub_x0 << "," << sub_y0 << ")\t--->\t("; + cout << sub_x1 << "," << sub_y1 << ")" << endl; + }else{ + cout << "Horizontal slice " << i << "\t: (" << sub_x0 << "," << sub_y0 << ")\t\t--->\t("; + cout << sub_x1 << "," << sub_y1 << ")" << endl; + } + + BImage out(sub_x1 - sub_x0, sub_y1 - sub_y0); + // Copy region of interest by moving the input + // iterators to the appropriate positions + copyImage(srcIterRange(image.upperLeft() + vigra::Diff2D(sub_x0, sub_y0), + image.upperLeft() + vigra::Diff2D(sub_x1, sub_y1)), + destImage(out)); + + // Get line coordinates + extract_coords(out); + + if (generate_images){ + //Export slice to file + string output = path; + output.append("horizontal_slice_"); + stringstream ii; + ii << i; + output.append(ii.str()); + output.append(".jpg"); + exportImage(srcImageRange(out), output.c_str()); + } + } + } + + catch (vigra::StdException & e){ + std::cout << e.what() << std::endl; + } + +} + +void detect_edge(vigra::BImage& image, string& file, string& path, string& format){ + + try{ + + // Paint output image white + vigra::BImage out(image.width(), image.height()); + //cout << image.width() << " x " << image.height() << endl; + out = 255; + + if(detector){ + + // Call Shen-Castan detector algorithm + differenceOfExponentialEdgeImage(srcImageRange(image), destImage(out), + scale, threshold, 0); + }else{ + + // Call Canny detector algorithm + cannyEdgeImage(srcImageRange(image), destImage(out), + scale, threshold, 0); + } + + if (generate_images){ + + // Create output file name + string output = path; + + if (file.substr(file.length()-4,1) == (".")){ + output.append(file.substr(0,file.length()-4)); + }else{ + output.append(file.substr(0,file.length()-4)); + } + output.append("_threshold"); + stringstream dt; + dt << threshold; + output.append(dt.str()); + output.append("_scale"); + stringstream ds; + ds << scale; + output.append(ds.str()); + output.append(format); + + cout << "Writing " << output << endl << endl; + exportImage(srcImageRange(out), output.c_str()); + } + + // Slice image + sub_image(out); + + } + + catch (vigra::StdException & e){ + std::cout << e.what() << std::endl; + } +} Added: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h (rev 0) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h 2009-05-07 23:16:26 UTC (rev 3835) @@ -0,0 +1,10 @@ +#ifndef PROCESSIMAGE_H +#define PROCESSIMAGE_H + +#include "vigra/impex.hxx" + +void extract_coords(vigra::BImage&); +void sub_image(vigra::BImage& image); +void detect_edge(vigra::BImage&, std::string&, std::string&, std::string&); + +#endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bl...@us...> - 2009-05-08 13:57:51
|
Revision: 3838 http://hugin.svn.sourceforge.net/hugin/?rev=3838&view=rev Author: blimbo Date: 2009-05-08 13:57:49 +0000 (Fri, 08 May 2009) Log Message: ----------- Got rid of some warnings, moved some functions out of Main.cpp, put coords in a vector ready for RANSAC Modified Paths: -------------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt 2009-05-08 05:28:03 UTC (rev 3837) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt 2009-05-08 13:57:49 UTC (rev 3838) @@ -1,3 +1,9 @@ -ADD_EXECUTABLE(calibrate_lens Main.cpp Globals.cpp ProcessImage.cpp ) +ADD_EXECUTABLE(calibrate_lens +Main.cpp +Globals.cpp +ProcessImage.cpp +) + TARGET_LINK_LIBRARIES( calibrate_lens ${image_libs} ) + INSTALL(TARGETS calibrate_lens DESTINATION ${BINDIR}) Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp 2009-05-08 05:28:03 UTC (rev 3837) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp 2009-05-08 13:57:49 UTC (rev 3838) @@ -18,17 +18,12 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#include <stdio.h> #include <fstream> -#include <iostream> -#include <sstream> #include <vector> #include <string> -#include "vigra/stdimagefunctions.hxx" #include "Globals.h" #include "ProcessImage.h" -using namespace vigra; using namespace std; #define VERSION 0.1 @@ -108,72 +103,8 @@ cout << "File " << images[i] << " doesn't exist." << endl << endl; exit(1); } - cout << "Processing image " << images[i].c_str() << endl << endl; - - vigra::ImageImportInfo info(images[i].c_str()); - - vigra::UInt16RGBImage in(info.width(), info.height()); - - importImage(info, destImage(in)); - - double sizefactor = 1; - int nw = info.width(), nh = info.height(); - - // Re-size to max dimension - if (info.width() > resize_dimension || info.height() > resize_dimension){ - - if (info.width() >= info.height()){ - - sizefactor = (double)resize_dimension/info.width(); - // calculate new image size - nw = resize_dimension; - nh = static_cast<int>(0.5 + (sizefactor*info.height())); - - }else{ - sizefactor = (double)resize_dimension/info.height(); - // calculate new image size - nw = static_cast<int>(0.5 + (sizefactor*info.width())); - nh = resize_dimension; - - } - - cout << "Scaling by:\t\t" << sizefactor << endl; - cout << "New dimensions:\t\t" << nw << " x " << nh << endl << endl; - - // create an image of appropriate size - vigra::UInt16RGBImage out(nw, nh); - - // resize the image, using a bi-cubic spline algorithm - resizeImageNoInterpolation(srcImageRange(in),destImageRange(out)); - - in = out; - - //exportImage(srcImageRange(in), ImageExportInfo("resized.jpg").setPixelType("UINT8")); - //exportImage(srcImageRange(in), ImageExportInfo("resized.tif").setPixelType("UINT16")); - - } - - BImage grey(nw, nh); - copyImage(srcImageRange(in, RGBToGrayAccessor<RGBValue<UInt16> >()), destImage(grey)); - //exportImage(srcImageRange(grey), ImageExportInfo("resized.jpg").setPixelType("UINT8")); - - // Uncomment this block to generate images at different scales/thresholds - // - //double scale_start = 0.1 ,scale_stop = 25; - //double threshold_start = 0, threshold_stop = 10; - //double scale_increment = 2, threshold_increment = 1; - // - //for (double threshold_test = threshold_start; threshold_test <= threshold_stop; threshold_test += threshold_increment){ - // - // for (double scale_test = scale_start;scale_test <= scale_stop; scale_test += scale_increment){ - // - // detect_edge(grey, images[i], path, format); - // - // } - //} - - detect_edge(grey, images[i], path, format); + process_image(images[i]); } Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-05-08 05:28:03 UTC (rev 3837) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-05-08 13:57:49 UTC (rev 3838) @@ -22,30 +22,60 @@ #include "vigra/stdimage.hxx" #include "vigra/edgedetection.hxx" #include "vigra/stdimagefunctions.hxx" +#include "vigra/diff2d.hxx" #include "Globals.h" #include "ProcessImage.h" +#include "vigra_ext/ransac.h" +#include "vigra_ext/RansacParameterEstimator.h" using namespace vigra; using namespace std; -void extract_coords(vigra::BImage& image){ +void ransac(vector<Point2D>& coords){ + cout << coords.size() << " 'edge' coordinates found." << endl; + + //vector<double> parameters; + //unsigned int minElements = 10; + //RansacParameterEstimator estimator(minElements); + //double desiredProbabilityForNoOutliers = 0.9; + //double maximalOutlierPercentage = 0.1; + //Ransac::compute(parameters, estimator, coords, desiredProbabilityForNoOutliers, maximalOutlierPercentage); + //Ransac::compute(S & parameters, const Estimator & paramEstimator, coords, desiredProbabilityForNoOutliers, maximalOutlierPercentage); + +} + +void extract_coords(BImage& image){ + + //vector< pair<int,int> > coords; + vector<Point2D> coords; + + // Gather black pixels for (unsigned int h = 0; h < image.height(); h++){ for (unsigned int w = 0; w < image.width(); w++){ RGBValue<int,0u,1u,2u> value = image(w,h); if (value[0] != 255){ - cout << "(" << w << "," << h << ")" << endl; + + // Do we need to invert h, since 0 is at the top, but for + // RANSAC/line fitting 0 will be at the bottom? + //coords.push_back(make_pair(w,h)); + + coords.push_back(Point2D (w,h)); + + //cout << "(" << w << "," << h << ")" << endl; } } } - cout << endl; + + ransac(coords); + } -void sub_image(vigra::BImage& image){ +void sub_image(BImage& image){ - unsigned int vertical_slice_width = (double)image.width()/vertical_slices; - unsigned int horizontal_slice_height = (double)image.height()/horizontal_slices; + unsigned int vertical_slice_width = image.width()/vertical_slices; + unsigned int horizontal_slice_height = image.height()/horizontal_slices; //cout << "vertical_slice_width: " << vertical_slice_width << endl; //cout << "horizontal_slice_height: " << horizontal_slice_height << endl; @@ -54,8 +84,8 @@ cout << "Generate vertical slices..." << endl; - int sub_y0 = 0; - int sub_y1 = image.height(); + unsigned int sub_y0 = 0; + unsigned int sub_y1 = image.height(); for (unsigned int i = 0; i <= vertical_slices; i++){ @@ -63,8 +93,8 @@ int sub_x1 = (i+1) * vertical_slice_width; // Make the slices overlap by 50% if (i){ - sub_x0 -= (double)vertical_slice_width/2; - sub_x1 -= (double)vertical_slice_width/2; + sub_x0 -= vertical_slice_width/2; + sub_x1 -= vertical_slice_width/2; } if (sub_x1 > image.width()) sub_x1 = image.width(); @@ -79,8 +109,8 @@ BImage out(sub_x1 - sub_x0, sub_y1 - sub_y0); // Copy region of interest by moving the input // iterators to the appropriate positions - copyImage(srcIterRange(image.upperLeft() + vigra::Diff2D(sub_x0, sub_y0), - image.upperLeft() + vigra::Diff2D(sub_x1, sub_y1)), + copyImage(srcIterRange(image.upperLeft() + Diff2D(sub_x0, sub_y0), + image.upperLeft() + Diff2D(sub_x1, sub_y1)), destImage(out)); // Get line coordinates @@ -98,8 +128,8 @@ } } - int sub_x0 = 0; - int sub_x1 = image.width(); + unsigned int sub_x0 = 0; + unsigned int sub_x1 = image.width(); cout << endl << "Generate horiztonal slices..." << endl; @@ -109,8 +139,8 @@ int sub_y1 = (i+1) * horizontal_slice_height; // Make the slices overlap by 50% if (i){ - sub_y0 -= (double)horizontal_slice_height/2; - sub_y1 -= (double)horizontal_slice_height/2; + sub_y0 -= horizontal_slice_height/2; + sub_y1 -= horizontal_slice_height/2; } if (sub_y1 > image.height()) sub_y1 = image.height(); @@ -125,8 +155,8 @@ BImage out(sub_x1 - sub_x0, sub_y1 - sub_y0); // Copy region of interest by moving the input // iterators to the appropriate positions - copyImage(srcIterRange(image.upperLeft() + vigra::Diff2D(sub_x0, sub_y0), - image.upperLeft() + vigra::Diff2D(sub_x1, sub_y1)), + copyImage(srcIterRange(image.upperLeft() + Diff2D(sub_x0, sub_y0), + image.upperLeft() + Diff2D(sub_x1, sub_y1)), destImage(out)); // Get line coordinates @@ -145,18 +175,18 @@ } } - catch (vigra::StdException & e){ - std::cout << e.what() << std::endl; + catch (StdException & e){ + cout << e.what() << endl; } } -void detect_edge(vigra::BImage& image, string& file, string& path, string& format){ +void detect_edge(BImage& image, string& file, string& path, string& format){ try{ // Paint output image white - vigra::BImage out(image.width(), image.height()); + BImage out(image.width(), image.height()); //cout << image.width() << " x " << image.height() << endl; out = 255; @@ -201,7 +231,76 @@ } - catch (vigra::StdException & e){ - std::cout << e.what() << std::endl; + catch (StdException & e){ + cout << e.what() << endl; } } + +void process_image(string& filename){ + + ImageImportInfo info(filename.c_str()); + + UInt16RGBImage in(info.width(), info.height()); + + importImage(info, destImage(in)); + + double sizefactor = 1; + int nw = info.width(), nh = info.height(); + + // Re-size to max dimension + if (info.width() > resize_dimension || info.height() > resize_dimension){ + + if (info.width() >= info.height()){ + + sizefactor = (double)resize_dimension/info.width(); + // calculate new image size + nw = resize_dimension; + nh = static_cast<int>(0.5 + (sizefactor*info.height())); + + }else{ + sizefactor = (double)resize_dimension/info.height(); + // calculate new image size + nw = static_cast<int>(0.5 + (sizefactor*info.width())); + nh = resize_dimension; + + } + + cout << "Scaling by:\t\t" << sizefactor << endl; + cout << "New dimensions:\t\t" << nw << " x " << nh << endl << endl; + + // create an image of appropriate size + UInt16RGBImage out(nw, nh); + + // resize the image, using a bi-cubic spline algorithm + resizeImageNoInterpolation(srcImageRange(in),destImageRange(out)); + + in = out; + + //exportImage(srcImageRange(in), ImageExportInfo("resized.jpg").setPixelType("UINT8")); + //exportImage(srcImageRange(in), ImageExportInfo("resized.tif").setPixelType("UINT16")); + + } + + // Convert to greyscale + BImage grey(nw, nh); + copyImage(srcImageRange(in, RGBToGrayAccessor<RGBValue<UInt16> >()), destImage(grey)); + //exportImage(srcImageRange(grey), ImageExportInfo("resized.jpg").setPixelType("UINT8")); + + // Uncomment this block to generate images at different scales/thresholds + // + //double scale_start = 0.1 ,scale_stop = 25; + //double threshold_start = 0, threshold_stop = 10; + //double scale_increment = 2, threshold_increment = 1; + // + //for (double threshold_test = threshold_start; threshold_test <= threshold_stop; threshold_test += threshold_increment){ + // + // for (double scale_test = scale_start;scale_test <= scale_stop; scale_test += scale_increment){ + // + // detect_edge(grey, images[i], path, format); + // + // } + //} + + detect_edge(grey, filename, path, format); + +} Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h 2009-05-08 05:28:03 UTC (rev 3837) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h 2009-05-08 13:57:49 UTC (rev 3838) @@ -2,9 +2,12 @@ #define PROCESSIMAGE_H #include "vigra/impex.hxx" +#include "vigra/diff2d.hxx" +void ransac(std::vector<vigra::Point2D>&); void extract_coords(vigra::BImage&); void sub_image(vigra::BImage& image); void detect_edge(vigra::BImage&, std::string&, std::string&, std::string&); +void process_image(std::string&); #endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bl...@us...> - 2009-05-11 17:03:08
|
Revision: 3846 http://hugin.svn.sourceforge.net/hugin/?rev=3846&view=rev Author: blimbo Date: 2009-05-11 17:03:05 +0000 (Mon, 11 May 2009) Log Message: ----------- Ransac functions added, but line estimator code needs to be replaced with a curve estimator Modified Paths: -------------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp Added Paths: ----------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.h hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Ransac.h Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt 2009-05-10 14:57:32 UTC (rev 3845) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt 2009-05-11 17:03:05 UTC (rev 3846) @@ -1,7 +1,10 @@ ADD_EXECUTABLE(calibrate_lens Main.cpp Globals.cpp +ParameterEstimator.cpp +ParameterEstimator.h ProcessImage.cpp +Ransac.h ) TARGET_LINK_LIBRARIES( calibrate_lens ${image_libs} ) Added: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp (rev 0) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp 2009-05-11 17:03:05 UTC (rev 3846) @@ -0,0 +1,104 @@ +#include <math.h> +#include "ParameterEstimator.h" +#include <iostream> +#include "vigra/diff2d.hxx" + +ParameterEstimator::ParameterEstimator(double delta){ + minForEstimate = 3; +} + +bool ParameterEstimator::estimate(std::vector<const vigra::Point2D *> &data, std::vector<double> ¶meters){ + + parameters.clear(); + if(data.size()<this->minForEstimate) + return(0); + double nx = data[1]->y - data[0]->y; + double ny = data[0]->x - data[1]->x; + double norm = sqrt(nx*nx + ny*ny); + + parameters.push_back(nx/norm); + parameters.push_back(ny/norm); + parameters.push_back(data[0]->x); + parameters.push_back(data[0]->y); + + //for (unsigned i = 0; i < parameters.size(); i++){ + // std::cout << "RANSAC curve parameter: " << i << " " << parameters[i] << std::endl; + //} + + return(1); +} +/*****************************************************************************/ +/* + * Compute the line parameters [n_x,n_y,a_x,a_y] + */ +void ParameterEstimator::leastSquaresEstimate(std::vector<const vigra::Point2D *> &data, std::vector<double> ¶meters) +{ + + //std::cout << "leastSquaresEstimate" << std::endl; + + double meanX, meanY, nx, ny, norm; + double covMat11, covMat12, covMat21, covMat22; // The entries of the symmetric covarinace matrix + int i, dataSize = data.size(); + + parameters.clear(); + if(data.size()<this->minForEstimate) + return; + + meanX = meanY = 0.0; + covMat11 = covMat12 = covMat21 = covMat22 = 0; + for(i=0; i<dataSize; i++) { + meanX +=data[i]->x; + meanY +=data[i]->y; + + covMat11 +=data[i]->x * data[i]->x; + covMat12 +=data[i]->x * data[i]->y; + covMat22 +=data[i]->y * data[i]->y; + } + + meanX/=dataSize; + meanY/=dataSize; + + covMat11 -= dataSize*meanX*meanX; + covMat12 -= dataSize*meanX*meanY; + covMat22 -= dataSize*meanY*meanY; + covMat21 = covMat12; + + if(covMat11<1e-12) { + nx = 1.0; + ny = 0.0; + } + else { //lamda1 is the largest eigen-value of the covariance matrix + //and is used to compute the eigne-vector corresponding to the smallest + //eigenvalue, which isn't computed explicitly. + double lamda1 = (covMat11 + covMat22 + sqrt((covMat11-covMat22)*(covMat11-covMat22) + 4*covMat12*covMat12)) / 2.0; + nx = -covMat12; + ny = lamda1 - covMat22; + norm = sqrt(nx*nx + ny*ny); + nx/=norm; + ny/=norm; + } + parameters.push_back(nx); + parameters.push_back(ny); + parameters.push_back(meanX); + parameters.push_back(meanY); +} +/*****************************************************************************/ +/* + * Given the line parameters [n_x,n_y,a_x,a_y] check if + * [n_x, n_y] dot [data.x-a_x, data.y-a_y] < m_delta + */ +bool ParameterEstimator::agree(std::vector<double> ¶meters, const vigra::Point2D &data){ + + //for (unsigned i = 0; i < parameters.size(); i++){ + // std::cout << "param " << parameters[i] << std::endl; + //} + //std::cout << "x = " << data.x << " y = " << data.y << std::endl; + + double signedDistance = parameters[0]*(data.x-parameters[2]) + parameters[1]*(data.y-parameters[3]); + + return ((signedDistance*signedDistance) < this->deltaSquared); + +} +/*****************************************************************************/ + + Added: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.h (rev 0) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.h 2009-05-11 17:03:05 UTC (rev 3846) @@ -0,0 +1,66 @@ +#ifndef _PARAMETER_ESTIMATOR_H_ +#define _PARAMETER_ESTIMATOR_H_ + +#include <vector> +#include <iostream> +#include "vigra/diff2d.hxx" + +/** + * This class defines the interface for parameter estimators. + * Classes which inherit from it can be used by the Ransac class to perform robust + * parameter estimation. + * The interface includes three methods: + * 1.estimate() - Estimation of the parameters using the minimal + * amount of data (exact estimate). + * 2.leastSquaresEstimate() - Estimation of the parameters using + * overdetermined data, so that the estimate + * minimizes a least squres error criteria. + * 3.agree() - Does the given data agree with the model parameters. + * + * Author: Ziv Yaniv + */ + +class ParameterEstimator { +public: + + /** + * Constructor which takes the number of data objects required for an exact + * estimate (e.g. 2 for a line where the data objects are points + */ + ParameterEstimator(double delta); + + /** + * Exact estimation of parameters. + * @param data The data used for the estimate. + * @param parameters This vector is cleared and then filled with the computed parameters. + */ + virtual bool estimate(std::vector<const vigra::Point2D *> &data, std::vector<double> ¶meters); + + /** + * Least squares estimation of parameters. + * @param data The data used for the estimate. + * @param parameters This vector is cleared and then filled with the computed parameters. + */ + virtual void leastSquaresEstimate(std::vector<const vigra::Point2D *> &data, std::vector<double> ¶meters); + + /** + * This method tests if the given data agrees with the given model parameters. + */ + virtual bool agree(std::vector<double> ¶meters, const vigra::Point2D &data); + + static void debugTest(std::ostream &out); + + /** + * Returns the number of data objects required for an exact + * estimate (e.g. 2 for a line where the data objects are points) + */ + unsigned int numForEstimate() const {return minForEstimate;} +protected: + unsigned int minForEstimate; + +private: + double deltaSquared; //given line L and point P, if dist(L,P)^2 < m_delta^2 then the point is on the line + +}; + +#endif //_PARAMETER_ESTIMATOR_H_ Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-05-10 14:57:32 UTC (rev 3845) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-05-11 17:03:05 UTC (rev 3846) @@ -25,8 +25,8 @@ #include "vigra/diff2d.hxx" #include "Globals.h" #include "ProcessImage.h" -#include "vigra_ext/ransac.h" -#include "vigra_ext/RansacParameterEstimator.h" +#include "Ransac.h" +#include "ParameterEstimator.h" using namespace vigra; using namespace std; @@ -35,14 +35,33 @@ cout << coords.size() << " 'edge' coordinates found." << endl; - //vector<double> parameters; - //unsigned int minElements = 10; - //RansacParameterEstimator estimator(minElements); - //double desiredProbabilityForNoOutliers = 0.9; - //double maximalOutlierPercentage = 0.1; - //Ransac::compute(parameters, estimator, coords, desiredProbabilityForNoOutliers, maximalOutlierPercentage); - //Ransac::compute(S & parameters, const Estimator & paramEstimator, coords, desiredProbabilityForNoOutliers, maximalOutlierPercentage); + vector<double> curveParameters; + int numSamples = 20; + int numOutliers = 80; + double desiredProbabilityForNoOutliers = 0.9; + double maximalOutlierPercentage = 0.1 + (double)numOutliers/(double)(numSamples + numOutliers); + //for a point to be on the line it has to be closer than 0.5 units from the line + ParameterEstimator curveEstimator(0.5); + + cout << endl << "Computing RANSAC..." << endl; + double usedData = Ransac::compute(curveParameters, &curveEstimator, coords, desiredProbabilityForNoOutliers, maximalOutlierPercentage); + + for (unsigned i = 0; i < curveParameters.size(); i++){ + cout << "RANSAC curve parameter: " << curveParameters[i] << endl; + } + + cout << endl << "Percentage of points which were used for final estimate: "<< usedData << endl << endl; + + //for (unsigned i = 0; i < coords.size(); i++){ + // double dotProd = curveParameters[0]*(-coords[i].y) + curveParameters[1]*coords[i].x; + // cout << "(" << coords[i].x << "," << coords[i].y << ") ---> " << dotProd << endl; + //} + //exit(1); + + //cout<<"RANSAC line parameters [n_x,n_y,a_x,a_y]\n\t [ "<<curveParameters[0]<<", "<<curveParameters[1]<<", "; + //cout<<curveParameters[2]<<", "<<curveParameters[3]<<" ]"<<endl; + } void extract_coords(BImage& image){ @@ -61,8 +80,8 @@ // RANSAC/line fitting 0 will be at the bottom? //coords.push_back(make_pair(w,h)); - coords.push_back(Point2D (w,h)); - + coords.push_back(Point2D(w,h)); + //cout << "(" << w << "," << h << ")" << endl; } } @@ -296,7 +315,7 @@ // // for (double scale_test = scale_start;scale_test <= scale_stop; scale_test += scale_increment){ // - // detect_edge(grey, images[i], path, format); + // detect_edge(grey, filename, path, format); // // } //} Added: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Ransac.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Ransac.h (rev 0) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Ransac.h 2009-05-11 17:03:05 UTC (rev 3846) @@ -0,0 +1,443 @@ +// -*- c-basic-offset: 4 -*- +/** @file RemappedPanoImage.h + * + * Generic implementation of the RanSaC algorithm. + * + * @author Ziv Yaniv + * + * Some minor changes by Pablo d'Angelo <pab...@we...> + * + * $Id: ransac.h 2894 2008-02-18 22:22:26Z brunopostle $ + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef _RANSAC_H_ +#define _RANSAC_H_ + +#include <set> +#include <vector> +#include <stdlib.h> +#include <cstring> +#include <math.h> +#include <ctime> + +#include <boost/random/mersenne_twister.hpp> +#include <boost/random/uniform_int.hpp> +#include <boost/random/variate_generator.hpp> +#include "ParameterEstimator.h" + +using namespace std; + + +/** + * This class implements the Random Sample Consensus (RanSac) framework, + * a framework for robust parameter estimation. + * Given data containing outliers we estimate the model parameters using sub-sets of + * the original data: + * 1. Choose the minimal subset from the data for computing the exact model parameters. + * 2. See how much of the input data agrees with the computed parameters. + * 3. Goto step 1. This can be done up to (m choose N) times, where m is the number of + * data objects required for an exact estimate and N is the total number of data objects. + * 4. Take the largest subset of objects which agreed on the parameters and compute a + * least squares fit using them. + * + * This is based on: + * Fischler M.A., Bolles R.C., + * ``Random Sample Consensus: A Paradigm for Model Fitting with Applications to Image Analysis and Automated Cartography'', + * Communications of the ACM, Vol. 24(6), 1981. + * + * Hartely R., Zisserman A., "Multiple View Geometry in Computer Vision" + * + * The class template parameters are T - objects used for the parameter estimation + * (e.g. Point2D in line estimation, + * std::pair<Point2D,Point2D> in homography estimation). + * S - type of parameters (e.g. std::vector<double>). + * + * Author: Ziv Yaniv + * + * Small modifications by Pablo d'Angelo: + * * allow arbitrary parameters, not just vector<S> + */ +class Ransac { + +public: + /** + * Estimate the model parameters using the RanSac framework. + * @param parameters A vector which will contain the estimated parameters. + * If there is an error in the input then this vector will be empty. + * Errors are: 1. Less data objects than required for an exact fit. + * 2. The given data is in a singular configuration (e.g. trying to fit a circle + * to a set of colinear points). + * @param paramEstimator An object which can estimate the desired parameters using either an exact fit or a + * least squares fit. + * @param data The input from which the parameters will be estimated. + * @param numForEstimate The number of data objects required for an exact fit. + * @param desiredProbabilityForNoOutliers The probability that at least one of the selected subsets doesn't contains an + * outlier. + * @param maximalOutlierPercentage The maximal expected percentage of outliers. + * @return Returns the percentage of data used in the least squares estimate. + */ + template<class Estimator, class S, class T> + static int compute(S & parameters, + const Estimator & paramEstimator , + const std::vector<T> &data, + double desiredProbabilityForNoOutliers, + double maximalOutlierPercentage); + + + /** + * Estimate the model parameters using the maximal consensus set by going over ALL possible + * subsets (brute force approach). + * Given: n - data.size() + * k - numForEstimate + * We go over all n choose k subsets n! + * ------------ + * (n-k)! * k! + * @param parameters A vector which will contain the estimated parameters. + * If there is an error in the input then this vector will be empty. + * Errors are: 1. Less data objects than required for an exact fit. + * 2. The given data is in a singular configuration (e.g. trying to fit a circle + * to a set of colinear points). + * @param paramEstimator An object which can estimate the desired parameters using either an exact fit or a + * least squares fit. + * @param data The input from which the parameters will be estimated. + * @param numForEstimate The number of data objects required for an exact fit. + * @return Returns the percentage of data used in the least squares estimate. + * + * NOTE: This method should be used only when n choose k is small (i.e. k or (n-k) are approximatly equal to n) + * + */ + template<class Estimator, class S, class T> + static int compute(S ¶meters, + const Estimator & paramEstimator , + const std::vector<T> &data); + +private: + + /** + * Compute n choose m [ n!/(m!*(n-m)!)] + */ + static unsigned int choose(unsigned int n, unsigned int m); + + template<class Estimator, class T> + static void computeAllChoices(const Estimator & paramEstimator, + const std::vector<T> &data, + int numForEstimate, + short *bestVotes, short *curVotes, + int &numVotesForBest, int startIndex, + int n, int k, int arrIndex, int *arr); + + + template<class Estimator, class T, class S> + static void estimate(const Estimator & paramEstimator, const std::vector<T> &data, + int numForEstimate, + short *bestVotes, short *curVotes, + int &numVotesForBest, int *arr); + + class SubSetIndexComparator + { + private: + int m_length; + public: + SubSetIndexComparator(int arrayLength) : m_length(arrayLength) + {} + + bool operator()(const int *arr1, const int *arr2) const + { + for(int i=0; i<m_length; i++) + if(arr1[i] < arr2[i]) + return true; + return false; + } + }; + +}; + + +/*******************************RanSac Implementation*************************/ + +template<class Estimator, class S, class T> +int Ransac::compute(S ¶meters, + const Estimator & paramEstimator, + const std::vector<T> &data, + double desiredProbabilityForNoOutliers, + double maximalOutlierPercentage) +{ + + //for (unsigned i = 0; i < data.size(); i++){ + // std::cout << data[i]->x << "," << data[i]->y << std::endl; + //} + + + unsigned int numDataObjects = (int) data.size(); + unsigned int numForEstimate = paramEstimator->numForEstimate(); + + //there are less data objects than the minimum required for an exact fit, or + //all the data is outliers? + if(numDataObjects < numForEstimate || maximalOutlierPercentage>=1.0){ + cout << "Less data objects than the minimum required for an exact fit" << endl; + cout << "numDataObjects = " << numDataObjects << " < numForEstimate = " << numForEstimate << endl; + cout << "or maximalOutlierPercentage = " << maximalOutlierPercentage << " >= 1.0" << endl; + return 0; + } + + std::vector<const T *> exactEstimateData; + std::vector<const T *> leastSquaresEstimateData; + S exactEstimateParameters; + int i, j, k, l, numVotesForBest, numVotesForCur, maxIndex, numTries; + short *bestVotes = new short[numDataObjects]; //one if data[i] agrees with the best model, otherwise zero + short *curVotes = new short[numDataObjects]; //one if data[i] agrees with the current model, otherwise zero + short *notChosen = new short[numDataObjects]; //not zero if data[i] is NOT chosen for computing the exact fit, otherwise zero + SubSetIndexComparator subSetIndexComparator(numForEstimate); + std::set<int *, SubSetIndexComparator > chosenSubSets(subSetIndexComparator); + int *curSubSetIndexes; + double outlierPercentage = maximalOutlierPercentage; + double numerator = log(1.0-desiredProbabilityForNoOutliers); + double denominator = log(1- pow((double)(1.0-maximalOutlierPercentage), (double)(numForEstimate))); + int allTries = choose(numDataObjects,numForEstimate); + + numVotesForBest = 0; //initalize with 0 so that the first computation which gives any type of fit will be set to best + + // intialize random generator + boost::mt19937 rng; + // start with a different seed every time. + rng.seed(static_cast<unsigned int>(std::time(0))); + // randomly sample points. + maxIndex = numDataObjects-1; + boost::uniform_int<> distribIndex(0, maxIndex); + boost::variate_generator<boost::mt19937&, boost::uniform_int<> > + randIndex(rng, distribIndex); // glues randomness with mapping + +// srand((unsigned)time(NULL)); //seed random number generator + numTries = (int)(numerator/denominator + 0.5); + + //there are cases when the probablistic number of tries is greater than all possible sub-sets + numTries = numTries<allTries ? numTries : allTries; + + for(i=0; i<numTries; i++) { + + //std::cout << "Try " << i << std::endl; + + //randomly select data for exact model fit ('numForEstimate' objects). + memset(notChosen,'1',numDataObjects*sizeof(short)); + curSubSetIndexes = new int[numForEstimate]; + + exactEstimateData.clear(); + + maxIndex = numDataObjects-1; + for(l=0; l<(int)numForEstimate; l++) { + //selectedIndex is in [0,maxIndex] + unsigned int selectedIndex = randIndex(); +// unsigned int selectedIndex = (unsigned int)(((float)rand()/(float)RAND_MAX)*maxIndex + 0.5); + for(j=-1,k=0; k<(int)numDataObjects && j<(int)selectedIndex; k++) { + if(notChosen[k]) + j++; + } + k--; + exactEstimateData.push_back(&(data[k])); + notChosen[k] = 0; + maxIndex--; + } + //get the indexes of the chosen objects so we can check that this sub-set hasn't been + //chosen already + for(l=0, j=0; j<(int)numDataObjects; j++) { + if(!notChosen[j]) { + curSubSetIndexes[l] = j+1; + l++; + } + } + + //check that the sub set just chosen is unique + std::pair< std::set<int *, SubSetIndexComparator >::iterator, bool > res = chosenSubSets.insert(curSubSetIndexes); + + if(res.second == true) { //first time we chose this sub set + //use the selected data for an exact model parameter fit + if (!paramEstimator->estimate(exactEstimateData,exactEstimateParameters)) + //selected data is a singular configuration (e.g. three colinear points for + //a circle fit) + continue; + //see how many agree on this estimate + numVotesForCur = 0; + memset(curVotes,'\0',numDataObjects*sizeof(short)); + for(j=0; j<(int)numDataObjects; j++) { + if(paramEstimator->agree(exactEstimateParameters, data[j])) { + curVotes[j] = 1; + numVotesForCur++; + } + } + if(numVotesForCur > numVotesForBest) { + numVotesForBest = numVotesForCur; + memcpy(bestVotes,curVotes, numDataObjects*sizeof(short)); + } + //update the estimate of outliers and the number of iterations we need + outlierPercentage = 1 - (double)numVotesForCur/(double)numDataObjects; + if(outlierPercentage < maximalOutlierPercentage) { + maximalOutlierPercentage = outlierPercentage; + denominator = log(1- pow((double)(1.0-maximalOutlierPercentage), (double)(numForEstimate))); + numTries = (int)(numerator/denominator + 0.5); + //there are cases when the probablistic number of tries is greater than all possible sub-sets + numTries = numTries<allTries ? numTries : allTries; + } + } + else { //this sub set already appeared, don't count this iteration + delete [] curSubSetIndexes; + i--; + } + } + + //release the memory + std::set<int *, SubSetIndexComparator >::iterator it = chosenSubSets.begin(); + std::set<int *, SubSetIndexComparator >::iterator chosenSubSetsEnd = chosenSubSets.end(); + while(it!=chosenSubSetsEnd) { + delete [] (*it); + it++; + } + chosenSubSets.clear(); + + //compute the least squares estimate using the largest sub set + if(numVotesForBest > 0) { + for(j=0; j<(int)numDataObjects; j++) { + if(bestVotes[j]) + leastSquaresEstimateData.push_back(&(data[j])); + } + paramEstimator->leastSquaresEstimate(leastSquaresEstimateData,parameters); + } + delete [] bestVotes; + delete [] curVotes; + delete [] notChosen; + + return numVotesForBest; + +} +/*****************************************************************************/ +template<class Estimator, class S, class T> +int Ransac::compute(S ¶meters, + const Estimator & paramEstimator, + const std::vector<T> &data) +{ + unsigned int numForEstimate = paramEstimator->numForEstimate(); + std::vector<T *> leastSquaresEstimateData; + int numDataObjects = data.size(); + int numVotesForBest = 0; + int *arr = new int[numForEstimate]; + short *curVotes = new short[numDataObjects]; //one if data[i] agrees with the current model, otherwise zero + short *bestVotes = new short[numDataObjects]; //one if data[i] agrees with the best model, otherwise zero + + //parameters.clear(); + + //there are less data objects than the minimum required for an exact fit + if(numDataObjects < numForEstimate) + return 0; + + computeAllChoices(paramEstimator,data,numForEstimate, + bestVotes, curVotes, numVotesForBest, 0, data.size(), numForEstimate, 0, arr); + + //compute the least squares estimate using the largest sub set + if(numVotesForBest > 0) { + for(int j=0; j<numDataObjects; j++) { + if(bestVotes[j]) + leastSquaresEstimateData.push_back(&(data[j])); + } + paramEstimator->leastSquaresEstimate(leastSquaresEstimateData,parameters); + } + + delete [] arr; + delete [] bestVotes; + delete [] curVotes; + + return numVotesForBest; +} +/*****************************************************************************/ +template<class Estimator, class T> +void Ransac::computeAllChoices(const Estimator ¶mEstimator, const std::vector<T> &data, + int numForEstimate,short *bestVotes, short *curVotes, + int &numVotesForBest, int startIndex, int n, int k, + int arrIndex, int *arr) +{ + //we have a new choice of indexes + if(k==0) { + estimate(paramEstimator, data, numForEstimate, bestVotes, curVotes, numVotesForBest, arr); + return; + } + + //continue to recursivly generate the choice of indexes + int endIndex = n-k; + for(int i=startIndex; i<=endIndex; i++) { + arr[arrIndex] = i; + computeAllChoices(paramEstimator, data, numForEstimate, bestVotes, curVotes, numVotesForBest, + i+1, n, k-1, arrIndex+1, arr); + } + +} +/*****************************************************************************/ +template<class Estimator, class T, class S> +void Ransac::estimate(const Estimator & paramEstimator, const std::vector<T> &data, + int numForEstimate, short *bestVotes, short *curVotes, + int &numVotesForBest, int *arr) +{ + std::vector<T *> exactEstimateData; + std::vector<S> exactEstimateParameters; + int numDataObjects; + int numVotesForCur;//initalize with -1 so that the first computation will be set to best + int j; + + numDataObjects = data.size(); + memset(curVotes,'\0',numDataObjects*sizeof(short)); + numVotesForCur=0; + + for(j=0; j<numForEstimate; j++) + exactEstimateData.push_back(&(data[arr[j]])); + paramEstimator->estimate(exactEstimateData,exactEstimateParameters); + //singular data configuration + if(exactEstimateParameters.size()==0) + return; + + for(j=0; j<numDataObjects; j++) { + if(paramEstimator->agree(exactEstimateParameters, data[j])) { + curVotes[j] = 1; + numVotesForCur++; + } + } + if(numVotesForCur > numVotesForBest) { + numVotesForBest = numVotesForCur; + memcpy(bestVotes,curVotes, numDataObjects*sizeof(short)); + } +} +/*****************************************************************************/ +inline unsigned int Ransac::choose(unsigned int n, unsigned int m) +{ + unsigned int denominatorEnd, numeratorStart, numerator,denominator; + if((n-m) > m) { + numeratorStart = n-m+1; + denominatorEnd = m; + } + else { + numeratorStart = m+1; + denominatorEnd = n-m; + } + + unsigned int i; + for(i=numeratorStart, numerator=1; i<=n; i++) + numerator*=i; + for(i=1, denominator=1; i<=denominatorEnd; i++) + denominator*=i; + return numerator/denominator; + +} + + +#endif //_RANSAC_H_ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bl...@us...> - 2009-05-11 22:56:41
|
Revision: 3848 http://hugin.svn.sourceforge.net/hugin/?rev=3848&view=rev Author: blimbo Date: 2009-05-11 22:56:37 +0000 (Mon, 11 May 2009) Log Message: ----------- Added some code to curve estimator Modified Paths: -------------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.h hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp 2009-05-11 22:16:00 UTC (rev 3847) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp 2009-05-11 22:56:37 UTC (rev 3848) @@ -3,28 +3,51 @@ #include <iostream> #include "vigra/diff2d.hxx" -ParameterEstimator::ParameterEstimator(double delta){ - minForEstimate = 3; +ParameterEstimator::ParameterEstimator(unsigned int m){ + + // Number of data objects required for an exact + // estimate (e.g. 2 for a line where the data objects are points) + minForEstimate = m; } bool ParameterEstimator::estimate(std::vector<const vigra::Point2D *> &data, std::vector<double> ¶meters){ - + + // Quadratic y = ax2 + bx + c + // Need to estimate a, b and c + + // When x == 0. Ok to take average of 3 c's? + double c = (double)(data[0]->y + data[1]->y + data[2]->y)/3; + + // Viète's formulas. Ok to take average of 2 b/c's? + double a = ( (c/(data[0]->x * data[1]->x)) + (c/(data[1]->x * data[2]->x)) )/2; + double b = ( (-1*(data[0]->x + data[1]->x)*a) + (-1*(data[1]->x + data[2]->x)) )/2; + + //for (unsigned i = 0; i < data.size(); i++){ + // std::cout << "Estimator: " << i << " " << data[i]->x << "," << data[i]->y << std::endl; + //} + parameters.clear(); if(data.size()<this->minForEstimate) return(0); - double nx = data[1]->y - data[0]->y; - double ny = data[0]->x - data[1]->x; - double norm = sqrt(nx*nx + ny*ny); + //double nx = data[1]->y - data[0]->y; + //double ny = data[0]->x - data[1]->x; + //double norm = sqrt(nx*nx + ny*ny); - parameters.push_back(nx/norm); - parameters.push_back(ny/norm); - parameters.push_back(data[0]->x); - parameters.push_back(data[0]->y); + //parameters.push_back(nx/norm); + //parameters.push_back(ny/norm); + //parameters.push_back(data[0]->x); + //parameters.push_back(data[0]->y); - //for (unsigned i = 0; i < parameters.size(); i++){ - // std::cout << "RANSAC curve parameter: " << i << " " << parameters[i] << std::endl; - //} + parameters.push_back(a); + parameters.push_back(b); + parameters.push_back(c); + char params[3] = {'a', 'b', 'c'}; + + for (unsigned i = 0; i < parameters.size(); i++){ + std::cout << "RANSAC curve parameter: " << params[i] << " " << parameters[i] << std::endl; + } + return(1); } /*****************************************************************************/ @@ -59,7 +82,7 @@ meanY/=dataSize; covMat11 -= dataSize*meanX*meanX; - covMat12 -= dataSize*meanX*meanY; + covMat12 -= dataSize*meanX*meanY; covMat22 -= dataSize*meanY*meanY; covMat21 = covMat12; Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.h 2009-05-11 22:16:00 UTC (rev 3847) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.h 2009-05-11 22:56:37 UTC (rev 3848) @@ -27,7 +27,7 @@ * Constructor which takes the number of data objects required for an exact * estimate (e.g. 2 for a line where the data objects are points */ - ParameterEstimator(double delta); + ParameterEstimator(unsigned int minForEstimate); /** * Exact estimation of parameters. Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-05-11 22:16:00 UTC (rev 3847) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-05-11 22:56:37 UTC (rev 3848) @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2008 by Tim Nugent * + * Copyright (C) 2009 by Tim Nugent * * tim...@gm... * * * * This program is free software; you can redistribute it and/or modify * @@ -36,14 +36,10 @@ cout << coords.size() << " 'edge' coordinates found." << endl; vector<double> curveParameters; - int numSamples = 20; - int numOutliers = 80; double desiredProbabilityForNoOutliers = 0.9; - double maximalOutlierPercentage = 0.1 + (double)numOutliers/(double)(numSamples + numOutliers); + double maximalOutlierPercentage = 0.8; + ParameterEstimator curveEstimator(3); - //for a point to be on the line it has to be closer than 0.5 units from the line - ParameterEstimator curveEstimator(0.5); - cout << endl << "Computing RANSAC..." << endl; double usedData = Ransac::compute(curveParameters, &curveEstimator, coords, desiredProbabilityForNoOutliers, maximalOutlierPercentage); @@ -57,7 +53,7 @@ // double dotProd = curveParameters[0]*(-coords[i].y) + curveParameters[1]*coords[i].x; // cout << "(" << coords[i].x << "," << coords[i].y << ") ---> " << dotProd << endl; //} - //exit(1); + exit(1); //cout<<"RANSAC line parameters [n_x,n_y,a_x,a_y]\n\t [ "<<curveParameters[0]<<", "<<curveParameters[1]<<", "; //cout<<curveParameters[2]<<", "<<curveParameters[3]<<" ]"<<endl; @@ -86,9 +82,7 @@ } } } - ransac(coords); - } void sub_image(BImage& image){ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bl...@us...> - 2009-05-12 22:19:49
|
Revision: 3849 http://hugin.svn.sourceforge.net/hugin/?rev=3849&view=rev Author: blimbo Date: 2009-05-12 22:19:39 +0000 (Tue, 12 May 2009) Log Message: ----------- Written RANSAC curve estimator using quadratic model Modified Paths: -------------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp Added Paths: ----------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/MatrixDeterminant.h Added: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/MatrixDeterminant.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/MatrixDeterminant.h (rev 0) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/MatrixDeterminant.h 2009-05-12 22:19:39 UTC (rev 3849) @@ -0,0 +1,33 @@ +#ifndef MATRIX_DETERMINANT_H +#define MATRIX_DETERMINANT_H + +#include <boost/numeric/ublas/lu.hpp> + +namespace ublas = boost::numeric::ublas; + +template<class matrix_T> +double determinant(ublas::matrix_expression<matrix_T> const& mat_r){ + + double det = 1.0; + + matrix_T mLu(mat_r() ); + ublas::permutation_matrix<std::size_t> pivots(mat_r().size1() ); + + int is_singular = lu_factorize(mLu, pivots); + + if(!is_singular){ + + for (std::size_t i=0; i < pivots.size(); ++i){ + if (pivots(i) != i){ + det *= -1.0; + } + det *= mLu(i,i); + } + }else{ + det = 0.0; + } + + return det; +} + +#endif Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp 2009-05-11 22:56:37 UTC (rev 3848) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp 2009-05-12 22:19:39 UTC (rev 3849) @@ -2,7 +2,12 @@ #include "ParameterEstimator.h" #include <iostream> #include "vigra/diff2d.hxx" +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/io.hpp> +#include "MatrixDeterminant.h" +using namespace boost::numeric::ublas; + ParameterEstimator::ParameterEstimator(unsigned int m){ // Number of data objects required for an exact @@ -12,43 +17,101 @@ bool ParameterEstimator::estimate(std::vector<const vigra::Point2D *> &data, std::vector<double> ¶meters){ - // Quadratic y = ax2 + bx + c + parameters.clear(); + if(data.size()<this->minForEstimate) + return(false); + + // Quadratic: ax^2 + bx + c = y // Need to estimate a, b and c + // + // Using Cramer's Rule + // http://en.wikipedia.org/wiki/Cramer%27s_rule + // [x_1^2, x_1, 1] [a] [y_1] + // [x_2^2, x_2, 1]*[b]=[y_2] + // [x_3^2, x_3, 1] [c] [y_3] + // (m1) + // + // [ y_1 , x_1, 1] + // [ y_2 , x_2, 1] + // [ y_3 , x_3, 1] + // a = --------------- + // [x_1^2, x_1, 1] + // [x_2^2, x_2, 1] + // [x_3^2, x_3, 1] + // + // [x_1^2, y_1, 1] + // [x_2^2, y_2, 1] + // [x_3^2, y_3, 1] + // b = --------------- + // [x_1^2, x_1, 1] + // [x_2^2, x_2, 1] + // [x_3^2, x_3, 1] + // + // [x_1^2, x_1, y_1] + // [x_2^2, x_2, y_2] + // [x_3^2, x_3, y_3] + // c = --------------- + // [x_1^2, x_1, 1] + // [x_2^2, x_2, 1] + // [x_3^2, x_3, 1] - // When x == 0. Ok to take average of 3 c's? - double c = (double)(data[0]->y + data[1]->y + data[2]->y)/3; - // Viète's formulas. Ok to take average of 2 b/c's? - double a = ( (c/(data[0]->x * data[1]->x)) + (c/(data[1]->x * data[2]->x)) )/2; - double b = ( (-1*(data[0]->x + data[1]->x)*a) + (-1*(data[1]->x + data[2]->x)) )/2; + matrix<double> m1 (3, 3), m2 (3, 3); + m1 (0,0) = data[0]->x*data[0]->x; + m1 (0,1) = data[0]->x; + m1 (0,2) = 1; + m1 (1,0) = data[1]->x*data[1]->x; + m1 (1,1) = data[1]->x; + m1 (1,2) = 1; + m1 (2,0) = data[2]->x*data[2]->x; + m1 (2,1) = data[2]->x; + m1 (2,2) = 1; - //for (unsigned i = 0; i < data.size(); i++){ - // std::cout << "Estimator: " << i << " " << data[i]->x << "," << data[i]->y << std::endl; - //} + double d_m1 = determinant(m1); + std::cout << "Matrix m1:\t" << m1 << std::endl; + std::cout << "m1 determinant:\t" << d_m1 << std::endl; - parameters.clear(); - if(data.size()<this->minForEstimate) - return(0); - //double nx = data[1]->y - data[0]->y; - //double ny = data[0]->x - data[1]->x; - //double norm = sqrt(nx*nx + ny*ny); - - //parameters.push_back(nx/norm); - //parameters.push_back(ny/norm); - //parameters.push_back(data[0]->x); - //parameters.push_back(data[0]->y); + m2 = m1; + m2 (0,0) = data[0]->y; + m2 (1,0) = data[0]->y; + m2 (2,0) = data[0]->y; + std::cout << "Matrix m2:\t" << m2 << std::endl; + double d_m2_a = determinant(m2); + std::cout << "(a) m2 determinant:\t" << d_m2_a << std::endl; + double a = d_m2_a/d_m1; + + m2 = m1; + m2 (0,1) = data[1]->y; + m2 (1,1) = data[1]->y; + m2 (2,1) = data[1]->y; + + std::cout << "Matrix m2:\t" << m2 << std::endl; + double d_m2_b = determinant(m2); + std::cout << "(b) m2 determinant:\t" << d_m2_b << std::endl; + double b = d_m2_b/d_m1; + + m2 = m1; + m2 (0,2) = data[2]->y; + m2 (1,2) = data[2]->y; + m2 (2,2) = data[2]->y; + + std::cout << "Matrix m2:\t" << m2 << std::endl; + double d_m2_c = determinant(m2); + std::cout << "(c) m2 determinant:\t" << d_m2_c << std::endl; + double c = d_m2_c/d_m1; + + std::cout << "Parameter estimates:" << std::endl; + std::cout << "a:\t" << a << std::endl; + std::cout << "b:\t" << b << std::endl; + std::cout << "c:\t" << c << std::endl << std::endl; + parameters.push_back(a); parameters.push_back(b); parameters.push_back(c); + return(true); - char params[3] = {'a', 'b', 'c'}; - for (unsigned i = 0; i < parameters.size(); i++){ - std::cout << "RANSAC curve parameter: " << params[i] << " " << parameters[i] << std::endl; - } - - return(1); } /*****************************************************************************/ /* This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bl...@us...> - 2009-05-12 22:27:09
|
Revision: 3850 http://hugin.svn.sourceforge.net/hugin/?rev=3850&view=rev Author: blimbo Date: 2009-05-12 22:27:00 +0000 (Tue, 12 May 2009) Log Message: ----------- Slight bug fix, wrong y coords were being used Modified Paths: -------------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt 2009-05-12 22:19:39 UTC (rev 3849) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt 2009-05-12 22:27:00 UTC (rev 3850) @@ -2,9 +2,7 @@ Main.cpp Globals.cpp ParameterEstimator.cpp -ParameterEstimator.h ProcessImage.cpp -Ransac.h ) TARGET_LINK_LIBRARIES( calibrate_lens ${image_libs} ) Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp 2009-05-12 22:19:39 UTC (rev 3849) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp 2009-05-12 22:27:00 UTC (rev 3850) @@ -31,6 +31,9 @@ // [x_3^2, x_3, 1] [c] [y_3] // (m1) // + // Divisions below are using the determinants of + // the matrices + // // [ y_1 , x_1, 1] // [ y_2 , x_2, 1] // [ y_3 , x_3, 1] @@ -73,8 +76,8 @@ m2 = m1; m2 (0,0) = data[0]->y; - m2 (1,0) = data[0]->y; - m2 (2,0) = data[0]->y; + m2 (1,0) = data[1]->y; + m2 (2,0) = data[2]->y; std::cout << "Matrix m2:\t" << m2 << std::endl; double d_m2_a = determinant(m2); @@ -82,9 +85,9 @@ double a = d_m2_a/d_m1; m2 = m1; - m2 (0,1) = data[1]->y; + m2 (0,1) = data[0]->y; m2 (1,1) = data[1]->y; - m2 (2,1) = data[1]->y; + m2 (2,1) = data[2]->y; std::cout << "Matrix m2:\t" << m2 << std::endl; double d_m2_b = determinant(m2); @@ -92,8 +95,8 @@ double b = d_m2_b/d_m1; m2 = m1; - m2 (0,2) = data[2]->y; - m2 (1,2) = data[2]->y; + m2 (0,2) = data[0]->y; + m2 (1,2) = data[1]->y; m2 (2,2) = data[2]->y; std::cout << "Matrix m2:\t" << m2 << std::endl; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bl...@us...> - 2009-05-16 01:09:15
|
Revision: 3857 http://hugin.svn.sourceforge.net/hugin/?rev=3857&view=rev Author: blimbo Date: 2009-05-16 01:09:12 +0000 (Sat, 16 May 2009) Log Message: ----------- Added some ransac code but func function needs to be completed Modified Paths: -------------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/MatrixDeterminant.h hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.h hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Ransac.h Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt 2009-05-15 16:35:28 UTC (rev 3856) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt 2009-05-16 01:09:12 UTC (rev 3857) @@ -5,6 +5,6 @@ ProcessImage.cpp ) -TARGET_LINK_LIBRARIES( calibrate_lens ${image_libs} ) +TARGET_LINK_LIBRARIES( calibrate_lens ${image_libs} ${common_libs}) INSTALL(TARGETS calibrate_lens DESTINATION ${BINDIR}) Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/MatrixDeterminant.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/MatrixDeterminant.h 2009-05-15 16:35:28 UTC (rev 3856) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/MatrixDeterminant.h 2009-05-16 01:09:12 UTC (rev 3857) @@ -29,5 +29,4 @@ return det; } - #endif Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp 2009-05-15 16:35:28 UTC (rev 3856) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp 2009-05-16 01:09:12 UTC (rev 3857) @@ -1,18 +1,21 @@ -#include <math.h> +#include <cmath> #include "ParameterEstimator.h" #include <iostream> #include "vigra/diff2d.hxx" #include <boost/numeric/ublas/matrix.hpp> #include <boost/numeric/ublas/io.hpp> +#include <levmar/lm.h> #include "MatrixDeterminant.h" using namespace boost::numeric::ublas; +using namespace std; -ParameterEstimator::ParameterEstimator(unsigned int m){ +ParameterEstimator::ParameterEstimator(unsigned int m, double delta){ // Number of data objects required for an exact // estimate (e.g. 2 for a line where the data objects are points) minForEstimate = m; + deltasquared = delta*delta; } bool ParameterEstimator::estimate(std::vector<const vigra::Point2D *> &data, std::vector<double> ¶meters){ @@ -21,44 +24,43 @@ if(data.size()<this->minForEstimate) return(false); - // Quadratic: ax^2 + bx + c = y - // Need to estimate a, b and c - // - // Using Cramer's Rule - // http://en.wikipedia.org/wiki/Cramer%27s_rule - // [x_1^2, x_1, 1] [a] [y_1] - // [x_2^2, x_2, 1]*[b]=[y_2] - // [x_3^2, x_3, 1] [c] [y_3] - // (m1) - // - // Divisions below are using the determinants of - // the matrices - // - // [ y_1 , x_1, 1] - // [ y_2 , x_2, 1] - // [ y_3 , x_3, 1] - // a = --------------- - // [x_1^2, x_1, 1] - // [x_2^2, x_2, 1] - // [x_3^2, x_3, 1] - // - // [x_1^2, y_1, 1] - // [x_2^2, y_2, 1] - // [x_3^2, y_3, 1] - // b = --------------- - // [x_1^2, x_1, 1] - // [x_2^2, x_2, 1] - // [x_3^2, x_3, 1] - // - // [x_1^2, x_1, y_1] - // [x_2^2, x_2, y_2] - // [x_3^2, x_3, y_3] - // c = --------------- - // [x_1^2, x_1, 1] - // [x_2^2, x_2, 1] - // [x_3^2, x_3, 1] + /* Quadratic: ax^2 + bx + c = y + Need to estimate a, b and c + + Using Cramer's Rule + http://en.wikipedia.org/wiki/Cramer%27s_rule + [x_1^2, x_1, 1] [a] [y_1] + [x_2^2, x_2, 1]*[b]=[y_2] + [x_3^2, x_3, 1] [c] [y_3] + + Divisions below are using the determinants of + the matrices + + [ y_1 , x_1, 1] + [ y_2 , x_2, 1] + [ y_3 , x_3, 1] + a = --------------- + [x_1^2, x_1, 1] + [x_2^2, x_2, 1] + [x_3^2, x_3, 1] + + [x_1^2, y_1, 1] + [x_2^2, y_2, 1] + [x_3^2, y_3, 1] + b = --------------- + [x_1^2, x_1, 1] + [x_2^2, x_2, 1] + [x_3^2, x_3, 1] + + [x_1^2, x_1, y_1] + [x_2^2, x_2, y_2] + [x_3^2, x_3, y_3] + c = ----------------- + [x_1^2, x_1, 1] + [x_2^2, x_2, 1] + [x_3^2, x_3, 1] + */ - matrix<double> m1 (3, 3), m2 (3, 3); m1 (0,0) = data[0]->x*data[0]->x; m1 (0,1) = data[0]->x; @@ -71,43 +73,54 @@ m1 (2,2) = 1; double d_m1 = determinant(m1); - std::cout << "Matrix m1:\t" << m1 << std::endl; - std::cout << "m1 determinant:\t" << d_m1 << std::endl; + //std::cout << "Matrix m1:\t" << m1 << std::endl; + //std::cout << "m1 determinant:\t" << d_m1 << std::endl; m2 = m1; m2 (0,0) = data[0]->y; m2 (1,0) = data[1]->y; m2 (2,0) = data[2]->y; + /* std::cout << "Matrix m2:\t" << m2 << std::endl; double d_m2_a = determinant(m2); std::cout << "(a) m2 determinant:\t" << d_m2_a << std::endl; double a = d_m2_a/d_m1; + */ + double a = determinant(m2)/d_m1; m2 = m1; m2 (0,1) = data[0]->y; m2 (1,1) = data[1]->y; m2 (2,1) = data[2]->y; + /* std::cout << "Matrix m2:\t" << m2 << std::endl; double d_m2_b = determinant(m2); std::cout << "(b) m2 determinant:\t" << d_m2_b << std::endl; double b = d_m2_b/d_m1; + */ + double b = determinant(m2)/d_m1; m2 = m1; m2 (0,2) = data[0]->y; m2 (1,2) = data[1]->y; m2 (2,2) = data[2]->y; + /* std::cout << "Matrix m2:\t" << m2 << std::endl; double d_m2_c = determinant(m2); std::cout << "(c) m2 determinant:\t" << d_m2_c << std::endl; double c = d_m2_c/d_m1; + */ + double c = determinant(m2)/d_m1; + /* std::cout << "Parameter estimates:" << std::endl; std::cout << "a:\t" << a << std::endl; std::cout << "b:\t" << b << std::endl; std::cout << "c:\t" << c << std::endl << std::endl; + */ parameters.push_back(a); parameters.push_back(b); @@ -119,75 +132,67 @@ /*****************************************************************************/ /* * Compute the line parameters [n_x,n_y,a_x,a_y] - */ + */ + + +/* model to be fitted to measurements: x_i = p[0]*exp(-p[1]*i) + p[2], i=0...n-1 */ +void func(double *p, double *x, int m, int n, void *data){ + register int i; + + std::vector<const vigra::Point2D *> * dat = (std::vector<const vigra::Point2D *> *) data; + + for(i=0; i < n; ++i){ + //cout << (*dat)[i]->x << "," << (*dat)[i]->y << endl; + //[i]= p[0] * exp(-p[1]*i) + p[2]; + } +} + +void jacfunc(double *p, double *jac, int m, int n, void *data){} + void ParameterEstimator::leastSquaresEstimate(std::vector<const vigra::Point2D *> &data, std::vector<double> ¶meters) { - //std::cout << "leastSquaresEstimate" << std::endl; - - double meanX, meanY, nx, ny, norm; - double covMat11, covMat12, covMat21, covMat22; // The entries of the symmetric covarinace matrix - int i, dataSize = data.size(); - - parameters.clear(); - if(data.size()<this->minForEstimate) - return; - - meanX = meanY = 0.0; - covMat11 = covMat12 = covMat21 = covMat22 = 0; - for(i=0; i<dataSize; i++) { - meanX +=data[i]->x; - meanY +=data[i]->y; - - covMat11 +=data[i]->x * data[i]->x; - covMat12 +=data[i]->x * data[i]->y; - covMat22 +=data[i]->y * data[i]->y; - } - - meanX/=dataSize; - meanY/=dataSize; - - covMat11 -= dataSize*meanX*meanX; - covMat12 -= dataSize*meanX*meanY; - covMat22 -= dataSize*meanY*meanY; - covMat21 = covMat12; - - if(covMat11<1e-12) { - nx = 1.0; - ny = 0.0; - } - else { //lamda1 is the largest eigen-value of the covariance matrix - //and is used to compute the eigne-vector corresponding to the smallest - //eigenvalue, which isn't computed explicitly. - double lamda1 = (covMat11 + covMat22 + sqrt((covMat11-covMat22)*(covMat11-covMat22) + 4*covMat12*covMat12)) / 2.0; - nx = -covMat12; - ny = lamda1 - covMat22; - norm = sqrt(nx*nx + ny*ny); - nx/=norm; - ny/=norm; - } - parameters.push_back(nx); - parameters.push_back(ny); - parameters.push_back(meanX); - parameters.push_back(meanY); + std::cout << "Least squares estimate using LEVMAR..." << std::endl; + + const int n= data.size(), m = 3; // n measurements, 3 parameters + double p[m], x[n], opts[LM_OPTS_SZ], info[LM_INFO_SZ]; + register int i; + int ret; + + //for(i=0; i<n; ++i) + // x[i]= data[i]->x; + + /* initial parameters estimate: (1.0, 1.0, 1.0) */ + p[0]=1.0; p[1]=1.0; p[2]=1.0; + + /* optimization control parameters; passing to levmar NULL instead of opts reverts to defaults */ + opts[0]=LM_INIT_MU; opts[1]=1E-15; opts[2]=1E-15; opts[3]=1E-20; + opts[4]=LM_DIFF_DELTA; // relevant only if the finite difference Jacobian version is used + + /* invoke the optimization function */ + ret=dlevmar_der(func, jacfunc, p, x, m, n, 1000, opts, info, NULL, NULL, &data); // with analytic Jacobian + + printf("Levenberg-Marquardt returned in %g iter, reason %g, sumsq %g [%g]\n", info[5], info[6], info[1], info[0]); + printf("Best fit parameters: %.7g %.7g %.7g\n", p[0], p[1], p[2]); + + parameters.push_back(p[0]); + parameters.push_back(p[1]); + parameters.push_back(p[2]); } -/*****************************************************************************/ -/* - * Given the line parameters [n_x,n_y,a_x,a_y] check if - * [n_x, n_y] dot [data.x-a_x, data.y-a_y] < m_delta - */ -bool ParameterEstimator::agree(std::vector<double> ¶meters, const vigra::Point2D &data){ - //for (unsigned i = 0; i < parameters.size(); i++){ - // std::cout << "param " << parameters[i] << std::endl; - //} - //std::cout << "x = " << data.x << " y = " << data.y << std::endl; - - double signedDistance = parameters[0]*(data.x-parameters[2]) + parameters[1]*(data.y-parameters[3]); +bool ParameterEstimator::agree(std::vector<double> ¶meters, const vigra::Point2D &data, double x_min, double x_max){ - return ((signedDistance*signedDistance) < this->deltaSquared); + double shortest = 100000000; + for (int x = x_min; x < x_max; x++){ + double y = (parameters[0]*(x*x)) + (parameters[1]*x) + parameters[2]; + double distancesquared = abs((data->x - x) + (data->y - y)); + if(distancesquared < shortest){ + shortest = distancesquared; + } + //std::cout << x << "\t=\t" << distancesquared << std::endl; + } + return (shortest < this->deltasquared); } -/*****************************************************************************/ Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.h 2009-05-15 16:35:28 UTC (rev 3856) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.h 2009-05-16 01:09:12 UTC (rev 3857) @@ -27,7 +27,7 @@ * Constructor which takes the number of data objects required for an exact * estimate (e.g. 2 for a line where the data objects are points */ - ParameterEstimator(unsigned int minForEstimate); + ParameterEstimator(unsigned int minForEstimate, double delta); /** * Exact estimation of parameters. @@ -46,7 +46,7 @@ /** * This method tests if the given data agrees with the given model parameters. */ - virtual bool agree(std::vector<double> ¶meters, const vigra::Point2D &data); + virtual bool agree(std::vector<double> ¶meters, const vigra::Point2D &data, double x_min, double x_max); static void debugTest(std::ostream &out); @@ -56,10 +56,10 @@ */ unsigned int numForEstimate() const {return minForEstimate;} protected: - unsigned int minForEstimate; + unsigned int minForEstimate, max_x; private: - double deltaSquared; //given line L and point P, if dist(L,P)^2 < m_delta^2 then the point is on the line + double deltasquared; //given line L and point P, if dist(L,P)^2 < m_delta^2 then the point is on the line }; Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-05-15 16:35:28 UTC (rev 3856) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-05-16 01:09:12 UTC (rev 3857) @@ -38,31 +38,21 @@ vector<double> curveParameters; double desiredProbabilityForNoOutliers = 0.9; double maximalOutlierPercentage = 0.8; - ParameterEstimator curveEstimator(3); + // Use 3 points to calculate a,b and c parameters + // Point must be within 0.2 units of curve to agree + ParameterEstimator curveEstimator(3, 0.2); cout << endl << "Computing RANSAC..." << endl; double usedData = Ransac::compute(curveParameters, &curveEstimator, coords, desiredProbabilityForNoOutliers, maximalOutlierPercentage); + cout << "y = " << curveParameters[0] << "x^2 + " << curveParameters[1] << "x + " << curveParameters[2] << endl; + cout << "Percentage of points which were used for final estimate: "<< usedData/coords.size() << " % (" << usedData << ")" << endl << endl; - for (unsigned i = 0; i < curveParameters.size(); i++){ - cout << "RANSAC curve parameter: " << curveParameters[i] << endl; - } - - cout << endl << "Percentage of points which were used for final estimate: "<< usedData << endl << endl; - - //for (unsigned i = 0; i < coords.size(); i++){ - // double dotProd = curveParameters[0]*(-coords[i].y) + curveParameters[1]*coords[i].x; - // cout << "(" << coords[i].x << "," << coords[i].y << ") ---> " << dotProd << endl; - //} exit(1); - //cout<<"RANSAC line parameters [n_x,n_y,a_x,a_y]\n\t [ "<<curveParameters[0]<<", "<<curveParameters[1]<<", "; - //cout<<curveParameters[2]<<", "<<curveParameters[3]<<" ]"<<endl; - } void extract_coords(BImage& image){ - //vector< pair<int,int> > coords; vector<Point2D> coords; // Gather black pixels Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Ransac.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Ransac.h 2009-05-15 16:35:28 UTC (rev 3856) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Ransac.h 2009-05-16 01:09:12 UTC (rev 3857) @@ -178,11 +178,20 @@ double maximalOutlierPercentage) { - //for (unsigned i = 0; i < data.size(); i++){ - // std::cout << data[i]->x << "," << data[i]->y << std::endl; - //} + // Modified by Tim + // Work out range of x coords to sample in agree function + double x_min = 10000000, x_max = -10000000; + for (unsigned i = 0; i < data.size(); i++){ + if (data[i]->x > x_max){ + x_max = data[i]->x; + } + if (data[i]->x < x_min){ + x_min = data[i]->x; + } + } + //std::cout << "X coord range:\t " << x_min << " - " << x_max << std::endl; + // - unsigned int numDataObjects = (int) data.size(); unsigned int numForEstimate = paramEstimator->numForEstimate(); @@ -274,7 +283,7 @@ numVotesForCur = 0; memset(curVotes,'\0',numDataObjects*sizeof(short)); for(j=0; j<(int)numDataObjects; j++) { - if(paramEstimator->agree(exactEstimateParameters, data[j])) { + if(paramEstimator->agree(exactEstimateParameters, data[j], x_min, x_max)) { curVotes[j] = 1; numVotesForCur++; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bl...@us...> - 2009-05-21 17:07:17
|
Revision: 3868 http://hugin.svn.sourceforge.net/hugin/?rev=3868&view=rev Author: blimbo Date: 2009-05-21 17:07:15 +0000 (Thu, 21 May 2009) Log Message: ----------- Test program test_line_dist.cpp to work out curve-point distance, can't quite get it to work yet Modified Paths: -------------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h Added Paths: ----------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/test_line_dist.cpp Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp 2009-05-20 18:27:37 UTC (rev 3867) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp 2009-05-21 17:07:15 UTC (rev 3868) @@ -1,5 +1,5 @@ -#include <cmath> -#include "ParameterEstimator.h" +#include <cmath> +#include "ParameterEstimator.h" #include <iostream> #include "vigra/diff2d.hxx" #include <boost/numeric/ublas/matrix.hpp> @@ -10,6 +10,8 @@ using namespace boost::numeric::ublas; using namespace std; +double a,b,c,p,q; + ParameterEstimator::ParameterEstimator(unsigned int m, double delta){ // Number of data objects required for an exact @@ -135,20 +137,21 @@ */ -/* model to be fitted to measurements: x_i = p[0]*exp(-p[1]*i) + p[2], i=0...n-1 */ + + void func(double *p, double *x, int m, int n, void *data){ register int i; std::vector<const vigra::Point2D *> * dat = (std::vector<const vigra::Point2D *> *) data; for(i=0; i < n; ++i){ - //cout << (*dat)[i]->x << "," << (*dat)[i]->y << endl; - //[i]= p[0] * exp(-p[1]*i) + p[2]; + //std::cout << "x = " << (*dat)[i]->x << ", y =" << (*dat)[i]->y << endl; + //[i]= ??? } } void jacfunc(double *p, double *jac, int m, int n, void *data){} - + void ParameterEstimator::leastSquaresEstimate(std::vector<const vigra::Point2D *> &data, std::vector<double> ¶meters) { @@ -159,8 +162,9 @@ register int i; int ret; - //for(i=0; i<n; ++i) - // x[i]= data[i]->x; + for(i=0; i < n; ++i){ + x[i]= 1; + } /* initial parameters estimate: (1.0, 1.0, 1.0) */ p[0]=1.0; p[1]=1.0; p[2]=1.0; @@ -175,15 +179,17 @@ printf("Levenberg-Marquardt returned in %g iter, reason %g, sumsq %g [%g]\n", info[5], info[6], info[1], info[0]); printf("Best fit parameters: %.7g %.7g %.7g\n", p[0], p[1], p[2]); - parameters.push_back(p[0]); - parameters.push_back(p[1]); - parameters.push_back(p[2]); -} + parameters.push_back(p[0]); + parameters.push_back(p[1]); + parameters.push_back(p[2]); +} bool ParameterEstimator::agree(std::vector<double> ¶meters, const vigra::Point2D &data, double x_min, double x_max){ + double shortest = 100000000; - for (int x = x_min; x < x_max; x++){ + + for (int x = (int)x_min; x < x_max; x++){ double y = (parameters[0]*(x*x)) + (parameters[1]*x) + parameters[2]; double distancesquared = abs((data->x - x) + (data->y - y)); if(distancesquared < shortest){ @@ -191,8 +197,35 @@ } //std::cout << x << "\t=\t" << distancesquared << std::endl; } + + + //std::cout << "Brute force:\t" << shortest << std::endl; + + + if (1){ + + double p = data->x; + double q = data->y; + double a = parameters[0]; + double b = parameters[1]; + double c = parameters[2]; + double a2 = a*a; + double a3 = a2*a; + double a4 = a2*a2; + double b2 = b*b; + + + shortest = -(b/(2*a)) + - (((6*a2) - (3*a2*b2) + (12*a3*c) - (12*a3*q)) + /(3 * pow(2,(double)(2/3)) * a2 * pow(((54*a3*b) + (108*a4*p) + sqrt(pow(((54*a3*b) + (108*a4*p)),2) + (4*pow(((6*a2) - (3*a2*b2) + (12*a3*c) - (12*a3*q)),3)))),(double)(1/3)))) + + (1/(6*pow(2,(double)(1/3))*a2)) + *(pow((54*a3*b) + (108*a4*p) + sqrt(pow(((54*a3*b) + (108*a4*p)),2) + (4*pow(((6*a2) - (3*a2*b2) + (12*a3*c) - (12*a3*q)),3))),(double)(1/3))); + + std::cout << "Algebreic:\t" << shortest << std::endl; + } + return (shortest < this->deltasquared); - -} + +} Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h 2009-05-20 18:27:37 UTC (rev 3867) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h 2009-05-21 17:07:15 UTC (rev 3868) @@ -4,7 +4,7 @@ #include "vigra/impex.hxx" #include "vigra/diff2d.hxx" -void ransac(std::vector<vigra::Point2D>&); +void ransac(std::vector<vigra::Point2D>&,unsigned int,unsigned int); void extract_coords(vigra::BImage&); void sub_image(vigra::BImage& image); void detect_edge(vigra::BImage&, std::string&, std::string&, std::string&); Added: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/test_line_dist.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/test_line_dist.cpp (rev 0) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/test_line_dist.cpp 2009-05-21 17:07:15 UTC (rev 3868) @@ -0,0 +1,45 @@ +#include <cmath> +#include <iostream> + +using namespace std; + +/* + +http://answers.yahoo.com/question/index?qid=20070109172252AAP34wx +Min distance from (3,2) to y = x^2 + 2 should = 2.23607 + +*/ + +double p = 3; +double q = 2; +double a = 1; +double b = 0; +double c = 2; +double a2 = a*a; +double a3 = a2*a; +double a4 = a2*a2; +double b2 = b*b; + +int main(){ + + double shortest_squared = + -(b/(2*a)) + - (6*a2 - 3*a2*b2 + 12*a3*c - 12*a3*q) + /(3*pow(2,(double)(2/3))*a2*pow((54*a3*b + 108*a4*p + + sqrt(pow((54*a3*b + 108*a4*p),2) + 4*pow((6*a2 - 3*a2*b2 + 12*a3*c - 12*a3*q),3)) + ),(double)(1/3))) + + (1/(6*pow(2,(double)(1/3))*a2)) + * pow( + (54*a3*b + 108*a4*p + sqrt(pow((54*a3*b + 108*a4*p),2) + + 4*pow((6*a2 - 3*a2*b2 + 12*a3*c - 12*a3*q),3))) + ,(double)(1/3)); + + std::cout << "Dist^2:\t" << shortest_squared << std::endl; + std::cout << "Dist:\t" << sqrt(shortest_squared) << std::endl; + + // closest point is (1,3) + std::cout << "Correct:\t" << sqrt ((3-1)*(3-1) + (2 - 3)*( 2 - 3)) << std::endl; + + return (1); + +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bl...@us...> - 2009-05-24 15:48:02
|
Revision: 3883 http://hugin.svn.sourceforge.net/hugin/?rev=3883&view=rev Author: blimbo Date: 2009-05-24 15:47:53 +0000 (Sun, 24 May 2009) Log Message: ----------- Slight mod to test_line_dist.cpp Modified Paths: -------------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/test_line_dist.cpp Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt 2009-05-24 15:12:40 UTC (rev 3882) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt 2009-05-24 15:47:53 UTC (rev 3883) @@ -5,6 +5,10 @@ ProcessImage.cpp ) +ADD_EXECUTABLE(test +test_line_dist.cpp +) + TARGET_LINK_LIBRARIES( calibrate_lens ${image_libs} ${common_libs}) INSTALL(TARGETS calibrate_lens DESTINATION ${BINDIR}) Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/test_line_dist.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/test_line_dist.cpp 2009-05-24 15:12:40 UTC (rev 3882) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/test_line_dist.cpp 2009-05-24 15:47:53 UTC (rev 3883) @@ -6,7 +6,7 @@ /* http://answers.yahoo.com/question/index?qid=20070109172252AAP34wx -Min distance from (3,2) to y = x^2 + 2 should = 2.23607 +Min distance from (3,2) to y = x^2 + 2 should = 2.23607 where x = 1,y = 3. */ @@ -22,7 +22,7 @@ int main(){ - double shortest_squared = + double x = -(b/(2*a)) - (6*a2 - 3*a2*b2 + 12*a3*c - 12*a3*q) /(3*pow(2,(double)(2/3))*a2*pow((54*a3*b + 108*a4*p + @@ -34,11 +34,10 @@ + 4*pow((6*a2 - 3*a2*b2 + 12*a3*c - 12*a3*q),3))) ,(double)(1/3)); - std::cout << "Dist^2:\t" << shortest_squared << std::endl; - std::cout << "Dist:\t" << sqrt(shortest_squared) << std::endl; + std::cout << "X:\t" << x << std::endl; // closest point is (1,3) - std::cout << "Correct:\t" << sqrt ((3-1)*(3-1) + (2 - 3)*( 2 - 3)) << std::endl; + //std::cout << "Correct:\t" << sqrt ((3-1)*(3-1) + (2 - 3)*( 2 - 3)) << std::endl; return (1); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bl...@us...> - 2009-05-28 16:37:23
|
Revision: 3890 http://hugin.svn.sourceforge.net/hugin/?rev=3890&view=rev Author: blimbo Date: 2009-05-28 16:37:18 +0000 (Thu, 28 May 2009) Log Message: ----------- Added Spline library, still have to connect it up though Modified Paths: -------------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Ransac.h Added Paths: ----------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/NewtonRaphson.h hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PolynomialEstimator.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PolynomialEstimator.h hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Spline.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Spline.h hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/SplineEstimator.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/SplineEstimator.h Removed Paths: ------------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.h hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/test_line_dist.cpp Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt 2009-05-27 17:49:29 UTC (rev 3889) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt 2009-05-28 16:37:18 UTC (rev 3890) @@ -1,14 +1,11 @@ ADD_EXECUTABLE(calibrate_lens Main.cpp Globals.cpp -ParameterEstimator.cpp ProcessImage.cpp +SplineEstimator.cpp +Spline.cpp ) -ADD_EXECUTABLE(test -test_line_dist.cpp -) - TARGET_LINK_LIBRARIES( calibrate_lens ${image_libs} ${common_libs}) INSTALL(TARGETS calibrate_lens DESTINATION ${BINDIR}) Added: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/NewtonRaphson.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/NewtonRaphson.h (rev 0) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/NewtonRaphson.h 2009-05-28 16:37:18 UTC (rev 3890) @@ -0,0 +1,37 @@ +// Newton-Raphson method of finding roots // +// Passing references to functions f(x) and f'(x) as function parameters // +// also demonstrates use of a function template // + +#include <iostream> +#include <iomanip> +#include <math.h> +#include <complex> + +using namespace std; + +//----------------------------------------------------------------------------// +// Function template: Newton-Raphson method find a root of the equation f(x) // +// see http://en.wikipedia.org/wiki/Newton's_method // +// Parameters in: &x reference to first approximation of root // +// (&f)(x) reference to function f(x) // +// (fdiv)(x) reference to function f'(x) // +// max_loop maxiumn number of itterations // +// accuracy required accuracy // +// out: &x return root found // +// function result: > 0 (true) if root found, 0 (false) if max_loop exceeded // +template <class T1> + int newton(T1 &x, T1 (&f)(T1), T1 (&fdiv)(T1), + int max_loop, const double accuracy) + { + T1 term; + do + { + // calculate next term f(x) / f'(x) then subtract from current root + term = (f)(x) / (fdiv)(x); + x = x - term; // new root + } + // check if term is within required accuracy or loop limit is exceeded + while ((abs(term / x) > accuracy) && (--max_loop)); + return max_loop; + } + Deleted: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp 2009-05-27 17:49:29 UTC (rev 3889) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.cpp 2009-05-28 16:37:18 UTC (rev 3890) @@ -1,231 +0,0 @@ -#include <cmath> -#include "ParameterEstimator.h" -#include <iostream> -#include "vigra/diff2d.hxx" -#include <boost/numeric/ublas/matrix.hpp> -#include <boost/numeric/ublas/io.hpp> -#include <levmar/lm.h> -#include "MatrixDeterminant.h" - -using namespace boost::numeric::ublas; -using namespace std; - -double a,b,c,p,q; - -ParameterEstimator::ParameterEstimator(unsigned int m, double delta){ - - // Number of data objects required for an exact - // estimate (e.g. 2 for a line where the data objects are points) - minForEstimate = m; - deltasquared = delta*delta; -} - -bool ParameterEstimator::estimate(std::vector<const vigra::Point2D *> &data, std::vector<double> ¶meters){ - - parameters.clear(); - if(data.size()<this->minForEstimate) - return(false); - - /* Quadratic: ax^2 + bx + c = y - Need to estimate a, b and c - - Using Cramer's Rule - http://en.wikipedia.org/wiki/Cramer%27s_rule - [x_1^2, x_1, 1] [a] [y_1] - [x_2^2, x_2, 1]*[b]=[y_2] - [x_3^2, x_3, 1] [c] [y_3] - - Divisions below are using the determinants of - the matrices - - [ y_1 , x_1, 1] - [ y_2 , x_2, 1] - [ y_3 , x_3, 1] - a = --------------- - [x_1^2, x_1, 1] - [x_2^2, x_2, 1] - [x_3^2, x_3, 1] - - [x_1^2, y_1, 1] - [x_2^2, y_2, 1] - [x_3^2, y_3, 1] - b = --------------- - [x_1^2, x_1, 1] - [x_2^2, x_2, 1] - [x_3^2, x_3, 1] - - [x_1^2, x_1, y_1] - [x_2^2, x_2, y_2] - [x_3^2, x_3, y_3] - c = ----------------- - [x_1^2, x_1, 1] - [x_2^2, x_2, 1] - [x_3^2, x_3, 1] - */ - - matrix<double> m1 (3, 3), m2 (3, 3); - m1 (0,0) = data[0]->x*data[0]->x; - m1 (0,1) = data[0]->x; - m1 (0,2) = 1; - m1 (1,0) = data[1]->x*data[1]->x; - m1 (1,1) = data[1]->x; - m1 (1,2) = 1; - m1 (2,0) = data[2]->x*data[2]->x; - m1 (2,1) = data[2]->x; - m1 (2,2) = 1; - - double d_m1 = determinant(m1); - //std::cout << "Matrix m1:\t" << m1 << std::endl; - //std::cout << "m1 determinant:\t" << d_m1 << std::endl; - - m2 = m1; - m2 (0,0) = data[0]->y; - m2 (1,0) = data[1]->y; - m2 (2,0) = data[2]->y; - - /* - std::cout << "Matrix m2:\t" << m2 << std::endl; - double d_m2_a = determinant(m2); - std::cout << "(a) m2 determinant:\t" << d_m2_a << std::endl; - double a = d_m2_a/d_m1; - */ - double a = determinant(m2)/d_m1; - - m2 = m1; - m2 (0,1) = data[0]->y; - m2 (1,1) = data[1]->y; - m2 (2,1) = data[2]->y; - - /* - std::cout << "Matrix m2:\t" << m2 << std::endl; - double d_m2_b = determinant(m2); - std::cout << "(b) m2 determinant:\t" << d_m2_b << std::endl; - double b = d_m2_b/d_m1; - */ - double b = determinant(m2)/d_m1; - - m2 = m1; - m2 (0,2) = data[0]->y; - m2 (1,2) = data[1]->y; - m2 (2,2) = data[2]->y; - - /* - std::cout << "Matrix m2:\t" << m2 << std::endl; - double d_m2_c = determinant(m2); - std::cout << "(c) m2 determinant:\t" << d_m2_c << std::endl; - double c = d_m2_c/d_m1; - */ - double c = determinant(m2)/d_m1; - - /* - std::cout << "Parameter estimates:" << std::endl; - std::cout << "a:\t" << a << std::endl; - std::cout << "b:\t" << b << std::endl; - std::cout << "c:\t" << c << std::endl << std::endl; - */ - - parameters.push_back(a); - parameters.push_back(b); - parameters.push_back(c); - return(true); - - -} -/*****************************************************************************/ -/* - * Compute the line parameters [n_x,n_y,a_x,a_y] - */ - - - - -void func(double *p, double *x, int m, int n, void *data){ - register int i; - - std::vector<const vigra::Point2D *> * dat = (std::vector<const vigra::Point2D *> *) data; - - for(i=0; i < n; ++i){ - //std::cout << "x = " << (*dat)[i]->x << ", y =" << (*dat)[i]->y << endl; - //[i]= ??? - } -} - -void jacfunc(double *p, double *jac, int m, int n, void *data){} - -void ParameterEstimator::leastSquaresEstimate(std::vector<const vigra::Point2D *> &data, std::vector<double> ¶meters) -{ - - std::cout << "Least squares estimate using LEVMAR..." << std::endl; - - const int n= data.size(), m = 3; // n measurements, 3 parameters - double p[m], x[n], opts[LM_OPTS_SZ], info[LM_INFO_SZ]; - register int i; - int ret; - - for(i=0; i < n; ++i){ - x[i]= 1; - } - - /* initial parameters estimate: (1.0, 1.0, 1.0) */ - p[0]=1.0; p[1]=1.0; p[2]=1.0; - - /* optimization control parameters; passing to levmar NULL instead of opts reverts to defaults */ - opts[0]=LM_INIT_MU; opts[1]=1E-15; opts[2]=1E-15; opts[3]=1E-20; - opts[4]=LM_DIFF_DELTA; // relevant only if the finite difference Jacobian version is used - - /* invoke the optimization function */ - ret=dlevmar_der(func, jacfunc, p, x, m, n, 1000, opts, info, NULL, NULL, &data); // with analytic Jacobian - - printf("Levenberg-Marquardt returned in %g iter, reason %g, sumsq %g [%g]\n", info[5], info[6], info[1], info[0]); - printf("Best fit parameters: %.7g %.7g %.7g\n", p[0], p[1], p[2]); - - parameters.push_back(p[0]); - parameters.push_back(p[1]); - parameters.push_back(p[2]); -} - -bool ParameterEstimator::agree(std::vector<double> ¶meters, const vigra::Point2D &data, double x_min, double x_max){ - - - double shortest = 100000000; - - for (int x = (int)x_min; x < x_max; x++){ - double y = (parameters[0]*(x*x)) + (parameters[1]*x) + parameters[2]; - double distancesquared = abs((data->x - x) + (data->y - y)); - if(distancesquared < shortest){ - shortest = distancesquared; - } - //std::cout << x << "\t=\t" << distancesquared << std::endl; - } - - - //std::cout << "Brute force:\t" << shortest << std::endl; - - - if (1){ - - double p = data->x; - double q = data->y; - double a = parameters[0]; - double b = parameters[1]; - double c = parameters[2]; - double a2 = a*a; - double a3 = a2*a; - double a4 = a2*a2; - double b2 = b*b; - - - shortest = -(b/(2*a)) - - (((6*a2) - (3*a2*b2) + (12*a3*c) - (12*a3*q)) - /(3 * pow(2,(double)(2/3)) * a2 * pow(((54*a3*b) + (108*a4*p) + sqrt(pow(((54*a3*b) + (108*a4*p)),2) + (4*pow(((6*a2) - (3*a2*b2) + (12*a3*c) - (12*a3*q)),3)))),(double)(1/3)))) - + (1/(6*pow(2,(double)(1/3))*a2)) - *(pow((54*a3*b) + (108*a4*p) + sqrt(pow(((54*a3*b) + (108*a4*p)),2) + (4*pow(((6*a2) - (3*a2*b2) + (12*a3*c) - (12*a3*q)),3))),(double)(1/3))); - - std::cout << "Algebreic:\t" << shortest << std::endl; - } - - return (shortest < this->deltasquared); - -} - - Deleted: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.h 2009-05-27 17:49:29 UTC (rev 3889) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ParameterEstimator.h 2009-05-28 16:37:18 UTC (rev 3890) @@ -1,66 +0,0 @@ -#ifndef _PARAMETER_ESTIMATOR_H_ -#define _PARAMETER_ESTIMATOR_H_ - -#include <vector> -#include <iostream> -#include "vigra/diff2d.hxx" - -/** - * This class defines the interface for parameter estimators. - * Classes which inherit from it can be used by the Ransac class to perform robust - * parameter estimation. - * The interface includes three methods: - * 1.estimate() - Estimation of the parameters using the minimal - * amount of data (exact estimate). - * 2.leastSquaresEstimate() - Estimation of the parameters using - * overdetermined data, so that the estimate - * minimizes a least squres error criteria. - * 3.agree() - Does the given data agree with the model parameters. - * - * Author: Ziv Yaniv - */ - -class ParameterEstimator { -public: - - /** - * Constructor which takes the number of data objects required for an exact - * estimate (e.g. 2 for a line where the data objects are points - */ - ParameterEstimator(unsigned int minForEstimate, double delta); - - /** - * Exact estimation of parameters. - * @param data The data used for the estimate. - * @param parameters This vector is cleared and then filled with the computed parameters. - */ - virtual bool estimate(std::vector<const vigra::Point2D *> &data, std::vector<double> ¶meters); - - /** - * Least squares estimation of parameters. - * @param data The data used for the estimate. - * @param parameters This vector is cleared and then filled with the computed parameters. - */ - virtual void leastSquaresEstimate(std::vector<const vigra::Point2D *> &data, std::vector<double> ¶meters); - - /** - * This method tests if the given data agrees with the given model parameters. - */ - virtual bool agree(std::vector<double> ¶meters, const vigra::Point2D &data, double x_min, double x_max); - - static void debugTest(std::ostream &out); - - /** - * Returns the number of data objects required for an exact - * estimate (e.g. 2 for a line where the data objects are points) - */ - unsigned int numForEstimate() const {return minForEstimate;} -protected: - unsigned int minForEstimate, max_x; - -private: - double deltasquared; //given line L and point P, if dist(L,P)^2 < m_delta^2 then the point is on the line - -}; - -#endif //_PARAMETER_ESTIMATOR_H_ Added: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PolynomialEstimator.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PolynomialEstimator.cpp (rev 0) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PolynomialEstimator.cpp 2009-05-28 16:37:18 UTC (rev 3890) @@ -0,0 +1,219 @@ +#include <cmath> +#include "ParameterEstimator.h" +#include <iostream> +#include "vigra/diff2d.hxx" +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/io.hpp> +#include <levmar/lm.h> +#include "MatrixDeterminant.h" + +using namespace boost::numeric::ublas; +using namespace std; + +double a,b,c,p,q; + +ParameterEstimator::ParameterEstimator(unsigned int m, double delta){ + + // Number of data objects required for an exact + // estimate (e.g. 2 for a line where the data objects are points) + minForEstimate = m; + deltasquared = delta*delta; +} + +bool ParameterEstimator::estimate(std::vector<const vigra::Point2D *> &data, std::vector<double> ¶meters){ + + parameters.clear(); + if(data.size()<this->minForEstimate) + return(false); + + /* Quadratic: ax^2 + bx + c = y + Need to estimate a, b and c + + Using Cramer's Rule + http://en.wikipedia.org/wiki/Cramer%27s_rule + [x_1^2, x_1, 1] [a] [y_1] + [x_2^2, x_2, 1]*[b]=[y_2] + [x_3^2, x_3, 1] [c] [y_3] + + Divisions below are using the determinants of + the matrices + + [ y_1 , x_1, 1] + [ y_2 , x_2, 1] + [ y_3 , x_3, 1] + a = --------------- + [x_1^2, x_1, 1] + [x_2^2, x_2, 1] + [x_3^2, x_3, 1] + + [x_1^2, y_1, 1] + [x_2^2, y_2, 1] + [x_3^2, y_3, 1] + b = --------------- + [x_1^2, x_1, 1] + [x_2^2, x_2, 1] + [x_3^2, x_3, 1] + + [x_1^2, x_1, y_1] + [x_2^2, x_2, y_2] + [x_3^2, x_3, y_3] + c = ----------------- + [x_1^2, x_1, 1] + [x_2^2, x_2, 1] + [x_3^2, x_3, 1] + */ + + matrix<double> m1 (3, 3), m2 (3, 3); + m1 (0,0) = data[0]->x*data[0]->x; + m1 (0,1) = data[0]->x; + m1 (0,2) = 1; + m1 (1,0) = data[1]->x*data[1]->x; + m1 (1,1) = data[1]->x; + m1 (1,2) = 1; + m1 (2,0) = data[2]->x*data[2]->x; + m1 (2,1) = data[2]->x; + m1 (2,2) = 1; + + double d_m1 = determinant(m1); + //std::cout << "Matrix m1:\t" << m1 << std::endl; + //std::cout << "m1 determinant:\t" << d_m1 << std::endl; + + m2 = m1; + m2 (0,0) = data[0]->y; + m2 (1,0) = data[1]->y; + m2 (2,0) = data[2]->y; + + /* + std::cout << "Matrix m2:\t" << m2 << std::endl; + double d_m2_a = determinant(m2); + std::cout << "(a) m2 determinant:\t" << d_m2_a << std::endl; + double a = d_m2_a/d_m1; + */ + double a = determinant(m2)/d_m1; + + m2 = m1; + m2 (0,1) = data[0]->y; + m2 (1,1) = data[1]->y; + m2 (2,1) = data[2]->y; + + /* + std::cout << "Matrix m2:\t" << m2 << std::endl; + double d_m2_b = determinant(m2); + std::cout << "(b) m2 determinant:\t" << d_m2_b << std::endl; + double b = d_m2_b/d_m1; + */ + double b = determinant(m2)/d_m1; + + m2 = m1; + m2 (0,2) = data[0]->y; + m2 (1,2) = data[1]->y; + m2 (2,2) = data[2]->y; + + /* + std::cout << "Matrix m2:\t" << m2 << std::endl; + double d_m2_c = determinant(m2); + std::cout << "(c) m2 determinant:\t" << d_m2_c << std::endl; + double c = d_m2_c/d_m1; + */ + double c = determinant(m2)/d_m1; + + /* + std::cout << "Parameter estimates:" << std::endl; + std::cout << "a:\t" << a << std::endl; + std::cout << "b:\t" << b << std::endl; + std::cout << "c:\t" << c << std::endl << std::endl; + */ + + parameters.push_back(a); + parameters.push_back(b); + parameters.push_back(c); + return(true); + + +} +/*****************************************************************************/ +/* + * Compute the line parameters [n_x,n_y,a_x,a_y] + */ + + + + +void func(double *p, double *x, int m, int n, void *data){ + register int i; + + std::vector<const vigra::Point2D *> * dat = (std::vector<const vigra::Point2D *> *) data; + + for(i=0; i < n; ++i){ + //std::cout << "x = " << (*dat)[i]->x << ", y =" << (*dat)[i]->y << endl; + //[i]= ??? + } +} + +void jacfunc(double *p, double *jac, int m, int n, void *data){} + +void ParameterEstimator::leastSquaresEstimate(std::vector<const vigra::Point2D *> &data, std::vector<double> ¶meters) +{ + + std::cout << "Least squares estimate using LEVMAR..." << std::endl; + + const int n= data.size(), m = 3; // n measurements, 3 parameters + double p[m], x[n], opts[LM_OPTS_SZ], info[LM_INFO_SZ]; + register int i; + int ret; + + for(i=0; i < n; ++i){ + x[i]= 1; + } + + /* initial parameters estimate: (1.0, 1.0, 1.0) */ + p[0]=1.0; p[1]=1.0; p[2]=1.0; + + /* optimization control parameters; passing to levmar NULL instead of opts reverts to defaults */ + opts[0]=LM_INIT_MU; opts[1]=1E-15; opts[2]=1E-15; opts[3]=1E-20; + opts[4]=LM_DIFF_DELTA; // relevant only if the finite difference Jacobian version is used + + /* invoke the optimization function */ + ret=dlevmar_der(func, jacfunc, p, x, m, n, 1000, opts, info, NULL, NULL, &data); // with analytic Jacobian + + printf("Levenberg-Marquardt returned in %g iter, reason %g, sumsq %g [%g]\n", info[5], info[6], info[1], info[0]); + printf("Best fit parameters: %.7g %.7g %.7g\n", p[0], p[1], p[2]); + + parameters.push_back(p[0]); + parameters.push_back(p[1]); + parameters.push_back(p[2]); +} + +bool ParameterEstimator::agree(std::vector<double> ¶meters, const vigra::Point2D &data){ + + double p = data->x; + double q = data->y; + double a = parameters[0]; + double b = parameters[1]; + double c = parameters[2]; + double a2 = a*a; + double a3 = a2*a; + double a4 = a2*a2; + double b2 = b*b; + + double x = + -(b/(2*a)) + - (6*a2 - 3*a2*b2 + 12*a3*c - 12*a3*q) + /(3*pow(2,(2.0/3.0))*a2*pow((54*a3*b + 108*a4*p + + sqrt(pow((54*a3*b + 108*a4*p),2) + 4*pow((6*a2 - 3*a2*b2 + 12*a3*c - 12*a3*q),3)) + ),(1.0/3.0))) + + (1/(6*pow(2,(1.0/3.0))*a2)) + * pow( + (54*a3*b + 108*a4*p + sqrt(pow((54*a3*b + 108*a4*p),2) + + 4*pow((6*a2 - 3*a2*b2 + 12*a3*c - 12*a3*q),3))) + ,(1.0/3.0)); + + double y = (a*(x*x)) + (b*x) + c; + + double distancesquared = abs((p - x) + (q - y)); + + return (distancesquared < this->deltasquared); + +} + + Added: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PolynomialEstimator.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PolynomialEstimator.h (rev 0) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PolynomialEstimator.h 2009-05-28 16:37:18 UTC (rev 3890) @@ -0,0 +1,66 @@ +#ifndef _PARAMETER_ESTIMATOR_H_ +#define _PARAMETER_ESTIMATOR_H_ + +#include <vector> +#include <iostream> +#include "vigra/diff2d.hxx" + +/** + * This class defines the interface for parameter estimators. + * Classes which inherit from it can be used by the Ransac class to perform robust + * parameter estimation. + * The interface includes three methods: + * 1.estimate() - Estimation of the parameters using the minimal + * amount of data (exact estimate). + * 2.leastSquaresEstimate() - Estimation of the parameters using + * overdetermined data, so that the estimate + * minimizes a least squres error criteria. + * 3.agree() - Does the given data agree with the model parameters. + * + * Author: Ziv Yaniv + */ + +class ParameterEstimator { +public: + + /** + * Constructor which takes the number of data objects required for an exact + * estimate (e.g. 2 for a line where the data objects are points + */ + ParameterEstimator(unsigned int minForEstimate, double delta); + + /** + * Exact estimation of parameters. + * @param data The data used for the estimate. + * @param parameters This vector is cleared and then filled with the computed parameters. + */ + virtual bool estimate(std::vector<const vigra::Point2D *> &data, std::vector<double> ¶meters); + + /** + * Least squares estimation of parameters. + * @param data The data used for the estimate. + * @param parameters This vector is cleared and then filled with the computed parameters. + */ + virtual void leastSquaresEstimate(std::vector<const vigra::Point2D *> &data, std::vector<double> ¶meters); + + /** + * This method tests if the given data agrees with the given model parameters. + */ + virtual bool agree(std::vector<double> ¶meters, const vigra::Point2D &data); + + static void debugTest(std::ostream &out); + + /** + * Returns the number of data objects required for an exact + * estimate (e.g. 2 for a line where the data objects are points) + */ + unsigned int numForEstimate() const {return minForEstimate;} +protected: + unsigned int minForEstimate; + +private: + double deltasquared; //given line L and point P, if dist(L,P)^2 < m_delta^2 then the point is on the line + +}; + +#endif //_PARAMETER_ESTIMATOR_H_ Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-05-27 17:49:29 UTC (rev 3889) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-05-28 16:37:18 UTC (rev 3890) @@ -26,7 +26,7 @@ #include "Globals.h" #include "ProcessImage.h" #include "Ransac.h" -#include "ParameterEstimator.h" +#include "SplineEstimator.h" using namespace vigra; using namespace std; @@ -40,7 +40,7 @@ double maximalOutlierPercentage = 0.8; // Use 3 points to calculate a,b and c parameters // Point must be within 0.2 units of curve to agree - ParameterEstimator curveEstimator(3, 0.2); + ParameterEstimator curveEstimator(3, 1); cout << endl << "Computing RANSAC..." << endl; double usedData = Ransac::compute(curveParameters, &curveEstimator, coords, desiredProbabilityForNoOutliers, maximalOutlierPercentage); Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Ransac.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Ransac.h 2009-05-27 17:49:29 UTC (rev 3889) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Ransac.h 2009-05-28 16:37:18 UTC (rev 3890) @@ -38,7 +38,7 @@ #include <boost/random/mersenne_twister.hpp> #include <boost/random/uniform_int.hpp> #include <boost/random/variate_generator.hpp> -#include "ParameterEstimator.h" +#include "SplineEstimator.h" using namespace std; @@ -178,20 +178,6 @@ double maximalOutlierPercentage) { - // Modified by Tim - // Work out range of x coords to sample in agree function - double x_min = 10000000, x_max = -10000000; - for (unsigned i = 0; i < data.size(); i++){ - if (data[i]->x > x_max){ - x_max = data[i]->x; - } - if (data[i]->x < x_min){ - x_min = data[i]->x; - } - } - //std::cout << "X coord range:\t " << x_min << " - " << x_max << std::endl; - // - unsigned int numDataObjects = (int) data.size(); unsigned int numForEstimate = paramEstimator->numForEstimate(); @@ -283,7 +269,7 @@ numVotesForCur = 0; memset(curVotes,'\0',numDataObjects*sizeof(short)); for(j=0; j<(int)numDataObjects; j++) { - if(paramEstimator->agree(exactEstimateParameters, data[j], x_min, x_max)) { + if(paramEstimator->agree(exactEstimateParameters, data[j])) { curVotes[j] = 1; numVotesForCur++; } Added: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Spline.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Spline.cpp (rev 0) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Spline.cpp 2009-05-28 16:37:18 UTC (rev 3890) @@ -0,0 +1,6551 @@ +/*************************************************************************** + * Copyright (C) John Burkardt * + * The computer code and data files described are distributed under the * + * GNU LGPL license. * + ***************************************************************************/ + +# include <cstdlib> +# include <iostream> +# include <iomanip> +# include <cmath> +# include <ctime> + +using namespace std; + +# include "Spline.h" + +//****************************************************************************80 + +double basis_function_b_val ( double tdata[], double tval ) + +//****************************************************************************80 +// +// Purpose: +// +// BASIS_FUNCTION_B_VAL evaluates the B spline basis function. +// +// Discussion: +// +// The B spline basis function is a piecewise cubic which +// has the properties that: +// +// * it equals 2/3 at TDATA(3), 1/6 at TDATA(2) and TDATA(4); +// * it is 0 for TVAL <= TDATA(1) or TDATA(5) <= TVAL; +// * it is strictly increasing from TDATA(1) to TDATA(3), +// and strictly decreasing from TDATA(3) to TDATA(5); +// * the function and its first two derivatives are continuous +// at each node TDATA(I). +// +// Licensing: +// +// This code is distributed under the GNU LGPL license. +// +// Modified: +// +// 24 February 2004 +// +// Author: +// +// John Burkardt +// +// Reference: +// +// Alan Davies, Philip Samuels, +// An Introduction to Computational Geometry for Curves and Surfaces, +// Clarendon Press, 1996, +// ISBN: 0-19-851478-6, +// LC: QA448.D38. +// +// Parameters: +// +// Input, double TDATA(5), the nodes associated with the basis function. +// The entries of TDATA are assumed to be distinct and increasing. +// +// Input, double TVAL, a point at which the B spline basis function is +// to be evaluated. +// +// Output, double BASIS_FUNCTION_B_VAL, the value of the function at TVAL. +// +{ +# define NDATA 5 + + int left; + int right; + double u; + double yval; + + if ( tval <= tdata[0] || tdata[NDATA-1] <= tval ) + { + yval = 0.0; + return yval; + } +// +// Find the interval [ TDATA(LEFT), TDATA(RIGHT) ] containing TVAL. +// + r8vec_bracket ( NDATA, tdata, tval, &left, &right ); +// +// U is the normalized coordinate of TVAL in this interval. +// + u = ( tval - tdata[left-1] ) / ( tdata[right-1] - tdata[left-1] ); +// +// Now evaluate the function. +// + if ( tval < tdata[1] ) + { + yval = pow ( u, 3 ) / 6.0; + } + else if ( tval < tdata[2] ) + { + yval = ( ( ( - 3.0 + * u + 3.0 ) + * u + 3.0 ) + * u + 1.0 ) / 6.0; + } + else if ( tval < tdata[3]) + { + yval = ( ( ( + 3.0 + * u - 6.0 ) + * u + 0.0 ) + * u + 4.0 ) / 6.0; + } + else if ( tval < tdata[4] ) + { + yval = pow ( ( 1.0 - u ), 3 ) / 6.0; + } + + return yval; + +# undef NDATA +} +//****************************************************************************80 + +double basis_function_beta_val ( double beta1, double beta2, double tdata[], + double tval ) + +//****************************************************************************80 +// +// Purpose: +// +// BASIS_FUNCTION_BETA_VAL evaluates the beta spline basis function. +// +// Discussion: +// +// With BETA1 = 1 and BETA2 = 0, the beta spline basis function +// equals the B spline basis function. +// +// With BETA1 large, and BETA2 = 0, the beta spline basis function +// skews to the right, that is, its maximum increases, and occurs +// to the right of the center. +// +// With BETA1 = 1 and BETA2 large, the beta spline becomes more like +// a linear basis function; that is, its value in the outer two intervals +// goes to zero, and its behavior in the inner two intervals approaches +// a piecewise linear function that is 0 at the second node, 1 at the +// third, and 0 at the fourth. +// +// Licensing: +// +// This code is distributed under the GNU LGPL license. +// +// Modified: +// +// 24 February 2004 +// +// Author: +// +// John Burkardt +// +// Reference: +// +// Alan Davies, Philip Samuels, +// An Introduction to Computational Geometry for Curves and Surfaces, +// Clarendon Press, 1996, +// ISBN: 0-19-851478-6, +// LC: QA448.D38. +// +// Parameters: +// +// Input, double BETA1, the skew or bias parameter. +// BETA1 = 1 for no skew or bias. +// +// Input, double BETA2, the tension parameter. +// BETA2 = 0 for no tension. +// +// Input, double TDATA[5], the nodes associated with the basis function. +// The entries of TDATA are assumed to be distinct and increasing. +// +// Input, double TVAL, a point at which the B spline basis function is +// to be evaluated. +// +// Output, double BASIS_FUNCTION_BETA_VAL, the value of the function at TVAL. +// +{ +# define NDATA 5 + + double a; + double b; + double c; + double d; + int left; + int right; + double u; + double yval; + + if ( tval <= tdata[0] || tdata[NDATA-1] <= tval ) + { + yval = 0.0; + return yval; + } +// +// Find the interval [ TDATA(LEFT), TDATA(RIGHT) ] containing TVAL. +// + r8vec_bracket ( NDATA, tdata, tval, &left, &right ); +// +// U is the normalized coordinate of TVAL in this interval. +// + u = ( tval - tdata[left-1] ) / ( tdata[right-1] - tdata[left-1] ); +// +// Now evaluate the function. +// + if ( tval < tdata[1] ) + { + yval = 2.0 * u * u * u; + } + else if ( tval < tdata[2] ) + { + a = beta2 + 4.0 * beta1 + 4.0 * beta1 * beta1 + + 6.0 * ( 1.0 - beta1 * beta1 ) + - 3.0 * ( 2.0 + beta2 + 2.0 * beta1 ) + + 2.0 * ( 1.0 + beta2 + beta1 + beta1 * beta1 ); + + b = - 6.0 * ( 1.0 - beta1 * beta1 ) + + 6.0 * ( 2.0 + beta2 + 2.0 * beta1 ) + - 6.0 * ( 1.0 + beta2 + beta1 + beta1 * beta1 ); + + c = - 3.0 * ( 2.0 + beta2 + 2.0 * beta1 ) + + 6.0 * ( 1.0 + beta2 + beta1 + beta1 * beta1 ); + + d = - 2.0 * ( 1.0 + beta2 + beta1 + beta1 * beta1 ); + + yval = a + b * u + c * u * u + d * u * u * u; + } + else if ( tval < tdata[3] ) + { + a = beta2 + 4.0 * beta1 + 4.0 * beta1 * beta1; + + b = - 6.0 * beta1 * ( 1.0 - beta1 * beta1 ); + + c = - 3.0 * ( beta2 + 2.0 * beta1 * beta1 + + 2.0 * beta1 * beta1 * beta1 ); + + d = 2.0 * ( beta2 + beta1 + beta1 * beta1 + beta1 * beta1 * beta1 ); + + yval = a + b * u + c * u * u + d * u * u * u; + } + else if ( tval < tdata[4] ) + { + yval = 2.0 * pow ( beta1 * ( 1.0 - u ), 3 ); + } + + yval = yval / ( 2.0 + beta2 + 4.0 * beta1 + 4.0 * beta1 * beta1 + + 2.0 * beta1 * beta1 * beta1 ); + + return yval; +# undef NDATA +} +//****************************************************************************80 + +double *basis_matrix_b_uni ( void ) + +//****************************************************************************80 +// +// Purpose: +// +// BASIS_MATRIX_B_UNI sets up the uniform B spline basis matrix. +// +// Licensing: +// +// This code is distributed under the GNU LGPL license. +// +// Modified: +// +// 11 February 2004 +// +// Author: +// +// John Burkardt +// +// Reference: +// +// James Foley, Andries vanDam, Steven Feiner, John Hughes, +// Computer Graphics, Principles and Practice, +// Second Edition, +// Addison Wesley, 1995, +// ISBN: 0201848406, +// LC: T385.C5735. +// +// Parameters: +// +// Output, double BASIS_MATRIX_B_UNI[4*4], the basis matrix. +// +{ + int i; + int j; + double *mbasis; + double mbasis_save[4*4] = { + -1.0 / 6.0, + 3.0 / 6.0, + -3.0 / 6.0, + 1.0 / 6.0, + 3.0 / 6.0, + -6.0 / 6.0, + 0.0, + 4.0 / 6.0, + -3.0 / 6.0, + 3.0 / 6.0, + 3.0 / 6.0, + 1.0 / 6.0, + 1.0 / 6.0, + 0.0, + 0.0, + 0.0 }; + + mbasis = new double[4*4]; + + for ( j = 0; j < 4; j++ ) + { + for ( i = 0; i < 4; i++ ) + { + mbasis[i+j*4] = mbasis_save[i+j*4]; + } + } + + return mbasis; +} +//****************************************************************************80 + +double *basis_matrix_beta_uni ( double beta1, double beta2 ) + +//****************************************************************************80 +// +// Purpose: +// +// BASIS_MATRIX_BETA_UNI sets up the uniform beta spline basis matrix. +// +// Discussion: +// +// If BETA1 = 1 and BETA2 = 0, then the beta spline reduces to +// the B spline. +// +// Licensing: +// +// This code is distributed under the GNU LGPL license. +// +// Modified: +// +// 12 February 2004 +// +// Author: +// +// John Burkardt +// +// Reference: +// +// James Foley, Andries vanDam, Steven Feiner, John Hughes, +// Computer Graphics, Principles and Practice, +// Second Edition, +// Addison Wesley, 1995, +// ISBN: 0201848406, +// LC: T385.C5735. +// +// Parameters: +// +// Input, double BETA1, the skew or bias parameter. +// BETA1 = 1 for no skew or bias. +// +// Input, double BETA2, the tension parameter. +// BETA2 = 0 for no tension. +// +// Output, double BASIS_MATRIX_BETA_UNI[4*4], the basis matrix. +// +{ + double delta; + int i; + int j; + double *mbasis; + + mbasis = new double[4*4]; + + mbasis[0+0*4] = - 2.0 * beta1 * beta1 * beta1; + mbasis[0+1*4] = 2.0 * beta2 + + 2.0 * beta1 * ( beta1 * beta1 + beta1 + 1.0 ); + mbasis[0+2*4] = - 2.0 * ( beta2 + beta1 * beta1 + beta1 + 1.0 ); + mbasis[0+3*4] = 2.0; + + mbasis[1+0*4] = 6.0 * beta1 * beta1 * beta1; + mbasis[1+1*4] = - 3.0 * beta2 + - 6.0 * beta1 * beta1 * ( beta1 + 1.0 ); + mbasis[1+2*4] = 3.0 * beta2 + 6.0 * beta1 * beta1; + mbasis[1+3*4] = 0.0; + + mbasis[2+0*4] = - 6.0 * beta1 * beta1 * beta1; + mbasis[2+1*4] = 6.0 * beta1 * ( beta1 - 1.0 ) * ( beta1 + 1.0 ); + mbasis[2+2*4] = 6.0 * beta1; + mbasis[2+3*4] = 0.0; + + mbasis[3+0*4] = 2.0 * beta1 * beta1 * beta1; + mbasis[3+1*4] = 4.0 * beta1 * ( beta1 + 1.0 ) + beta2; + mbasis[3+2*4] = 2.0; + mbasis[3+3*4] = 0.0; + + delta = ( ( 2.0 + * beta1 + 4.0 ) + * beta1 + 4.0 ) + * beta1 + 2.0 + beta2; + + for ( j = 0; j < 4; j++ ) + { + for ( i = 0; i < 4; i++ ) + { + mbasis[i+j*4] = mbasis[i+j*4] / delta; + } + } + + return mbasis; +} +//****************************************************************************80 + +double *basis_matrix_bezier ( void ) + +//****************************************************************************80 +// +// Purpose: +// +// BASIS_MATRIX_BEZIER_UNI sets up the cubic Bezier spline basis matrix. +// +// Discussion: +// +// This basis matrix assumes that the data points are stored as +// ( P1, P2, P3, P4 ). P1 is the function value at T = 0, while +// P2 is used to approximate the derivative at T = 0 by +// dP/dt = 3 * ( P2 - P1 ). Similarly, P4 is the function value +// at T = 1, and P3 is used to approximate the derivative at T = 1 +// by dP/dT = 3 * ( P4 - P3 ). +// +// Licensing: +// +// This code is distributed under the GNU LGPL license. +// +// Modified: +// +// 13 February 2004 +// +// Author: +// +// John Burkardt +// +// Reference: +// +// James Foley, Andries vanDam, Steven Feiner, John Hughes, +// Computer Graphics, Principles and Practice, +// Second Edition, +// Addison Wesley, 1995, +// ISBN: 0201848406, +// LC: T385.C5735. +// +// Parameters: +// +// Output, double BASIS_MATRIX_BEZIER[4*4], the basis matrix. +// +{ + double *mbasis; + + mbasis = new double[4*4]; + + mbasis[0+0*4] = -1.0; + mbasis[0+1*4] = 3.0; + mbasis[0+2*4] = -3.0; + mbasis[0+3*4] = 1.0; + + mbasis[1+0*4] = 3.0; + mbasis[1+1*4] = -6.0; + mbasis[1+2*4] = 3.0; + mbasis[1+3*4] = 0.0; + + mbasis[2+0*4] = -3.0; + mbasis[2+1*4] = 3.0; + mbasis[2+2*4] = 0.0; + mbasis[2+3*4] = 0.0; + + mbasis[3+0*4] = 1.0; + mbasis[3+1*4] = 0.0; + mbasis[3+2*4] = 0.0; + mbasis[3+3*4] = 0.0; + + return mbasis; +} +//****************************************************************************80 + +double *basis_matrix_hermite ( void ) + +//****************************************************************************80 +// +// Purpose: +// +// BASIS_MATRIX_HERMITE sets up the Hermite spline basis matrix. +// +// Discussion: +// +// This basis matrix assumes that the data points are stored as +// ( P1, P2, P1', P2' ), with P1 and P1' being the data value and +// the derivative dP/dT at T = 0, while P2 and P2' apply at T = 1. +// +// Licensing: +// +// This code is distributed under the GNU LGPL license. +// +// Modified: +// +// 13 February 2004 +// +// Author: +// +// John Burkardt +// +// Reference: +// +// James Foley, Andries vanDam, Steven Feiner, John Hughes, +// Computer Graphics, Principles and Practice, +// Second Edition, +// Addison Wesley, 1995, +// ISBN: 0201848406, +// LC: T385.C5735. +// +// Parameters: +// +// Output, double BASIS_MATRIX_HERMITE[4*4], the basis matrix. +// +{ + double *mbasis; + + mbasis = new double[4*4]; + + mbasis[0+0*4] = 2.0; + mbasis[0+1*4] = -2.0; + mbasis[0+2*4] = 1.0; + mbasis[0+3*4] = 1.0; + + mbasis[1+0*4] = -3.0; + mbasis[1+1*4] = 3.0; + mbasis[1+2*4] = -2.0; + mbasis[1+3*4] = -1.0; + + mbasis[2+0*4] = 0.0; + mbasis[2+1*4] = 0.0; + mbasis[2+2*4] = 1.0; + mbasis[2+3*4] = 0.0; + + mbasis[3+0*4] = 1.0; + mbasis[3+1*4] = 0.0; + mbasis[3+2*4] = 0.0; + mbasis[3+3*4] = 0.0; + + return mbasis; +} +//****************************************************************************80 + +double *basis_matrix_overhauser_nonuni ( double alpha, double beta ) + +//****************************************************************************80 +// +// Purpose: +// +// BASIS_MATRIX_OVERHAUSER_NONUNI sets the nonuniform Overhauser spline basis matrix. +// +// Discussion: +// +// This basis matrix assumes that the data points P1, P2, P3 and +// P4 are not uniformly spaced in T, and that P2 corresponds to T = 0, +// and P3 to T = 1. +// +// Licensing: +// +// This code is distributed under the GNU LGPL license. +// +// Modified: +// +// 13 February 2004 +// +// Author: +// +// John Burkardt +// +// Parameters: +// +// Input, double ALPHA, BETA. +// ALPHA = || P2 - P1 || / ( || P3 - P2 || + || P2 - P1 || ) +// BETA = || P3 - P2 || / ( || P4 - P3 || + || P3 - P2 || ). +// +// Output, double BASIS_MATRIX_OVERHAUSER_NONUNI[4*4], the basis matrix. +// +{ + double *mbasis; + + mbasis = new double[4*4]; + + mbasis[0+0*4] = - ( 1.0 - alpha ) * ( 1.0 - alpha ) / alpha; + mbasis[0+1*4] = beta + ( 1.0 - alpha ) / alpha; + mbasis[0+2*4] = alpha - 1.0 / ( 1.0 - beta ); + mbasis[0+3*4] = beta * beta / ( 1.0 - beta ); + + mbasis[1+0*4] = 2.0 * ( 1.0 - alpha ) * ( 1.0 - alpha ) / alpha; + mbasis[1+1*4] = ( - 2.0 * ( 1.0 - alpha ) - alpha * beta ) / alpha; + mbasis[1+2*4] = ( 2.0 * ( 1.0 - alpha ) + - beta * ( 1.0 - 2.0 * alpha ) ) / ( 1.0 - beta ); + mbasis[1+3*4] = - beta * beta / ( 1.0 - beta ); + + mbasis[2+0*4] = - ( 1.0 - alpha ) * ( 1.0 - alpha ) / alpha; + mbasis[2+1*4] = ( 1.0 - 2.0 * alpha ) / alpha; + mbasis[2+2*4] = alpha; + mbasis[2+3*4] = 0.0; + + mbasis[3+0*4] = 0.0; + mbasis[3+1*4] = 1.0; + mbasis[3+2*4] = 0.0; + mbasis[3+3*4] = 0.0; + + return mbasis; +} +//****************************************************************************80 + +double *basis_matrix_overhauser_nul ( double alpha ) + +//****************************************************************************80 +// +// Purpose: +// +// BASIS_MATRIX_OVERHAUSER_NUL sets the nonuniform left Overhauser spline basis matrix. +// +// Discussion: +// +// This basis matrix assumes that the data points P1, P2, and +// P3 are not uniformly spaced in T, and that P1 corresponds to T = 0, +// and P2 to T = 1. (???) +// +// Licensing: +// +// This code is distributed under the GNU LGPL license. +// +// Modified: +// +// 13 February 2004 +// +// Author: +// +// John Burkardt +// +// Parameters: +// +// Input, double ALPHA. +// ALPHA = || P2 - P1 || / ( || P3 - P2 || + || P2 - P1 || ) +// +// Output, double BASIS_MATRIX_OVERHAUSER_NUL[3*3], the basis matrix. +// +{ + double *mbasis; + + mbasis = new double[3*3]; + + mbasis[0+0*3] = 1.0 / alpha; + mbasis[0+1*3] = - 1.0 / ( alpha * ( 1.0 - alpha ) ); + mbasis[0+2*3] = 1.0 / ( 1.0 - alpha ); + + mbasis[1+0*3] = - ( 1.0 + alpha ) / alpha; + mbasis[1+1*3] = 1.0 / ( alpha * ( 1.0 - alpha ) ); + mbasis[1+2*3] = - alpha / ( 1.0 - alpha ); + + mbasis[2+0*3] = 1.0; + mbasis[2+1*3] = 0.0; + mbasis[2+2*3] = 0.0; + + return mbasis; +} +//****************************************************************************80 + +double *basis_matrix_overhauser_nur ( double beta ) + +//****************************************************************************80 +// +// Purpose: +// +// BASIS_MATRIX_OVERHAUSER_NUR sets the nonuniform right Overhauser spline basis matrix. +// +// Discussion: +// +// This basis matrix assumes that the data points PN-2, PN-1, and +// PN are not uniformly spaced in T, and that PN-1 corresponds to T = 0, +// and PN to T = 1. (???) +// +// Licensing: +// +// This code is distributed under the GNU LGPL license. +// +// Modified: +// +// 14 February 2004 +// +// Author: +// +// John Burkardt +// +// Parameters: +// +// Input, double BETA. +// BETA = || P(N) - P(N-1) || / ( || P(N) - P(N-1) || + || P(N-1) - P(N-2) || ) +// +// Output, double BASIS_MATRIX_OVERHAUSER_NUR[3*3], the basis matrix. +// +{ + double *mbasis; + + mbasis = new double[3*3]; + + mbasis[0+0*3] = 1.0 / beta; + mbasis[0+1*3] = - 1.0 / ( beta * ( 1.0 - beta ) ); + mbasis[0+2*3] = 1.0 / ( 1.0 - beta ); + + mbasis[1+0*3] = - ( 1.0 + beta ) / beta; + mbasis[1+1*3] = 1.0 / ( beta * ( 1.0 - beta ) ); + mbasis[1+2*3] = - beta / ( 1.0 - beta ); + + mbasis[2+0*3] = 1.0; + mbasis[2+1*3] = 0.0; + mbasis[2+2*3] = 0.0; + + return mbasis; +} +//****************************************************************************80 + +double *basis_matrix_overhauser_uni ( void) + +//****************************************************************************80 +// +// Purpose: +// +// BASIS_MATRIX_OVERHAUSER_UNI sets the uniform Overhauser spline basis matrix. +// +// Discussion: +// +// This basis matrix assumes that the data points P1, P2, P3 and +// P4 are uniformly spaced in T, and that P2 corresponds to T = 0, +// and P3 to T = 1. +// +// Licensing: +// +// This code is distributed under the GNU LGPL license. +// +// Modified: +// +// 14 February 2004 +// +// Author: +// +// John Burkardt +// +// Reference: +// +// James Foley, Andries vanDam, Steven Feiner, John Hughes, +// Computer Graphics, Principles and Practice, +// Second Edition, +// Addison Wesley, 1995, +// ISBN: 0201848406, +// LC: T385.C5735. +// +// Parameters: +// +// Output, double BASIS_MATRIX_OVERHASUER_UNI[4*4], the basis matrix. +// +{ + double *mbasis; + + mbasis = new double[4*4]; + + mbasis[0+0*4] = - 1.0 / 2.0; + mbasis[0+1*4] = 3.0 / 2.0; + mbasis[0+2*4] = - 3.0 / 2.0; + mbasis[0+3*4] = 1.0 / 2.0; + + mbasis[1+0*4] = 2.0 / 2.0; + mbasis[1+1*4] = - 5.0 / 2.0; + mbasis[1+2*4] = 4.0 / 2.0; + mbasis[1+3*4] = - 1.0 / 2.0; + + mbasis[2+0*4] = - 1.0 / 2.0; + mbasis[2+1*4] = 0.0; + mbasis[2+2*4] = 1.0 / 2.0; + mbasis[2+3*4] = 0.0; + + mbasis[3+0*4] = 0.0; + mbasis[3+1*4] = 2.0 / 2.0; + mbasis[3+2*4] = 0.0; + mbasis[3+3*4] = 0.0; + + return mbasis; +} +//****************************************************************************80 + +double *basis_matrix_overhauser_uni_l ( void ) + +//****************************************************************************80 +// +// Purpose: +// +// BASIS_MATRIX_OVERHAUSER_UNI_L sets the left uniform Overhauser spline basis matrix. +// +// Discussion: +// +// This basis matrix assumes that the data points P1, P2, and P3 +// are not uniformly spaced in T, and that P1 corresponds to T = 0, +// and P2 to T = 1. +// +// Licensing: +// +// This code is distributed under the GNU LGPL license. +// +// Modified: +// +// 14 February 2004 +// +// Author: +// +// John Burkardt +// +// Parameters: +// +// Output, double BASIS_MATRIX_OVERHASUER_UNI_L[3*3], the basis matrix. +// +{ + double *mbasis; + + mbasis = new double[3*3]; + + mbasis[0+0*3] = 2.0; + mbasis[0+1*3] = - 4.0; + mbasis[0+2*3] = 2.0; + + mbasis[1+0*3] = - 3.0; + mbasis[1+1*3] = 4.0; + mbasis[1+2*3] = - 1.0; + + mbasis[2+0*3] = 1.0; + mbasis[2+1*3] = 0.0; + mbasis[2+2*3] = 0.0; + + return mbasis; +} +//****************************************************************************80 + +double *basis_matrix_overhauser_uni_r ( void ) + +//****************************************************************************80 +// +// Purpose: +// +// BASIS_MATRIX_OVERHAUSER_UNI_R sets the right uniform Overhauser spline basis matrix. +// +// Discussion: +// +// This basis matrix assumes that the data points P(N-2), P(N-1), +// and P(N) are uniformly spaced in T, and that P(N-1) corresponds to +// T = 0, and P(N) to T = 1. +// +// Licensing: +// +// This code is distributed under the GNU LGPL license. +// +// Modified: +// +// 14 February 2004 +// +// Author: +// +// John Burkardt +// +// Parameters: +// +// Output, double BASIS_MATRIX_OVERHASUER_UNI_R[3*3], the basis matrix. +// +{ + double *mbasis; + + mbasis = new double[3*3]; + + mbasis[0+0*3] = 2.0; + mbasis[0+1*3] = - 4.0; + mbasis[0+2*3] = 2.0; + + mbasis[1+0*3] = - 3.0; + mbasis[1+1*3] = 4.0; + mbasis[1+2*3] = - 1.0; + + mbasis[2+0*3] = 1.0; + mbasis[2+1*3] = 0.0; + mbasis[2+2*3] = 0.0; + + return mbasis; +} +//****************************************************************************80 + +double basis_matrix_tmp ( int left, int n, double mbasis[], int ndata, + double tdata[], double ydata[], double tval ) + +//****************************************************************************80 +// +// Purpose: +// +// BASIS_MATRIX_TMP computes Q = T * MBASIS * P +// +// Discussion: +// +// YDATA is a vector of data values, most frequently the values of some +// function sampled at uniformly spaced points. MBASIS is the basis +// matrix for a particular kind of spline. T is a vector of the +// powers of the normalized difference between TVAL and the left +// endpoint of the interval. +// +// Licensing: +// +// This code is distributed under the GNU LGPL license. +// +// Modified: +// +// 14 February 2004 +// +// Author: +// +// John Burkardt +// +// Parameters: +// +// Input, int LEFT, indicats that TVAL is in the interval +// [ TDATA(LEFT), TDATA(LEFT+1) ], or that this is the "nearest" +// interval to TVAL. +// For TVAL < TDATA(1), use LEFT = 1. +// For TDATA(NDATA) < TVAL, use LEFT = NDATA - 1. +// +// Input, int N, the order of the basis matrix. +// +// Input, double MBASIS[N*N], the basis matrix. +// +// Input, int NDATA, the dimension of the vectors TDATA and YDATA. +// +// Input, double TDATA[NDATA], the abscissa values. This routine +// assumes that the TDATA values are uniformly spaced, with an +// increment of 1.0. +// +// Input, double YDATA[NDATA], the data values to be interpolated or +// approximated. +// +// Input, double TVAL, the value of T at which the spline is to be +// evaluated. +// +// Output, double BASIS_MATRIX_TMP, the value of the spline at TVAL. +// +{ + double arg; + int first; + int i; + int j; + double temp; + double tm; + double *tvec; + double yval; + + tvec = new double[n]; + + if ( left == 1 ) + { + arg = 0.5 * ( tval - tdata[left-1] ); + first = left; + } + else if ( left < ndata - 1 ) + { + arg = tval - tdata[left-1]; + first = left - 1; + } + else if ( left == ndata - 1 ) + { + arg = 0.5 * ( 1.0 + tval - tdata[left-1] ); + first = left - 1; + } +// +// TVEC(I) = ARG**(N-I). +// + tvec[n-1] = 1.0; + for ( i = n-2; 0 <= i; i-- ) + { + tvec[i] = arg * tvec[i+1]; + } + + yval = 0.0; + for ( j = 0; j < n; j++ ) + { + tm = 0.0; + for ( i = 0; i < n; i++ ) + { + tm = tm + tvec[i] * mbasis[i+j*n]; + } + yval = yval + tm * ydata[first - 1 + j]; + } + + delete [] tvec; + + return yval; +} +//****************************************************************************80 + +void bc_val ( int n, double t, double xcon[], double ycon[], double *xval, + double *yval ) + +//****************************************************************************80 +// +// Purpose: +// +// BC_VAL evaluates a parameterized Bezier curve. +// +// Discussion: +// +// BC_VAL(T) is the value of a vector function of the form +// +// BC_VAL(T) = ( X(T), Y(T) ) +// +// where +// +// X(T) = Sum ( 0 <= I <= N ) XCON(I) * BERN(I,N)(T) +// Y(T) = Sum ( 0 <= I <= N ) YCON(I) * BERN(I,N)(T) +// +// BERN(I,N)(T) is the I-th Bernstein polynomial of order N +// defined on the interval [0,1], +// +// XCON(0:N) and YCON(0:N) are the coordinates of N+1 "control points". +// +// Licensing: +// +// This code is distributed under the GNU LGPL license. +// +// Modified: +// +// 12 February 2004 +// +// Author: +// +// John Burkardt +// +// Reference: +// +// David Kahaner, Cleve Moler, Steven Nash, +// Numerical Methods and Software, +// Prentice Hall, 1989, +// ISBN: 0-13-627258-4, +// LC: TA345.K34. +// +// Parameters: +// +// Input, int N, the order of the Bezier curve, which +// must be at least 0. +// +// Input, double T, the point at which the Bezier curve should +// be evaluated. The best results are obtained within the interval +// [0,1] but T may be anywhere. +// +// Input, double XCON[0:N], YCON[0:N], the X and Y coordinates +// of the control points. The Bezier curve will pass through +// the points ( XCON(0), YCON(0) ) and ( XCON(N), YCON(N) ), but +// generally NOT through the other control points. +// +// Output, double *XVAL, *YVAL, the X and Y coordinates of the point +// on the Bezier curve corresponding to the given T value. +// +{ + double *bval; + int i; + + bval = bp01 ( n, t ); + + *xval = 0.0; + for ( i = 0; i <= n; i++ ) + { + *xval = *xval + xcon[i] * bval[i]; + } + + *yval = 0.0; + for ( i = 0; i <= n; i++ ) + { + *yval = *yval + ycon[i] * bval[i]; + } + + delete [] bval; + + return; +} +//****************************************************************************80 + +double bez_val ( int n, double x, double a, double b, double y[] ) + +//****************************************************************************80 +// +// Purpose: +// +// BEZ_VAL evaluates a Bezier function at a point. +// +// Discussion: +// +// The Bezier function has the form: +// +// BEZ(X) = Sum ( 0 <= I <= N ) Y(I) * BERN(N,I)( (X-A)/(B-A) ) +// +// BERN(N,I)(X) is the I-th Bernstein polynomial of order N +// defined on the interval [0,1], +// +// Y(0:N) is a set of coefficients, +// +// and if, for I = 0 to N, we define the N+1 points +// +// X(I) = ( (N-I)*A + I*B) / N, +// +// equally spaced in [A,B], the pairs ( X(I), Y(I) ) can be regarded as +// "control points". +// +// Licensing: +// +// This code is distributed under the GNU LGPL license. +// +// Modified: +// +// 12 February 2004 +// +// Author: +// +// John Burkardt +// +// Reference: +// +// David Kahaner, Cleve Moler, Steven Nash, +// Numerical Methods and Software, +// Prentice Hall, 1989, +// ISBN: 0-13-627258-4, +// LC: TA345.K34. +// +// Parameters: +// +// Input, int N, the order of the Bezier function, which +// must be at least 0. +// +// Input, double X, the point at which the Bezier function should +// be evaluated. The best results are obtained within the interval +// [A,B] but X may be anywhere. +// +// Input, double A, B, the interval over which the Bezier function +// has been defined. This is the interval in which the control +// points have been set up. Note BEZ(A) = Y(0) and BEZ(B) = Y(N), +// although BEZ will not, in general pass through the other +// control points. A and B must not be equal. +// +// Input, double Y[0:N], a set of data defining the Y coordinates +// of the control points. +// +// Output, double BEZ_VAL, the value of the Bezier function at X. +// +{ + double *bval; + int i; + double value; + double x01; + + if ( b - a == 0.0 ) + { + cout << "\n"; + cout << "BEZ_VAL - Fatal error!\n"; + cout << " Null interval, A = B = " << a << "\n"; + exit ( 1 ); + } +// +// X01 lies in [0,1], in the same relative position as X in [A,B]. +// + x01 = ( x - a ) / ( b - a ); + + bval = bp01 ( n, x01 ); + + value = 0.0; + for ( i = 0; i <= n; i++ ) + { + value = value + y[i] * bval[i]; + } + + delete [] bval; + + return value; +} +//****************************************************************************80 + +double bp_approx ( int n, double a, double b, double ydata[], double xval ) + +//****************************************************************************80 +// +// Purpose: +// +// BP_APPROX evaluates the Bernstein polynomial for F(X) on [A,B]. +// +// Formula: +// +// BERN(F)(X) = sum ( 0 <= I <= N ) F(X(I)) * B_BASE(I,X) +// +// where +// +// X(I) = ( ( N - I ) * A + I * B ) / N +// B_BASE(I,X) is the value of the I-th Bernstein basis polynomial at X. +// +// Discussion: +// +// The Bernstein polynomial BERN(F) for F(X) is an approximant, not an +// interpolant; in other words, its value is not guaranteed to equal +// that of F at any particular point. However, for a fixed interval +// [A,B], if we let N increase, the Bernstein polynomial converges +// uniformly to F everywhere in [A,B], provided only that F is continuous. +// Even if F is not continuous, but is bounded, the polynomial converges +// pointwise to F(X) at all points of continuity. On the other hand, +// the convergence is quite slow compared to other interpolation +// and approximation schemes. +// +// Licensing: +// +// This code is distributed under the GNU LGPL license. +// +// Modified: +// +// 12 February 2004 +// +// Author: +// +// John Burkardt +// +// Reference: +// +// David Kahaner, Cleve Moler, Steven Nash, +// Numerical Methods and Software, +// Prentice Hall, 1989, +// ISBN: 0-13-627258-4, +// LC: TA345.K34. +// +// Parameters: +// +// Input, int N, the degree of the Bernstein polynomial to be used. +// +// Input, double A, B, the endpoints of the interval on which the +// approximant is based. A and B should not be equal. +// +// Input, double YDATA[0:N], the data values at N+1 equally spaced points +// in [A,B]. If N = 0, then the evaluation point should be 0.5 * ( A + B). +// Otherwise, evaluation point I should be ( (N-I)*A + I*B ) / N ). +// +// Input, double XVAL, the point at which the Bernstein polynomial +// approximant is to be evaluated. XVAL does not have to lie in the +// interval [A,B]. +// +// Output, double BP_APPROX, the value of the Bernstein polynomial approximant +// for F, based in [A,B], evaluated at XVAL. +// +{ + double *bvec; + int i; + double yval; +// +// Evaluate the Bernstein basis polynomials at XVAL. +// + bvec = bpab ( n, a, b, xval ); +// +// Now compute the sum of YDATA(I) * BVEC(I). +// + yval = 0.0; + + for ( i = 0; i <= n; i++ ) + { + yval = yval + ydata[i] * bvec[i]; + } + delete [] bvec; + + return yval; +} +//****************************************************************************80 + +double *bp01 ( int n, double x ) + +//****************************************************************************80 +// +// Purpose: +// +// BP01 evaluates the Bernstein basis polynomials for [0,1] at a point. +// +// Discussion: +// +// For any N greater than or equal to 0, there is a set of N+1 Bernstein +// basis polynomials, each of degree N, which form a basis for +// all polynomials of degree N on [0,1]. +// +// Formula: +// +// BERN(N,I,X) = [N!/(I!*(N-I)!)] * (1-X)**(N-I) * X**I +// +// N is the degree; +// +// 0 <= I <= N indicates which of the N+1 basis polynomials +// of degree N to choose; +// +// X is a point in [0,1] at which to evaluate the basis polynomial. +// +// First values: +// +// B(0,0,X) = 1 +// +// B(1,0,X) = 1-X +// B(1,1,X) = X +// +// B(2,0,X) = (1-X)**2 +// B(2,1,X) = 2 * (1-X) * X +// B(2,2,X) = X**2 +// +// B(3,0,X) = (1-X)**3 +// B(3,1,X) = 3 * (1-X)**2 * X +// B(3,2,X) = 3 * (1-X) * X**2 +// B(3,3,X) = X**3 +// +// B(4,0,X) = (1-X)**4 +// B(4,1,X) = 4 * (1-X)**3 * X +// B(4,2,X) = 6 * (1-X)**2 * X**2 +// B(4,3,X) = 4 * (1-X) * X**3 +// B(4,4,X) = X**4 +// +// Special values: +// +// B(N,I,1/2) = C(N,K) / 2**N +// +// Licensing: +// +// This code is distributed under the GNU LGPL license. +// +// Modified: +// +// 12 February 2004 +// +// Author: +// +// John Burkardt +// +// Reference: +// +// David Kahaner, Cleve Moler, Steven Nash, +// Numerical Methods and Software, +// Prentice Hall, 1989, +// ISBN: 0-13-627258-4, +// LC: TA345.K34. +// +// Parameters: +// +// Input, int N, the degree of the Bernstein basis polynomials. +// +// Input, double X, the evaluation point. +// +// Output, double BP01[0:N], the values of the N+1 Bernstein basis +// polynomials at X. +// +{ + double *bern; + int i; + int j; + + bern = new double[n+1]; + + if ( n == 0 ) + { + bern[0] = 1.0; + } + else if ( 0 < n ) + { + bern[0] = 1.0 - x; + bern[1] = x; + + for ( i = 2; i <= n; i++ ) + { + bern[i] = x * bern[i-1]; + for ( j = i-1; 1 <= j; j-- ) + { + bern[j] = x * bern[j-1] + ( 1.0 - x ) * bern[j]; + } + bern[0] = ( 1.0 - x ) * bern[0]; + } + + } + + return bern; +} +//****************************************************************************80 + +double *bpab ( int n, double a, double b,... [truncated message content] |
From: <bl...@us...> - 2009-05-29 16:36:58
|
Revision: 3892 http://hugin.svn.sourceforge.net/hugin/?rev=3892&view=rev Author: blimbo Date: 2009-05-29 16:36:52 +0000 (Fri, 29 May 2009) Log Message: ----------- Added spline parameter estimator Modified Paths: -------------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/SplineEstimator.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/SplineEstimator.h Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/SplineEstimator.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/SplineEstimator.cpp 2009-05-29 05:23:39 UTC (rev 3891) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/SplineEstimator.cpp 2009-05-29 16:36:52 UTC (rev 3892) @@ -1,165 +1,187 @@ #include "SplineEstimator.h" #include <cmath> +#include <iomanip> #include <iostream> #include "vigra/diff2d.hxx" -#include <boost/numeric/ublas/matrix.hpp> -#include <boost/numeric/ublas/io.hpp> #include <levmar/lm.h> #include "MatrixDeterminant.h" #include "Spline.h" -using namespace boost::numeric::ublas; using namespace std; + +double frunge (double x); +double fprunge (double x); +double fpprunge (double x); + double a,b,c,p,q; +bool compare (const vigra::Point2D * i,const vigra::Point2D * j) { + return (i->x<j->x); +} + + ParameterEstimator::ParameterEstimator(unsigned int m, double delta){ - // Number of data objects required for an exact - // estimate (e.g. 2 for a line where the data objects are points) minForEstimate = m; deltasquared = delta*delta; } bool ParameterEstimator::estimate(std::vector<const vigra::Point2D *> &data, std::vector<double> ¶meters){ - parameters.clear(); - if(data.size()<this->minForEstimate) + parameters.clear(); + if(data.size()<this->minForEstimate){ return(false); + } + + sort(data.begin(), data.end(), compare); + if((data[0]->x == data[1]->x)||(data[1]->x == data[2]->x)){ + return(false); + } - /* Quadratic: ax^2 + bx + c = y - Need to estimate a, b and c - - Using Cramer's Rule - http://en.wikipedia.org/wiki/Cramer%27s_rule - [x_1^2, x_1, 1] [a] [y_1] - [x_2^2, x_2, 1]*[b]=[y_2] - [x_3^2, x_3, 1] [c] [y_3] - - Divisions below are using the determinants of - the matrices - - [ y_1 , x_1, 1] - [ y_2 , x_2, 1] - [ y_3 , x_3, 1] - a = --------------- - [x_1^2, x_1, 1] - [x_2^2, x_2, 1] - [x_3^2, x_3, 1] - - [x_1^2, y_1, 1] - [x_2^2, y_2, 1] - [x_3^2, y_3, 1] - b = --------------- - [x_1^2, x_1, 1] - [x_2^2, x_2, 1] - [x_3^2, x_3, 1] - - [x_1^2, x_1, y_1] - [x_2^2, x_2, y_2] - [x_3^2, x_3, y_3] - c = ----------------- - [x_1^2, x_1, 1] - [x_2^2, x_2, 1] - [x_3^2, x_3, 1] + /* + Cubic splines have 2n+2 parameters, where n is the number of + data points. The first n parameters are the x-values. The next + n parameters are the y-values. The last two parameters are + the values of the derivative at the first and last point. For natural + splines, these parameters are unused. + + http://www.extremeoptimization.com/QuickStart/CubicSplinesVB.aspx + */ - matrix<double> m1 (3, 3), m2 (3, 3); - m1 (0,0) = data[0]->x*data[0]->x; - m1 (0,1) = data[0]->x; - m1 (0,2) = 1; - m1 (1,0) = data[1]->x*data[1]->x; - m1 (1,1) = data[1]->x; - m1 (1,2) = 1; - m1 (2,0) = data[2]->x*data[2]->x; - m1 (2,1) = data[2]->x; - m1 (2,2) = 1; + for(int i = 0; i < data.size(); i++){ + parameters.push_back(data[i]->x); + } + for(int i = 0; i < data.size(); i++){ + parameters.push_back(data[i]->y); + } - double d_m1 = determinant(m1); - //std::cout << "Matrix m1:\t" << m1 << std::endl; - //std::cout << "m1 determinant:\t" << d_m1 << std::endl; +// - m2 = m1; - m2 (0,0) = data[0]->y; - m2 (1,0) = data[1]->y; - m2 (2,0) = data[2]->y; + int N = data.size(); + int i; + int ibcbeg; + int ibcend; + int j; + int jhi; + int k; + double t[N]; + double tval; + double y[N]; + double ybcbeg; + double ybcend; + double *ypp; + double yppval; + double ypval; + double yval; - /* - std::cout << "Matrix m2:\t" << m2 << std::endl; - double d_m2_a = determinant(m2); - std::cout << "(a) m2 determinant:\t" << d_m2_a << std::endl; - double a = d_m2_a/d_m1; - */ - double a = determinant(m2)/d_m1; + cout << "SPLINE_CUBIC_SET sets up a cubic spline;\n"; + cout << "SPLINE_CUBIC_VAL evaluates it.\n"; + cout << "\n"; + cout << "Runge's function, evenly spaced knots.\n\n"; + // Points (knots?) are not evenly spaced - is this important? + cout << "I\tT\tY\n\n"; + for ( i = 0; i < N; i++ ) { + t[i] = data[i]->x; + y[i] = data[i]->y; + cout << i << "\t" << t[i] << "\t" << y[i] << "\n"; + } - m2 = m1; - m2 (0,1) = data[0]->y; - m2 (1,1) = data[1]->y; - m2 (2,1) = data[2]->y; - /* - std::cout << "Matrix m2:\t" << m2 << std::endl; - double d_m2_b = determinant(m2); - std::cout << "(b) m2 determinant:\t" << d_m2_b << std::endl; - double b = d_m2_b/d_m1; - */ - double b = determinant(m2)/d_m1; + ibcbeg = 1; + ybcbeg = fprunge ( t[0] ); - m2 = m1; - m2 (0,2) = data[0]->y; - m2 (1,2) = data[1]->y; - m2 (2,2) = data[2]->y; + ibcend = 1; + ybcend = fprunge ( t[N-1] ); - /* - std::cout << "Matrix m2:\t" << m2 << std::endl; - double d_m2_c = determinant(m2); - std::cout << "(c) m2 determinant:\t" << d_m2_c << std::endl; - double c = d_m2_c/d_m1; - */ - double c = determinant(m2)/d_m1; + cout << "\nBoundary condition 1 at both ends:\n"; + cout << "Y'(left) = " << ybcbeg << "\n"; + cout << "Y'(right) = " << ybcend << "\n"; - /* - std::cout << "Parameter estimates:" << std::endl; - std::cout << "a:\t" << a << std::endl; - std::cout << "b:\t" << b << std::endl; - std::cout << "c:\t" << c << std::endl << std::endl; - */ + // Are these values the derivatives needed to complete the paramaters + // or do i get them by calling spline_cubic_val for 1st and last values? + //parameters.push_back(ybcbeg); + //parameters.push_back(ybcend); + // Can we return here? - parameters.push_back(a); - parameters.push_back(b); - parameters.push_back(c); - return(true); + ypp = spline_cubic_set ( N, t, y, ibcbeg, ybcbeg, ibcend, ybcend ); + cout << "\n"; + cout << "SPLINE''(T)\tF''(T):\n"; + cout << "\n"; + for ( i = 0; i < N; i++ ){ + cout << ypp[i] << "\t" << fpprunge (t[i]) << "\n"; + } -} -/*****************************************************************************/ -/* - * Compute the line parameters [n_x,n_y,a_x,a_y] - */ + cout << "\n"; + cout << "T\tSPLINE(T)\tF(T)\n"; + cout << "\n"; + for ( i = 0; i <= N; i++ ){ + + if ( i == 0 ){ + jhi = 1; + }else if ( i < N ){ + jhi = 2; + }else{ + jhi = 2; + } + for ( j = 1; j <= jhi; j++ ){ + if ( i == 0 ){ + tval = t[0] - 1.0; + }else if ( i < N ){ + tval = ( + ( double ) ( jhi - j + 1 ) * t[i-1] + + ( double ) ( j - 1 ) * t[i] ) + / ( double ) ( jhi ); + }else{ + if ( j == 1 ){ + tval = t[N-1]; + }else{ + tval = t[N-1] + 1.0; + } + } + yval = spline_cubic_val ( N, t, tval, y, ypp, &ypval, &yppval ); -void func(double *p, double *x, int m, int n, void *data){ - register int i; + cout << tval << "\t" << yval << "\t\t" << frunge (tval) << "\n"; - std::vector<const vigra::Point2D *> * dat = (std::vector<const vigra::Point2D *> *) data; + // I think these are the derivitive parameters we need + // If so, we don't really need to be in either of these for loops, just call + // spline_cubic_val on 1st and last point + if ((tval == data[0]->x) || (tval == data[N-1]->x)){ + //cout << i << " " << tval << " deriv:" << ypval << endl; + parameters.push_back(ypval); + } + + } + + + } + + delete [] ypp; - for(i=0; i < n; ++i){ - //std::cout << "x = " << (*dat)[i]->x << ", y =" << (*dat)[i]->y << endl; - //[i]= ??? + cout << endl << "Spline Parameters:" << endl << endl; + for ( i = 0; i < parameters.size(); i++ ) { + cout << i << ":\t" << parameters[i] << endl; } + + cout << endl << "====================================" << endl << endl; + + return(true); + } -void jacfunc(double *p, double *jac, int m, int n, void *data){} +void ParameterEstimator::leastSquaresEstimate(std::vector<const vigra::Point2D *> &data, std::vector<double> ¶meters){ -void ParameterEstimator::leastSquaresEstimate(std::vector<const vigra::Point2D *> &data, std::vector<double> ¶meters) -{ + std::cout << "Least squares estimate..." << std::endl; - std::cout << "Least squares estimate using LEVMAR..." << std::endl; - const int n= data.size(), m = 3; // n measurements, 3 parameters double p[m], x[n], opts[LM_OPTS_SZ], info[LM_INFO_SZ]; + + /* register int i; int ret; @@ -167,18 +189,19 @@ x[i]= 1; } - /* initial parameters estimate: (1.0, 1.0, 1.0) */ + // initial parameters estimate: (1.0, 1.0, 1.0) p[0]=1.0; p[1]=1.0; p[2]=1.0; - /* optimization control parameters; passing to levmar NULL instead of opts reverts to defaults */ + // optimization control parameters; passing to levmar NULL instead of opts reverts to defaults opts[0]=LM_INIT_MU; opts[1]=1E-15; opts[2]=1E-15; opts[3]=1E-20; opts[4]=LM_DIFF_DELTA; // relevant only if the finite difference Jacobian version is used - /* invoke the optimization function */ + // invoke the optimization function ret=dlevmar_der(func, jacfunc, p, x, m, n, 1000, opts, info, NULL, NULL, &data); // with analytic Jacobian printf("Levenberg-Marquardt returned in %g iter, reason %g, sumsq %g [%g]\n", info[5], info[6], info[1], info[0]); printf("Best fit parameters: %.7g %.7g %.7g\n", p[0], p[1], p[2]); + */ parameters.push_back(p[0]); parameters.push_back(p[1]); @@ -217,4 +240,94 @@ } +//****************************************************************************80 +double frunge (double x){ + +//****************************************************************************80 +// +// Purpose: +// +// FRUNGE sets the Runge data values. +// +// Licensing: +// +// This code is distributed under the GNU LGPL license. +// +// Modified: +// +// 13 January 2007 +// +// Author: +// +// John Burkardt +// + + double fx; + + fx = 1.0 / ( 1.0 + 25.0 * x * x ); + + return fx; +} +//****************************************************************************80 + +double fprunge(double x){ + +//****************************************************************************80 +// +// Purpose: +// +// FPRUNGE sets the Runge derivative values at the endpoints. +// +// Licensing: +// +// This code is distributed under the GNU LGPL license. +// +// Modified: +// +// 13 January 2007 +// +// Author: +// +// John Burkardt +// + + double bot; + double fx; + + bot = 1.0 + 25.0 * x * x; + fx = -50.0 * x / ( bot * bot ); + + return fx; +} +//****************************************************************************80 + +double fpprunge (double x){ + +//****************************************************************************80 +// +// Purpose: +// +// FPPRUNGE sets the Runge second derivative values at the endpoints. +// +// Licensing: +// +// This code is distributed under the GNU LGPL license. +// +// Modified: +// +// 13 January 2007 +// +// Author: +// +// John Burkardt +// + + double bot; + double fx; + + bot = 1.0 + 25.0 * x * x; + fx = ( -50.0 + 3750.0 * x * x ) / ( bot * bot * bot ); + + return fx; +} Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/SplineEstimator.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/SplineEstimator.h 2009-05-29 05:23:39 UTC (rev 3891) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/SplineEstimator.h 2009-05-29 16:36:52 UTC (rev 3892) @@ -58,7 +58,7 @@ protected: unsigned int minForEstimate; -private: +private: double deltasquared; //given line L and point P, if dist(L,P)^2 < m_delta^2 then the point is on the line }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bl...@us...> - 2009-06-02 00:04:00
|
Revision: 3903 http://hugin.svn.sourceforge.net/hugin/?rev=3903&view=rev Author: blimbo Date: 2009-06-02 00:03:55 +0000 (Tue, 02 Jun 2009) Log Message: ----------- Fixed array bug, agree function now measures distance from point to straght line between 2 spline points Modified Paths: -------------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Spline.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/SplineEstimator.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/SplineEstimator.h Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-06-01 20:38:48 UTC (rev 3902) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-06-02 00:03:55 UTC (rev 3903) @@ -36,15 +36,18 @@ cout << coords.size() << " 'edge' coordinates found." << endl; vector<double> curveParameters; - double desiredProbabilityForNoOutliers = 0.9; + double desiredProbabilityForNoOutliers = 0.9; double maximalOutlierPercentage = 0.8; - // Use 3 points to calculate a,b and c parameters - // Point must be within 0.2 units of curve to agree - ParameterEstimator curveEstimator(3, 1); + // Use 4 points + // Point must be within 10 units of curve to agree + ParameterEstimator curveEstimator(4, 0.5); cout << endl << "Computing RANSAC..." << endl; double usedData = Ransac::compute(curveParameters, &curveEstimator, coords, desiredProbabilityForNoOutliers, maximalOutlierPercentage); - cout << "y = " << curveParameters[0] << "x^2 + " << curveParameters[1] << "x + " << curveParameters[2] << endl; + for (int i = 0; i < curveParameters.size(); i++){ + cout << "Parameter " << i << ":\t" << curveParameters[i] << endl; + } + cout << "Percentage of points which were used for final estimate: "<< usedData/coords.size() << " % (" << usedData << ")" << endl << endl; exit(1); Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Spline.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Spline.cpp 2009-06-01 20:38:48 UTC (rev 3902) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Spline.cpp 2009-06-02 00:03:55 UTC (rev 3903) @@ -9,6 +9,7 @@ # include <iomanip> # include <cmath> # include <ctime> +#include <string.h> using namespace std; Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/SplineEstimator.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/SplineEstimator.cpp 2009-06-01 20:38:48 UTC (rev 3902) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/SplineEstimator.cpp 2009-06-02 00:03:55 UTC (rev 3903) @@ -9,22 +9,24 @@ using namespace std; - double frunge (double x); double fprunge (double x); double fpprunge (double x); +int dot(const vigra::Point2D A, const vigra::Point2D B, const vigra::Point2D C); +int cross(const vigra::Point2D A, const vigra::Point2D B, const vigra::Point2D C); +double distance(const vigra::Point2D A, const vigra::Point2D B); +double linePointDist(const vigra::Point2D A, const vigra::Point2D B, const vigra::Point2D C, bool isSegment); -double a,b,c,p,q; bool compare (const vigra::Point2D * i,const vigra::Point2D * j) { return (i->x<j->x); } - ParameterEstimator::ParameterEstimator(unsigned int m, double delta){ minForEstimate = m; - deltasquared = delta*delta; + distance = delta; + distancesquared = delta*delta; } bool ParameterEstimator::estimate(std::vector<const vigra::Point2D *> &data, std::vector<double> ¶meters){ @@ -35,8 +37,10 @@ } sort(data.begin(), data.end(), compare); - if((data[0]->x == data[1]->x)||(data[1]->x == data[2]->x)){ - return(false); + for (int t = 0; t < data.size()-1; t++){ + if (data[t]->x == data[t+1]->x){ + return(false); + } } /* @@ -66,9 +70,9 @@ int j; int jhi; int k; - double t[N]; + double tval; - double y[N]; + double ybcbeg; double ybcend; double *ypp; @@ -76,6 +80,12 @@ double ypval; double yval; + //double t[N]; + //double y[N]; + + double * t = new double[N]; + double * y = new double[N]; + cout << "SPLINE_CUBIC_SET sets up a cubic spline;\n"; cout << "SPLINE_CUBIC_VAL evaluates it.\n"; cout << "\n"; @@ -170,6 +180,9 @@ cout << endl << "====================================" << endl << endl; + delete [] t; + delete [] y; + return(true); } @@ -178,65 +191,40 @@ std::cout << "Least squares estimate..." << std::endl; - const int n= data.size(), m = 3; // n measurements, 3 parameters - double p[m], x[n], opts[LM_OPTS_SZ], info[LM_INFO_SZ]; - /* - register int i; - int ret; - - for(i=0; i < n; ++i){ - x[i]= 1; + for (int i = 0; i < data.size(); i++){ + cout << data[i]->x << "," << data[i]->y << endl; } - // initial parameters estimate: (1.0, 1.0, 1.0) - p[0]=1.0; p[1]=1.0; p[2]=1.0; - - // optimization control parameters; passing to levmar NULL instead of opts reverts to defaults - opts[0]=LM_INIT_MU; opts[1]=1E-15; opts[2]=1E-15; opts[3]=1E-20; - opts[4]=LM_DIFF_DELTA; // relevant only if the finite difference Jacobian version is used - - // invoke the optimization function - ret=dlevmar_der(func, jacfunc, p, x, m, n, 1000, opts, info, NULL, NULL, &data); // with analytic Jacobian - - printf("Levenberg-Marquardt returned in %g iter, reason %g, sumsq %g [%g]\n", info[5], info[6], info[1], info[0]); - printf("Best fit parameters: %.7g %.7g %.7g\n", p[0], p[1], p[2]); - */ - - parameters.push_back(p[0]); - parameters.push_back(p[1]); - parameters.push_back(p[2]); + //parameters.push_back(p[0]); + //parameters.push_back(p[1]); + //parameters.push_back(p[2]); } bool ParameterEstimator::agree(std::vector<double> ¶meters, const vigra::Point2D &data){ - double p = data->x; - double q = data->y; - double a = parameters[0]; - double b = parameters[1]; - double c = parameters[2]; - double a2 = a*a; - double a3 = a2*a; - double a4 = a2*a2; - double b2 = b*b; + //cout << endl << "Agree Parameters:" << endl; + //for (int i = 0; i < parameters.size()-2; i++ ){ + // cout << i << ":\t" << parameters[i] << endl; + //} - double x = - -(b/(2*a)) - - (6*a2 - 3*a2*b2 + 12*a3*c - 12*a3*q) - /(3*pow(2,(2.0/3.0))*a2*pow((54*a3*b + 108*a4*p + - sqrt(pow((54*a3*b + 108*a4*p),2) + 4*pow((6*a2 - 3*a2*b2 + 12*a3*c - 12*a3*q),3)) - ),(1.0/3.0))) - + (1/(6*pow(2,(1.0/3.0))*a2)) - * pow( - (54*a3*b + 108*a4*p + sqrt(pow((54*a3*b + 108*a4*p),2) - + 4*pow((6*a2 - 3*a2*b2 + 12*a3*c - 12*a3*q),3))) - ,(1.0/3.0)); - - double y = (a*(x*x)) + (b*x) + c; + vector<vigra::Point2D> coords; + double min_distance = 100000; + + for (int i = 0; i < this->minForEstimate; i++ ){ + //cout << "pushing " << i << " and " << i+this->minForEstimate << endl; + coords.push_back(vigra::Point2D(parameters[i],parameters[i+this->minForEstimate])); + } - double distancesquared = abs((p - x) + (q - y)); + for (int i = 0; i < coords.size()-1; i++ ){ + double distance = linePointDist(coords[i],coords[i+1],data,true); + if(distance < min_distance)min_distance = distance; + //cout << "Distance = " << distance << endl; + } - return (distancesquared < this->deltasquared); + //cout << "Min distance = " << min_distance << endl; + + return(min_distance < this->distance); } @@ -331,3 +319,52 @@ return fx; } + + +// Compute the dot product AB . BC +int dot(const vigra::Point2D A, const vigra::Point2D B, const vigra::Point2D C){ + + int AB[2]; + int BC[2]; + AB[0] = B->x-A->x; + AB[1] = B->y-A->y; + BC[0] = C->x-B->x; + BC[1] = C->y-B->y; + int dot = AB[0] * BC[0] + AB[1] * BC[1]; + return dot; + +} +// Compute the cross product AB x AC +int cross(const vigra::Point2D A, const vigra::Point2D B, const vigra::Point2D C){ + + int AB[2]; + int AC[2]; + AB[0] = B->x-A->x; + AB[1] = B->y-A->y; + AC[0] = C->x-A->x; + AC[1] = C->y-A->y; + int cross = AB[0] * AC[1] - AB[1] * AC[0]; + return cross; +} + + +// Compute the distance from A to B +double distance(const vigra::Point2D A, const vigra::Point2D B){ + int d1 = A->x - B->x; + int d2 = A->y - B->y; + return sqrt(d1*d1+d2*d2); +} + +// Compute the distance from AB to C +// If isSegment is true, AB is a segment, not a line. +double linePointDist(const vigra::Point2D A, const vigra::Point2D B, const vigra::Point2D C, bool isSegment){ + + double dist = cross(A,B,C) / distance(A,B); + if(isSegment){ + int dot1 = dot(A,B,C); + if(dot1 > 0)return distance(B,C); + int dot2 = dot(B,A,C); + if(dot2 > 0)return distance(A,C); + } + return abs(dist); +} Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/SplineEstimator.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/SplineEstimator.h 2009-06-01 20:38:48 UTC (rev 3902) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/SplineEstimator.h 2009-06-02 00:03:55 UTC (rev 3903) @@ -59,7 +59,7 @@ unsigned int minForEstimate; private: - double deltasquared; //given line L and point P, if dist(L,P)^2 < m_delta^2 then the point is on the line + double distance,distancesquared; //given line L and point P, if dist(L,P)^2 < m_delta^2 then the point is on the line }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bl...@us...> - 2009-06-04 23:25:49
|
Revision: 3914 http://hugin.svn.sourceforge.net/hugin/?rev=3914&view=rev Author: blimbo Date: 2009-06-04 23:25:47 +0000 (Thu, 04 Jun 2009) Log Message: ----------- Added least squares function Modified Paths: -------------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Spline.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Spline.h hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/SplineEstimator.cpp Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt 2009-06-03 16:15:19 UTC (rev 3913) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt 2009-06-04 23:25:47 UTC (rev 3914) @@ -1,6 +1,7 @@ ADD_EXECUTABLE(calibrate_lens Main.cpp Globals.cpp +PointLineDist.cpp ProcessImage.cpp SplineEstimator.cpp Spline.cpp Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Spline.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Spline.cpp 2009-06-03 16:15:19 UTC (rev 3913) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Spline.cpp 2009-06-04 23:25:47 UTC (rev 3914) @@ -6550,3 +6550,97 @@ return; # undef TIME_SIZE } + + +//****************************************************************************80 + +double frunge (double x){ + +//****************************************************************************80 +// +// Purpose: +// +// FRUNGE sets the Runge data values. +// +// Licensing: +// +// This code is distributed under the GNU LGPL license. +// +// Modified: +// +// 13 January 2007 +// +// Author: +// +// John Burkardt +// + + double fx; + + fx = 1.0 / ( 1.0 + 25.0 * x * x ); + + return fx; +} +//****************************************************************************80 + +double fprunge(double x){ + +//****************************************************************************80 +// +// Purpose: +// +// FPRUNGE sets the Runge derivative values at the endpoints. +// +// Licensing: +// +// This code is distributed under the GNU LGPL license. +// +// Modified: +// +// 13 January 2007 +// +// Author: +// +// John Burkardt +// + + double bot; + double fx; + + bot = 1.0 + 25.0 * x * x; + fx = -50.0 * x / ( bot * bot ); + + return fx; +} +//****************************************************************************80 + +double fpprunge (double x){ + +//****************************************************************************80 +// +// Purpose: +// +// FPPRUNGE sets the Runge second derivative values at the endpoints. +// +// Licensing: +// +// This code is distributed under the GNU LGPL license. +// +// Modified: +// +// 13 January 2007 +// +// Author: +// +// John Burkardt +// + + double bot; + double fx; + + bot = 1.0 + 25.0 * x * x; + fx = ( -50.0 + 3750.0 * x * x ) / ( bot * bot * bot ); + + return fx; +} + Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Spline.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Spline.h 2009-06-03 16:15:19 UTC (rev 3913) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Spline.h 2009-06-04 23:25:47 UTC (rev 3914) @@ -95,3 +95,6 @@ void spline_quadratic_val ( int ndata, double tdata[], double ydata[], double tval, double *yval, double *ypval ); void timestamp ( void ); +double frunge (double x); +double fprunge (double x); +double fpprunge (double x); Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/SplineEstimator.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/SplineEstimator.cpp 2009-06-03 16:15:19 UTC (rev 3913) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/SplineEstimator.cpp 2009-06-04 23:25:47 UTC (rev 3914) @@ -1,23 +1,14 @@ -#include "SplineEstimator.h" #include <cmath> #include <iomanip> +#include <algorithm> #include <iostream> #include "vigra/diff2d.hxx" -#include <levmar/lm.h> -#include "MatrixDeterminant.h" +#include "SplineEstimator.h" #include "Spline.h" +#include "PointLineDist.h" using namespace std; -double frunge (double x); -double fprunge (double x); -double fpprunge (double x); -int dot(const vigra::Point2D A, const vigra::Point2D B, const vigra::Point2D C); -int cross(const vigra::Point2D A, const vigra::Point2D B, const vigra::Point2D C); -double distance(const vigra::Point2D A, const vigra::Point2D B); -double linePointDist(const vigra::Point2D A, const vigra::Point2D B, const vigra::Point2D C, bool isSegment); - - bool compare (const vigra::Point2D * i,const vigra::Point2D * j) { return (i->x<j->x); } @@ -114,12 +105,6 @@ cout << "Y'(right) = " << ybcend << "\n"; */ - // Are these values the derivatives needed to complete the paramaters - // or do i get them by calling spline_cubic_val for 1st and last values? - //parameters.push_back(ybcbeg); - //parameters.push_back(ybcend); - // Can we return here? - ypp = spline_cubic_set ( N, t, y, ibcbeg, ybcbeg, ibcend, ybcend ); /* @@ -133,7 +118,6 @@ cout << "\n"; cout << "T\tSPLINE(T)\tF(T)\n"; cout << "\n"; - */ for ( i = 0; i <= N; i++ ){ @@ -163,12 +147,13 @@ yval = spline_cubic_val ( N, t, tval, y, ypp, &ypval, &yppval ); - //cout << tval << "\t" << yval << "\t\t" << frunge (tval) << "\n"; + cout << tval << "\t" << yval << "\t\t" << frunge (tval) << "\n"; // I think these are the derivitive parameters we need // If so, we don't really need to be in either of these for loops, just call // spline_cubic_val on 1st and last point if ((tval == data[0]->x) || (tval == data[N-1]->x)){ + cout << "Pushing parameters" << endl; parameters.push_back(ypval); } @@ -176,9 +161,14 @@ } - - delete [] ypp; + */ + + yval = spline_cubic_val ( N, t, data[0]->x, y, ypp, &ypval, &yppval ); + parameters.push_back(ypval); + yval = spline_cubic_val ( N, t, data[N-1]->x, y, ypp, &ypval, &yppval ); + parameters.push_back(ypval); + /* cout << endl << "Spline Parameters:" << endl << endl; for ( i = 0; i < parameters.size(); i++ ) { @@ -187,6 +177,7 @@ cout << endl << "====================================" << endl << endl; */ + delete [] ypp; delete [] t; delete [] y; @@ -196,182 +187,84 @@ void ParameterEstimator::leastSquaresEstimate(std::vector<const vigra::Point2D *> &data, std::vector<double> ¶meters){ - std::cout << "Least squares estimate..." << std::endl; - - + cout << endl << "Inliers:" << endl; for (int i = 0; i < data.size(); i++){ cout << data[i]->x << "," << data[i]->y << endl; } + cout << endl; - //parameters.push_back(p[0]); - //parameters.push_back(p[1]); - //parameters.push_back(p[2]); + int NTERMS = this->minForEstimate; + int POINT_NUM = data.size(); + + double * b = new double[NTERMS]; + double * c = new double[NTERMS]; + double * d = new double[NTERMS]; + double * f = new double[POINT_NUM]; + double * fp = new double[POINT_NUM]; + int i; + int nterms2; + double px; + double * w = new double[POINT_NUM]; + double * x = new double[POINT_NUM]; + + for ( i = 0; i < POINT_NUM; i++ ){ + w[i] = 1.0; // weight + x[i] = data[i]->x; // abscissas of the data points + f[i] = x[i] * x[i] - x[i] - 6.0; // data values at the points X(*) ?? + fp[i] = 2.0 * x[i] - 1.0; // ?? + } + + least_set ( POINT_NUM, x, f, w, NTERMS, b, c, d ); + + cout << " LEAST_SET sets a least squares polynomial,\n"; + cout << " LEAST_VAL evaluates it.\n"; + cout << "\n"; + cout << " X, F(X), P(X), Error\n"; + cout << "\n"; + //for ( nterms2 = 1; nterms2 <= 3; nterms2++ ){ + for ( nterms2 = 3; nterms2 <= 3; nterms2++ ){ + cout << "\n"; + cout << " Using polynomial order = " << nterms2 << "\n"; + cout << "\n"; + for ( i = 0; i < POINT_NUM; i++ ){ + px = least_val ( nterms2, b, c, d, x[i] ); + cout << " " << setw(12) << x[i] + << " " << setw(12) << f[i] + << " " << setw(12) << px + << " " << setw(12) << px - f[i] << "\n"; + } + } + + cout << endl; + for ( i = 0; i < NTERMS; i++ ){ + cout << "b:\t" << b[i] << setw(12) << "c:\t" << c[i] << setw(12) << "d:\t" << d[i] << endl; + } + cout << endl; + + delete [] b; + delete [] c; + delete [] d; + delete [] f; + delete [] fp; + delete [] w; + delete [] x; + + } bool ParameterEstimator::agree(std::vector<double> ¶meters, const vigra::Point2D &data){ - //cout << endl << "Agree Parameters:" << endl; - //for (int i = 0; i < parameters.size()-2; i++ ){ - // cout << i << ":\t" << parameters[i] << endl; - //} - + // Use distance between point and line between spline control points vector<vigra::Point2D> coords; double min_distance = 100000; for (int i = 0; i < this->minForEstimate; i++ ){ - //cout << "pushing " << i << " and " << i+this->minForEstimate << endl; coords.push_back(vigra::Point2D((int)parameters[i],(int)parameters[i+this->minForEstimate])); } - for (int i = 0; i < coords.size()-1; i++ ){ double distance = linePointDist(coords[i],coords[i+1],data,true); - if(distance < min_distance)min_distance = distance; - //cout << "Distance = " << distance << endl; + if(distance < min_distance) min_distance = distance; } - - //cout << "Min distance = " << min_distance << endl; - return(min_distance < this->distance); } - -//****************************************************************************80 - -double frunge (double x){ - -//****************************************************************************80 -// -// Purpose: -// -// FRUNGE sets the Runge data values. -// -// Licensing: -// -// This code is distributed under the GNU LGPL license. -// -// Modified: -// -// 13 January 2007 -// -// Author: -// -// John Burkardt -// - - double fx; - - fx = 1.0 / ( 1.0 + 25.0 * x * x ); - - return fx; -} -//****************************************************************************80 - -double fprunge(double x){ - -//****************************************************************************80 -// -// Purpose: -// -// FPRUNGE sets the Runge derivative values at the endpoints. -// -// Licensing: -// -// This code is distributed under the GNU LGPL license. -// -// Modified: -// -// 13 January 2007 -// -// Author: -// -// John Burkardt -// - - double bot; - double fx; - - bot = 1.0 + 25.0 * x * x; - fx = -50.0 * x / ( bot * bot ); - - return fx; -} -//****************************************************************************80 - -double fpprunge (double x){ - -//****************************************************************************80 -// -// Purpose: -// -// FPPRUNGE sets the Runge second derivative values at the endpoints. -// -// Licensing: -// -// This code is distributed under the GNU LGPL license. -// -// Modified: -// -// 13 January 2007 -// -// Author: -// -// John Burkardt -// - - double bot; - double fx; - - bot = 1.0 + 25.0 * x * x; - fx = ( -50.0 + 3750.0 * x * x ) / ( bot * bot * bot ); - - return fx; -} - - -// Compute the dot product AB . BC -int dot(const vigra::Point2D A, const vigra::Point2D B, const vigra::Point2D C){ - - int AB[2]; - int BC[2]; - AB[0] = B->x-A->x; - AB[1] = B->y-A->y; - BC[0] = C->x-B->x; - BC[1] = C->y-B->y; - int dot = AB[0] * BC[0] + AB[1] * BC[1]; - return dot; - -} -// Compute the cross product AB x AC -int cross(const vigra::Point2D A, const vigra::Point2D B, const vigra::Point2D C){ - - int AB[2]; - int AC[2]; - AB[0] = B->x-A->x; - AB[1] = B->y-A->y; - AC[0] = C->x-A->x; - AC[1] = C->y-A->y; - int cross = AB[0] * AC[1] - AB[1] * AC[0]; - return cross; -} - - -// Compute the distance from A to B -double distance(const vigra::Point2D A, const vigra::Point2D B){ - int d1 = A->x - B->x; - int d2 = A->y - B->y; - return sqrt(d1*d1+d2*d2); -} - -// Compute the distance from AB to C -// If isSegment is true, AB is a segment, not a line. -double linePointDist(const vigra::Point2D A, const vigra::Point2D B, const vigra::Point2D C, bool isSegment){ - - double dist = cross(A,B,C) / distance(A,B); - if(isSegment){ - int dot1 = dot(A,B,C); - if(dot1 > 0)return distance(B,C); - int dot2 = dot(B,A,C); - if(dot2 > 0)return distance(A,C); - } - return abs(dist); -} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bl...@us...> - 2009-06-04 23:26:38
|
Revision: 3915 http://hugin.svn.sourceforge.net/hugin/?rev=3915&view=rev Author: blimbo Date: 2009-06-04 23:26:36 +0000 (Thu, 04 Jun 2009) Log Message: ----------- Add some files Added Paths: ----------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PointLineDist.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PointLineDist.h Added: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PointLineDist.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PointLineDist.cpp (rev 0) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PointLineDist.cpp 2009-06-04 23:26:36 UTC (rev 3915) @@ -0,0 +1,52 @@ +#include <cmath> +#include "vigra/diff2d.hxx" +#include <stdlib.h> + +// Compute the dot product AB . BC +int dot(const vigra::Point2D A, const vigra::Point2D B, const vigra::Point2D C){ + + int AB[2]; + int BC[2]; + AB[0] = B->x-A->x; + AB[1] = B->y-A->y; + BC[0] = C->x-B->x; + BC[1] = C->y-B->y; + int dot = AB[0] * BC[0] + AB[1] * BC[1]; + return dot; + +} +// Compute the cross product AB x AC +int cross(const vigra::Point2D A, const vigra::Point2D B, const vigra::Point2D C){ + + int AB[2]; + int AC[2]; + AB[0] = B->x-A->x; + AB[1] = B->y-A->y; + AC[0] = C->x-A->x; + AC[1] = C->y-A->y; + int cross = AB[0] * AC[1] - AB[1] * AC[0]; + return cross; +} + + +// Compute the distance from A to B +double distance(const vigra::Point2D A, const vigra::Point2D B){ + int d1 = A->x - B->x; + int d2 = A->y - B->y; + return sqrt(d1*d1+d2*d2); +} + +// Compute the distance from AB to C +// If isSegment is true, AB is a segment, not a line. +double linePointDist(const vigra::Point2D A, const vigra::Point2D B, const vigra::Point2D C, bool isSegment){ + + double dist = cross(A,B,C) / distance(A,B); + if(isSegment){ + int dot1 = dot(A,B,C); + if(dot1 > 0)return distance(B,C); + int dot2 = dot(B,A,C); + if(dot2 > 0)return distance(A,C); + } + return abs(dist); +} + Added: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PointLineDist.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PointLineDist.h (rev 0) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PointLineDist.h 2009-06-04 23:26:36 UTC (rev 3915) @@ -0,0 +1,4 @@ +int dot(const vigra::Point2D A, const vigra::Point2D B, const vigra::Point2D C); +int cross(const vigra::Point2D A, const vigra::Point2D B, const vigra::Point2D C); +double distance(const vigra::Point2D A, const vigra::Point2D B); +double linePointDist(const vigra::Point2D A, const vigra::Point2D B, const vigra::Point2D C, bool isSegment); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bl...@us...> - 2009-06-05 16:02:58
|
Revision: 3920 http://hugin.svn.sourceforge.net/hugin/?rev=3920&view=rev Author: blimbo Date: 2009-06-05 16:02:55 +0000 (Fri, 05 Jun 2009) Log Message: ----------- Function to plot inliers Modified Paths: -------------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PointLineDist.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PointLineDist.h hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/SplineEstimator.cpp Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp 2009-06-05 13:03:31 UTC (rev 3919) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp 2009-06-05 16:02:55 UTC (rev 3920) @@ -20,6 +20,7 @@ #include "Globals.h" #include <string> +#include <vector> unsigned int resize_dimension = 800; unsigned int detector = 0; @@ -30,3 +31,4 @@ unsigned int vertical_slices = 12; unsigned int horizontal_slices = 8; unsigned int generate_images = 1; +std::vector<const vigra::Point2D *> inliers; Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h 2009-06-05 13:03:31 UTC (rev 3919) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h 2009-06-05 16:02:55 UTC (rev 3920) @@ -2,6 +2,8 @@ #define GLOBALS_H #include <string> +#include <vector> +#include "vigra/diff2d.hxx" extern unsigned int resize_dimension; extern unsigned int detector; @@ -12,6 +14,8 @@ extern unsigned int horizontal_slices; extern unsigned int vertical_slices; extern unsigned int generate_images; +extern unsigned int generate_images; +extern std::vector<const vigra::Point2D *> inliers; #endif Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PointLineDist.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PointLineDist.cpp 2009-06-05 13:03:31 UTC (rev 3919) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PointLineDist.cpp 2009-06-05 16:02:55 UTC (rev 3920) @@ -30,7 +30,7 @@ // Compute the distance from A to B -double distance(const vigra::Point2D A, const vigra::Point2D B){ +double PointPointDist(const vigra::Point2D A, const vigra::Point2D B){ int d1 = A->x - B->x; int d2 = A->y - B->y; return sqrt(d1*d1+d2*d2); @@ -38,15 +38,15 @@ // Compute the distance from AB to C // If isSegment is true, AB is a segment, not a line. -double linePointDist(const vigra::Point2D A, const vigra::Point2D B, const vigra::Point2D C, bool isSegment){ +double LinePointDist(const vigra::Point2D A, const vigra::Point2D B, const vigra::Point2D C, bool isSegment){ - double dist = cross(A,B,C) / distance(A,B); + double dist = cross(A,B,C) / PointPointDist(A,B); if(isSegment){ - int dot1 = dot(A,B,C); - if(dot1 > 0)return distance(B,C); - int dot2 = dot(B,A,C); - if(dot2 > 0)return distance(A,C); + int dot1 = dot(A,B,C); + if(dot1 > 0)return PointPointDist(B,C); + int dot2 = dot(B,A,C); + if(dot2 > 0)return PointPointDist(A,C); } - return abs(dist); + return fabs(dist); } Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PointLineDist.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PointLineDist.h 2009-06-05 13:03:31 UTC (rev 3919) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PointLineDist.h 2009-06-05 16:02:55 UTC (rev 3920) @@ -1,4 +1,9 @@ +#ifndef POINTLINEDIST_H +#define POINTLINEDIST_H + int dot(const vigra::Point2D A, const vigra::Point2D B, const vigra::Point2D C); int cross(const vigra::Point2D A, const vigra::Point2D B, const vigra::Point2D C); -double distance(const vigra::Point2D A, const vigra::Point2D B); -double linePointDist(const vigra::Point2D A, const vigra::Point2D B, const vigra::Point2D C, bool isSegment); +double PointPointDist(const vigra::Point2D A, const vigra::Point2D B); +double LinePointDist(const vigra::Point2D A, const vigra::Point2D B, const vigra::Point2D C, bool isSegment); + +#endif Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-06-05 13:03:31 UTC (rev 3919) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-06-05 16:02:55 UTC (rev 3920) @@ -31,6 +31,8 @@ using namespace vigra; using namespace std; +typedef vigra::BRGBImage::PixelType RGB; + void ransac(vector<Point2D>& coords){ cout << coords.size() << " 'edge' coordinates found." << endl; @@ -40,21 +42,54 @@ double maximalOutlierPercentage = 0.8; // Use 4 points // Point must be within 10 units of curve to agree - ParameterEstimator curveEstimator(4, 0.5); + //ParameterEstimator curveEstimator(4, 0.5); + ParameterEstimator curveEstimator(4, 2); cout << endl << "Computing RANSAC..." << endl; double usedData = Ransac::compute(curveParameters, &curveEstimator, coords, desiredProbabilityForNoOutliers, maximalOutlierPercentage); - for (int i = 0; i < curveParameters.size(); i++){ - cout << "Parameter " << i << ":\t" << curveParameters[i] << endl; - } + //for (int i = 0; i < curveParameters.size(); i++){ + // cout << "Parameter " << i << ":\t" << curveParameters[i] << endl; + //} cout << "Percentage of points which were used for final estimate: "<< usedData/coords.size() << " % (" << usedData << ")" << endl << endl; - exit(1); +} +void plot_inliers(BImage& image, int i){ + + vigra::BRGBImage tmp(image.width(),image.height()); + vigra::initImage(srcIterRange(tmp.upperLeft(), + tmp.upperLeft() + vigra::Diff2D(image.width(),image.height())), + RGB(255,255,255) ); + + cout << "Plotting inliers:\t" << inliers.size() << endl; + for (unsigned int il = 0; il < inliers.size(); il++){ + //cout << il << ": " << inliers[il]->x << "," << inliers[il]->y << endl; + vigra::initImage(srcIterRange(tmp.upperLeft() + vigra::Diff2D(inliers[il]->x, inliers[il]->y), + tmp.upperLeft() + vigra::Diff2D(inliers[il]->x+1, inliers[il]->y+1)), + RGB(255,0,0) ); + + } + + + //exit(1); + + if (generate_images){ + // Export slice to file + string output = path; + output.append("inliers"); + stringstream ii; + ii << i; + output.append(ii.str()); + //output.append("inliers"); + output.append(".jpg"); + exportImage(srcImageRange(tmp), ImageExportInfo(output.c_str()).setPixelType("UINT8")); + //exportImage(srcImageRange(tmp), output.c_str().setPixelType("UINT8")); + } + } -void extract_coords(BImage& image){ +void extract_coords(BImage& image, int i){ vector<Point2D> coords; @@ -75,7 +110,25 @@ } } } - ransac(coords); + + //ransac(coords); + //plot_inliers(image,i); + + // Get 5 strongest lines + for (int a = 1; a < 6; a++){ + cout << "Searching for line " << a << ":" << endl; + ransac(coords); + plot_inliers(image,a); + for (unsigned int il = 0; il < inliers.size(); il++){ + for (unsigned int c = 0; c < coords.size(); c++){ + if (inliers[il]->x == coords[c]->x && inliers[il]->y == coords[c]->y){ + coords.erase(coords.begin()+c); + } + } + } + inliers.clear(); + } + } void sub_image(BImage& image){ @@ -120,7 +173,7 @@ destImage(out)); // Get line coordinates - extract_coords(out); + extract_coords(out,i); if (generate_images){ // Export slice to file @@ -132,8 +185,11 @@ output.append(".jpg"); exportImage(srcImageRange(out), output.c_str()); } + } + exit(1); + unsigned int sub_x0 = 0; unsigned int sub_x1 = image.width(); @@ -166,7 +222,7 @@ destImage(out)); // Get line coordinates - extract_coords(out); + extract_coords(out,i); if (generate_images){ //Export slice to file @@ -233,8 +289,10 @@ } // Slice image - sub_image(out); + //sub_image(out); + extract_coords(out,1); + } catch (StdException & e){ Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h 2009-06-05 13:03:31 UTC (rev 3919) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h 2009-06-05 16:02:55 UTC (rev 3920) @@ -5,7 +5,8 @@ #include "vigra/diff2d.hxx" void ransac(std::vector<vigra::Point2D>&,unsigned int,unsigned int); -void extract_coords(vigra::BImage&); +void plot_inliers(vigra::BImage& image, int); +void extract_coords(vigra::BImage&, int); void sub_image(vigra::BImage& image); void detect_edge(vigra::BImage&, std::string&, std::string&, std::string&); void process_image(std::string&); Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/SplineEstimator.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/SplineEstimator.cpp 2009-06-05 13:03:31 UTC (rev 3919) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/SplineEstimator.cpp 2009-06-05 16:02:55 UTC (rev 3920) @@ -4,6 +4,7 @@ #include <iostream> #include "vigra/diff2d.hxx" #include "SplineEstimator.h" +#include "Globals.h" #include "Spline.h" #include "PointLineDist.h" @@ -45,9 +46,11 @@ */ + // Load the x values in to parameters vector for(int i = 0; i < data.size(); i++){ parameters.push_back(data[i]->x); } + // Load the y values in to parameters vector for(int i = 0; i < data.size(); i++){ parameters.push_back(data[i]->y); } @@ -105,6 +108,7 @@ cout << "Y'(right) = " << ybcend << "\n"; */ + // Set up the cubic spline with this data ypp = spline_cubic_set ( N, t, y, ibcbeg, ybcbeg, ibcend, ybcend ); /* @@ -146,24 +150,13 @@ } yval = spline_cubic_val ( N, t, tval, y, ypp, &ypval, &yppval ); - cout << tval << "\t" << yval << "\t\t" << frunge (tval) << "\n"; - // I think these are the derivitive parameters we need - // If so, we don't really need to be in either of these for loops, just call - // spline_cubic_val on 1st and last point - if ((tval == data[0]->x) || (tval == data[N-1]->x)){ - cout << "Pushing parameters" << endl; - parameters.push_back(ypval); - } - } - - } - */ + // Add the values of the derivative at the first and last point yval = spline_cubic_val ( N, t, data[0]->x, y, ypp, &ypval, &yppval ); parameters.push_back(ypval); yval = spline_cubic_val ( N, t, data[N-1]->x, y, ypp, &ypval, &yppval ); @@ -188,7 +181,9 @@ void ParameterEstimator::leastSquaresEstimate(std::vector<const vigra::Point2D *> &data, std::vector<double> ¶meters){ cout << endl << "Inliers:" << endl; + sort(data.begin(), data.end(), compare); for (int i = 0; i < data.size(); i++){ + inliers.push_back(data[i]); cout << data[i]->x << "," << data[i]->y << endl; } cout << endl; @@ -222,7 +217,7 @@ cout << " X, F(X), P(X), Error\n"; cout << "\n"; //for ( nterms2 = 1; nterms2 <= 3; nterms2++ ){ - for ( nterms2 = 3; nterms2 <= 3; nterms2++ ){ + cout << "\n"; cout << " Using polynomial order = " << nterms2 << "\n"; cout << "\n"; @@ -233,7 +228,7 @@ << " " << setw(12) << px << " " << setw(12) << px - f[i] << "\n"; } - } + //} cout << endl; for ( i = 0; i < NTERMS; i++ ){ @@ -253,18 +248,30 @@ } bool ParameterEstimator::agree(std::vector<double> ¶meters, const vigra::Point2D &data){ - - // Use distance between point and line between spline control points - vector<vigra::Point2D> coords; - double min_distance = 100000; - + + vector<vigra::Point2D> agree_coords; + double min_distance = this->distance; + for (int i = 0; i < this->minForEstimate; i++ ){ - coords.push_back(vigra::Point2D((int)parameters[i],(int)parameters[i+this->minForEstimate])); + agree_coords.push_back(vigra::Point2D((int)parameters[i],(int)parameters[i+this->minForEstimate])); } - for (int i = 0; i < coords.size()-1; i++ ){ - double distance = linePointDist(coords[i],coords[i+1],data,true); - if(distance < min_distance) min_distance = distance; + + // Use distance between point and line between spline control points + for (int i = 0; i < agree_coords.size()-1; i++ ){ + double this_distance = LinePointDist(agree_coords[i],agree_coords[i+1],data,true); + if(this_distance < min_distance) min_distance = this_distance; } + + /* + // Use distance between point and spline control points + for (int i = 0; i < agree_coords.size(); i++ ){ + double this_distance = PointPointDist(agree_coords[i],data); + //cout << "thisDistance:\t" << this_distance << endl; + if(this_distance < min_distance) min_distance = this_distance; + } + */ + //cout << "Distance:\t" << min_distance << endl; + return(min_distance < this->distance); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bl...@us...> - 2009-06-07 23:48:26
|
Revision: 3926 http://hugin.svn.sourceforge.net/hugin/?rev=3926&view=rev Author: blimbo Date: 2009-06-07 23:48:17 +0000 (Sun, 07 Jun 2009) Log Message: ----------- Added some boundary tensor code Modified Paths: -------------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PolynomialEstimator.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Ransac.h Added Paths: ----------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/LineParamEstimator.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/LineParamEstimator.h Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt 2009-06-07 16:17:32 UTC (rev 3925) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt 2009-06-07 23:48:17 UTC (rev 3926) @@ -3,10 +3,13 @@ Globals.cpp PointLineDist.cpp ProcessImage.cpp -SplineEstimator.cpp +LineParamEstimator.cpp +#PolynomialEstimator.cpp Spline.cpp ) +#SplineEstimator.cpp + TARGET_LINK_LIBRARIES( calibrate_lens ${image_libs} ${common_libs}) INSTALL(TARGETS calibrate_lens DESTINATION ${BINDIR}) Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp 2009-06-07 16:17:32 UTC (rev 3925) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp 2009-06-07 23:48:17 UTC (rev 3926) @@ -28,6 +28,7 @@ std::string format = (".jpg"); double threshold = 8; double scale = 2; +double tscale = 1; unsigned int vertical_slices = 12; unsigned int horizontal_slices = 8; unsigned int generate_images = 1; Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h 2009-06-07 16:17:32 UTC (rev 3925) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h 2009-06-07 23:48:17 UTC (rev 3926) @@ -10,7 +10,8 @@ extern std::string path; extern std::string format; extern double threshold; -extern double scale; +extern double scale; +extern double tscale; extern unsigned int horizontal_slices; extern unsigned int vertical_slices; extern unsigned int generate_images; Added: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/LineParamEstimator.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/LineParamEstimator.cpp (rev 0) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/LineParamEstimator.cpp 2009-06-07 23:48:17 UTC (rev 3926) @@ -0,0 +1,111 @@ +#include <math.h> +#include "LineParamEstimator.h" +#include "Globals.h" +#include "vigra/diff2d.hxx" +#include <iostream> //cout used in the debugTest method +#include <algorithm> + +using namespace vigra; + +bool compare (const vigra::Point2D * i,const vigra::Point2D * j) { + return (i->x<j->x); +} + +LineParamEstimator::LineParamEstimator(int min, double delta){ + minForEstimate = min; + deltaSquared = delta*delta; +} +/*****************************************************************************/ +/* + * Compute the line parameters [n_x,n_y,a_x,a_y] + */ +bool LineParamEstimator::estimate(std::vector<const Point2D *> &data, + std::vector<double> ¶meters) +{ + parameters.clear(); + if(data.size()<this->minForEstimate) + return(false); + double nx = data[1]->y - data[0]->y; + double ny = data[0]->x - data[1]->x; + double norm = sqrt(nx*nx + ny*ny); + + parameters.push_back(nx/norm); + parameters.push_back(ny/norm); + parameters.push_back(data[0]->x); + parameters.push_back(data[0]->y); + return(true); +} +/*****************************************************************************/ +/* + * Compute the line parameters [n_x,n_y,a_x,a_y] + */ +void LineParamEstimator::leastSquaresEstimate(std::vector<const Point2D *> &data, + std::vector<double> ¶meters) +{ + double meanX, meanY, nx, ny, norm; + double covMat11, covMat12, covMat21, covMat22; // The entries of the symmetric covarinace matrix + int i, dataSize = data.size(); + + parameters.clear(); + if(data.size()<this->minForEstimate) + return; + + meanX = meanY = 0.0; + covMat11 = covMat12 = covMat21 = covMat22 = 0; + for(i=0; i<dataSize; i++) { + meanX +=data[i]->x; + meanY +=data[i]->y; + + covMat11 +=data[i]->x * data[i]->x; + covMat12 +=data[i]->x * data[i]->y; + covMat22 +=data[i]->y * data[i]->y; + } + + meanX/=dataSize; + meanY/=dataSize; + + covMat11 -= dataSize*meanX*meanX; + covMat12 -= dataSize*meanX*meanY; + covMat22 -= dataSize*meanY*meanY; + covMat21 = covMat12; + + if(covMat11<1e-12) { + nx = 1.0; + ny = 0.0; + } + else { //lamda1 is the largest eigen-value of the covariance matrix + //and is used to compute the eigne-vector corresponding to the smallest + //eigenvalue, which isn't computed explicitly. + double lamda1 = (covMat11 + covMat22 + sqrt((covMat11-covMat22)*(covMat11-covMat22) + 4*covMat12*covMat12)) / 2.0; + nx = -covMat12; + ny = lamda1 - covMat22; + norm = sqrt(nx*nx + ny*ny); + nx/=norm; + ny/=norm; + } + parameters.push_back(nx); + parameters.push_back(ny); + parameters.push_back(meanX); + parameters.push_back(meanY); + + cout << endl << "Inliers:" << endl; + sort(data.begin(), data.end(), compare); + for (int i = 0; i < data.size(); i++){ + inliers.push_back(data[i]); + cout << data[i]->x << "," << data[i]->y << endl; + } + cout << endl; + +} +/*****************************************************************************/ +/* + * Given the line parameters [n_x,n_y,a_x,a_y] check if + * [n_x, n_y] dot [data.x-a_x, data.y-a_y] < m_delta + */ +bool LineParamEstimator::agree(std::vector<double> ¶meters, const Point2D &data) +{ + double signedDistance = parameters[0]*(data.x-parameters[2]) + parameters[1]*(data.y-parameters[3]); + return ((signedDistance*signedDistance) < this->deltaSquared); +} +/*****************************************************************************/ + Added: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/LineParamEstimator.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/LineParamEstimator.h (rev 0) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/LineParamEstimator.h 2009-06-07 23:48:17 UTC (rev 3926) @@ -0,0 +1,72 @@ +#ifndef _LINE_PARAM_ESTIMATOR_H_ +#define _LINE_PARAM_ESTIMATOR_H_ + +#include "vigra/diff2d.hxx" +#include <vector> +using namespace std; +using namespace vigra; + +/** + * This class estimates the parameters of 2D lines. + * A 2D line is represented as: (*) dot(n,p-a)=0 + * where n is the line normal (|n| = 1) and 'a' is a + * point on the line. + * All points 'p' which satisfy equation (*) are on the line. + * + * The reason for choosing this line parametrization is that it can represent + * all lines, including vertical and horizontal, unlike the slope intercept (y=ax+b) + * parametrization. + * + * Author: Ziv Yaniv + */ + +class LineParamEstimator { +public: + LineParamEstimator(int min, double delta); + + /** + * Compute the line defined by the given data points. + * @param data A vector containing two 2D points. + * @param This vector is cleared and then filled with the computed parameters. + * The parameters of the line passing through these points [n_x,n_y,a_x,a_y] + * where ||(n_x,ny)|| = 1. + * If the vector contains less than two points then the resulting parameters + * vector is empty (size = 0). + */ + bool estimate(std::vector<const Point2D *> &data, std::vector<double> ¶meters); + + /** + * Compute a least squares estimate of the line defined by the given points. + * This implementation is of an orthogonal least squares error. + * + * @param data The line should minimize the least squares error to these points. + * @param parameters This vector is cleared and then filled with the computed parameters. + * Fill this vector with the computed line parameters [n_x,n_y,a_x,a_y] + * where ||(n_x,ny)|| = 1. + * If the vector contains less than two points then the resulting parameters + * vector is empty (size = 0). + */ + virtual void leastSquaresEstimate(std::vector<const Point2D *> &data, std::vector<double> ¶meters); + + /** + * Return true if the distance between the line defined by the parameters and the + * given point is smaller than 'delta' (see constructor). + * @param parameters The line parameters [n_x,n_y,a_x,a_y]. + * @param data Check that the distance between this point and the line is smaller than 'delta'. + */ + virtual bool agree(std::vector<double> ¶meters, const Point2D &data); + + /** + * Test the class methods, output to specified stream. + */ + //static void debugTest(ostream &out); + + unsigned int numForEstimate() const {return minForEstimate;} +protected: + unsigned int minForEstimate; + +private: + double deltaSquared; //given line L and point P, if dist(L,P)^2 < m_delta^2 then the point is on the line +}; + +#endif //_LINE_PARAM_ESTIMATOR_H_ Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp 2009-06-07 16:17:32 UTC (rev 3925) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp 2009-06-07 23:48:17 UTC (rev 3926) @@ -41,6 +41,7 @@ cout << " -p <path> Output path. Default output/" << endl; cout << " -s <float> Edge detector scale. Default 2" << endl; cout << " -t <float> Edge detector threshold. Default 8" << endl; + cout << " -c <float> Boundary tensor scale. Default 2" << endl; cout << " -i <0|1> Generate intermediate images. Default 1" << endl; cout << " -h Print usage." << endl; cout << endl; @@ -77,6 +78,7 @@ case 'e' : {detector = atoi(argv[i]); break;} case 'd' : {resize_dimension = atoi(argv[i]); break;} case 's' : {scale = atof(argv[i]); break;} + case 'c' : {tscale = atof(argv[i]); break;} case 't' : {threshold = atof(argv[i]); break;} case 'i' : {generate_images = atoi(argv[i]); break;} } Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PolynomialEstimator.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PolynomialEstimator.cpp 2009-06-07 16:17:32 UTC (rev 3925) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/PolynomialEstimator.cpp 2009-06-07 23:48:17 UTC (rev 3926) @@ -1,16 +1,19 @@ #include <cmath> -#include "ParameterEstimator.h" +#include "PolynomialEstimator.h" #include <iostream> #include "vigra/diff2d.hxx" #include <boost/numeric/ublas/matrix.hpp> #include <boost/numeric/ublas/io.hpp> #include <levmar/lm.h> #include "MatrixDeterminant.h" +#include "Globals.h" using namespace boost::numeric::ublas; using namespace std; -double a,b,c,p,q; +bool compare (const vigra::Point2D * i,const vigra::Point2D * j) { + return (i->x<j->x); +} ParameterEstimator::ParameterEstimator(unsigned int m, double delta){ @@ -130,33 +133,26 @@ return(true); -} -/*****************************************************************************/ -/* - * Compute the line parameters [n_x,n_y,a_x,a_y] - */ - - - - -void func(double *p, double *x, int m, int n, void *data){ - register int i; - - std::vector<const vigra::Point2D *> * dat = (std::vector<const vigra::Point2D *> *) data; - - for(i=0; i < n; ++i){ - //std::cout << "x = " << (*dat)[i]->x << ", y =" << (*dat)[i]->y << endl; - //[i]= ??? - } } -void jacfunc(double *p, double *jac, int m, int n, void *data){} void ParameterEstimator::leastSquaresEstimate(std::vector<const vigra::Point2D *> &data, std::vector<double> ¶meters) { - std::cout << "Least squares estimate using LEVMAR..." << std::endl; + + cout << endl << "Inliers:" << endl; + sort(data.begin(), data.end(), compare); + for (int i = 0; i < data.size(); i++){ + inliers.push_back(data[i]); + cout << data[i]->x << "," << data[i]->y << endl; + } + cout << endl; + + + /* + + std::cout << "Least squares estimate..." << std::endl; const int n= data.size(), m = 3; // n measurements, 3 parameters double p[m], x[n], opts[LM_OPTS_SZ], info[LM_INFO_SZ]; register int i; @@ -166,14 +162,14 @@ x[i]= 1; } - /* initial parameters estimate: (1.0, 1.0, 1.0) */ + // initial parameters estimate: (1.0, 1.0, 1.0) p[0]=1.0; p[1]=1.0; p[2]=1.0; - /* optimization control parameters; passing to levmar NULL instead of opts reverts to defaults */ + // optimization control parameters; passing to levmar NULL instead of opts reverts to defaults opts[0]=LM_INIT_MU; opts[1]=1E-15; opts[2]=1E-15; opts[3]=1E-20; opts[4]=LM_DIFF_DELTA; // relevant only if the finite difference Jacobian version is used - /* invoke the optimization function */ + // invoke the optimization function ret=dlevmar_der(func, jacfunc, p, x, m, n, 1000, opts, info, NULL, NULL, &data); // with analytic Jacobian printf("Levenberg-Marquardt returned in %g iter, reason %g, sumsq %g [%g]\n", info[5], info[6], info[1], info[0]); @@ -182,6 +178,8 @@ parameters.push_back(p[0]); parameters.push_back(p[1]); parameters.push_back(p[2]); + */ + } bool ParameterEstimator::agree(std::vector<double> ¶meters, const vigra::Point2D &data){ @@ -209,8 +207,11 @@ ,(1.0/3.0)); double y = (a*(x*x)) + (b*x) + c; + + int d1 = p - x; + int d2 = q - y; - double distancesquared = abs((p - x) + (q - y)); + double distancesquared = (d1*d1 + d2*d2); return (distancesquared < this->deltasquared); Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-06-07 16:17:32 UTC (rev 3925) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-06-07 23:48:17 UTC (rev 3926) @@ -22,11 +22,15 @@ #include "vigra/stdimage.hxx" #include "vigra/edgedetection.hxx" #include "vigra/stdimagefunctions.hxx" +#include "vigra/tensorutilities.hxx" +#include "vigra/boundarytensor.hxx" #include "vigra/diff2d.hxx" #include "Globals.h" #include "ProcessImage.h" #include "Ransac.h" -#include "SplineEstimator.h" +//#include "SplineEstimator.h" +#include "LineParamEstimator.h" +//#include "PolynomialEstimator.h" using namespace vigra; using namespace std; @@ -42,8 +46,9 @@ double maximalOutlierPercentage = 0.8; // Use 4 points // Point must be within 10 units of curve to agree - //ParameterEstimator curveEstimator(4, 0.5); - ParameterEstimator curveEstimator(4, 2); + //ParameterEstimator curveEstimator(3, 0.1); + //ParameterEstimator curveEstimator(4, 2); + LineParamEstimator curveEstimator(2,10); cout << endl << "Computing RANSAC..." << endl; double usedData = Ransac::compute(curveParameters, &curveEstimator, coords, desiredProbabilityForNoOutliers, maximalOutlierPercentage); @@ -365,6 +370,32 @@ // } //} + + // + + // Create image of appropriate size for boundary tensor + FVector3Image boundarytensor(nw, nh); + + // Calculate the boundary tensor + boundaryTensor(srcImageRange(grey), destImage(boundarytensor), tscale); + + FImage boundarystrength(nw, nh), cornerness(nw, nh); + FVector2Image edgeness(nw,nh); + + cout << "Calculating boundary strength..." << endl; + tensorTrace(srcImageRange(boundarytensor), destImage(boundarystrength)); + cout << "Calculating corner strength..." << endl; + tensorToEdgeCorner(srcImageRange(boundarytensor), destImage(edgeness), destImage(cornerness)); + + string output = path; + output.append("boundarystrength.jpg"); + exportImage(srcImageRange(boundarystrength), ImageExportInfo(output.c_str()).setPixelType("UINT8")); + output = path; + output.append("cornerstrength.jpg"); + exportImage(srcImageRange(cornerness), ImageExportInfo(output.c_str()).setPixelType("UINT8")); + + + detect_edge(grey, filename, path, format); } Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Ransac.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Ransac.h 2009-06-07 16:17:32 UTC (rev 3925) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Ransac.h 2009-06-07 23:48:17 UTC (rev 3926) @@ -38,7 +38,9 @@ #include <boost/random/mersenne_twister.hpp> #include <boost/random/uniform_int.hpp> #include <boost/random/variate_generator.hpp> -#include "SplineEstimator.h" +//#include "SplineEstimator.h" +#include "LineParamEstimator.h" +//#include "PolynomialEstimator.h" using namespace std; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bl...@us...> - 2009-06-08 22:50:23
|
Revision: 3928 http://hugin.svn.sourceforge.net/hugin/?rev=3928&view=rev Author: blimbo Date: 2009-06-08 22:50:16 +0000 (Mon, 08 Jun 2009) Log Message: ----------- Added ANN code Modified Paths: -------------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt 2009-06-08 18:14:56 UTC (rev 3927) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt 2009-06-08 22:50:16 UTC (rev 3928) @@ -5,11 +5,9 @@ ProcessImage.cpp LineParamEstimator.cpp #PolynomialEstimator.cpp +#SplineEstimator.cpp Spline.cpp ) -#SplineEstimator.cpp - -TARGET_LINK_LIBRARIES( calibrate_lens ${image_libs} ${common_libs}) - +TARGET_LINK_LIBRARIES( calibrate_lens ${huginANN} ${image_libs} ${common_libs} ) INSTALL(TARGETS calibrate_lens DESTINATION ${BINDIR}) Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-06-08 18:14:56 UTC (rev 3927) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-06-08 22:50:16 UTC (rev 3928) @@ -31,6 +31,7 @@ //#include "SplineEstimator.h" #include "LineParamEstimator.h" //#include "PolynomialEstimator.h" +#include <ANN/ANN.h> using namespace vigra; using namespace std; @@ -94,6 +95,35 @@ } +void find_ann(vector<Point2D>& coords){ + + int k = 1; // Number of nearest neighbours + int dim = 2; // Dimensions + double eps = 0; // Error bound + int maxPts = coords.size(); // Max number of data points + int nPts = coords.size(); // Actual number of data points + ANNpointArray dataPts; // Data points + ANNpoint queryPt; // Query point + ANNidxArray nnIdx; // Near neighbor indices + ANNdistArray dists; // Near neighbor distances + ANNkd_tree* kdTree; // Search structure + + queryPt = annAllocPt(dim,0); // Allocate query point + dataPts = annAllocPts(maxPts, dim); // Allocate data points + nnIdx = new ANNidx[k]; // Allocate near neighbor indices + dists = new ANNdist[k]; // Allocate near neighbor distances + + for (unsigned int c = 0; c < coords.size(); c++){ + } + + // Clean up + delete [] nnIdx; + delete [] dists; + delete kdTree; + annClose(); + +} + void extract_coords(BImage& image, int i){ vector<Point2D> coords; @@ -122,7 +152,11 @@ // Get 5 strongest lines for (int a = 1; a < 6; a++){ cout << "Searching for line " << a << ":" << endl; - ransac(coords); + + + find_ann(coords); + //ransac(coords); + plot_inliers(image,a); for (unsigned int il = 0; il < inliers.size(); il++){ for (unsigned int c = 0; c < coords.size(); c++){ Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h 2009-06-08 18:14:56 UTC (rev 3927) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h 2009-06-08 22:50:16 UTC (rev 3928) @@ -4,7 +4,8 @@ #include "vigra/impex.hxx" #include "vigra/diff2d.hxx" -void ransac(std::vector<vigra::Point2D>&,unsigned int,unsigned int); +void ransac(std::vector<vigra::Point2D>&); +void find_ann(std::vector<vigra::Point2D>&); void plot_inliers(vigra::BImage& image, int); void extract_coords(vigra::BImage&, int); void sub_image(vigra::BImage& image); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bl...@us...> - 2009-06-09 18:16:52
|
Revision: 3933 http://hugin.svn.sourceforge.net/hugin/?rev=3933&view=rev Author: blimbo Date: 2009-06-09 18:16:37 +0000 (Tue, 09 Jun 2009) Log Message: ----------- ANN code fixed Modified Paths: -------------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/LineParamEstimator.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt 2009-06-09 11:40:09 UTC (rev 3932) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt 2009-06-09 18:16:37 UTC (rev 3933) @@ -9,5 +9,5 @@ Spline.cpp ) -TARGET_LINK_LIBRARIES( calibrate_lens ${huginANN} ${image_libs} ${common_libs} ) +TARGET_LINK_LIBRARIES( calibrate_lens huginANN ${image_libs} ${common_libs} ) INSTALL(TARGETS calibrate_lens DESTINATION ${BINDIR}) Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp 2009-06-09 11:40:09 UTC (rev 3932) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp 2009-06-09 18:16:37 UTC (rev 3933) @@ -25,6 +25,7 @@ unsigned int resize_dimension = 800; unsigned int detector = 0; std::string path = ("output/"); +//std::string path = (""); std::string format = (".jpg"); double threshold = 8; double scale = 2; @@ -32,4 +33,4 @@ unsigned int vertical_slices = 12; unsigned int horizontal_slices = 8; unsigned int generate_images = 1; -std::vector<const vigra::Point2D *> inliers; +std::vector<vigra::Point2D> inliers; Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h 2009-06-09 11:40:09 UTC (rev 3932) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h 2009-06-09 18:16:37 UTC (rev 3933) @@ -16,7 +16,7 @@ extern unsigned int vertical_slices; extern unsigned int generate_images; extern unsigned int generate_images; -extern std::vector<const vigra::Point2D *> inliers; +extern std::vector<vigra::Point2D> inliers; #endif Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/LineParamEstimator.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/LineParamEstimator.cpp 2009-06-09 11:40:09 UTC (rev 3932) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/LineParamEstimator.cpp 2009-06-09 18:16:37 UTC (rev 3933) @@ -91,7 +91,7 @@ cout << endl << "Inliers:" << endl; sort(data.begin(), data.end(), compare); for (int i = 0; i < data.size(); i++){ - inliers.push_back(data[i]); + //inliers.push_back(data[i]); cout << data[i]->x << "," << data[i]->y << endl; } cout << endl; Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp 2009-06-09 11:40:09 UTC (rev 3932) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp 2009-06-09 18:16:37 UTC (rev 3933) @@ -91,6 +91,8 @@ i++; } + //images.push_back("/home/tnugent/src/gsoc2009_lenscalibration/src/lens_calibrate/dsc_0040.jpg"); + if (!images.size()){ usage(); } Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-06-09 11:40:09 UTC (rev 3932) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-06-09 18:16:37 UTC (rev 3933) @@ -25,6 +25,7 @@ #include "vigra/tensorutilities.hxx" #include "vigra/boundarytensor.hxx" #include "vigra/diff2d.hxx" +#include <vigra/rgbvalue.hxx> #include "Globals.h" #include "ProcessImage.h" #include "Ransac.h" @@ -38,6 +39,38 @@ typedef vigra::BRGBImage::PixelType RGB; +double line_length(int x1,int y1,int x2,int y2){ + + /* + int max_x = -1, max_y = -1; + int min_x = 100000, min_y = 100000; + + for (unsigned int c = 0; c < coords.size(); c++){ + if (coords[c]->x > max_x) max_x = coords[c]->x; + if (coords[c]->y > max_y) max_y = coords[c]->y; + if (coords[c]->x < min_x) min_x = coords[c]->x; + if (coords[c]->y < min_y) min_y = coords[c]->y; + } + int d1 = max_x - min_x; + int d2 = max_y - min_y; + + cout << "x max: " << max_x << endl; + cout << "y max: " << max_y << endl; + cout << "x min: " << min_x << endl; + cout << "y min: " << min_y << endl; + + return(sqrt(d1*d1+d2*d2)); + */ + + //cout << coords[0]->x << " - " << coords[coords.size()-1]->x << endl; + //cout << coords[0]->y << " - " << coords[coords.size()-1]->y << endl; + + int d1 = x1 - x2; + int d2 = y1 - y2; + return(sqrt(d1*d1+d2*d2)); + +} + void ransac(vector<Point2D>& coords){ cout << coords.size() << " 'edge' coordinates found." << endl; @@ -71,9 +104,16 @@ cout << "Plotting inliers:\t" << inliers.size() << endl; for (unsigned int il = 0; il < inliers.size(); il++){ //cout << il << ": " << inliers[il]->x << "," << inliers[il]->y << endl; + + if (il == 0){ + vigra::initImage(srcIterRange(tmp.upperLeft() + vigra::Diff2D(inliers[il]->x-4, inliers[il]->y-4), + tmp.upperLeft() + vigra::Diff2D(inliers[il]->x+4, inliers[il]->y+4)), + RGB(255,0,0) ); + }else{ vigra::initImage(srcIterRange(tmp.upperLeft() + vigra::Diff2D(inliers[il]->x, inliers[il]->y), tmp.upperLeft() + vigra::Diff2D(inliers[il]->x+1, inliers[il]->y+1)), - RGB(255,0,0) ); + RGB(255,0,0) ); + } } @@ -95,31 +135,143 @@ } -void find_ann(vector<Point2D>& coords){ +void find_ann(vector<Point2D>& coords, unsigned int& good_lines){ - int k = 1; // Number of nearest neighbours - int dim = 2; // Dimensions - double eps = 0; // Error bound - int maxPts = coords.size(); // Max number of data points - int nPts = coords.size(); // Actual number of data points - ANNpointArray dataPts; // Data points - ANNpoint queryPt; // Query point - ANNidxArray nnIdx; // Near neighbor indices - ANNdistArray dists; // Near neighbor distances - ANNkd_tree* kdTree; // Search structure + int k = 1; // Number of nearest neighbours + int dim = 2; // Dimensions + double eps = 0.0; // Error bound + double total_distance = 0; + + // Select query point, then remove from coords + ANNpoint queryPt; // Query point queryPt = annAllocPt(dim,0); // Allocate query point - dataPts = annAllocPts(maxPts, dim); // Allocate data points - nnIdx = new ANNidx[k]; // Allocate near neighbor indices - dists = new ANNdist[k]; // Allocate near neighbor distances + srand(time(0)); + int queryidx = rand() % coords.size(); + queryPt[0] = coords[queryidx]->x; + queryPt[1] = coords[queryidx]->y; - for (unsigned int c = 0; c < coords.size(); c++){ + int first_x = coords[queryidx]->x; + int first_y = coords[queryidx]->y; + + + inliers.push_back(coords[queryidx]); + coords.erase(coords.begin()+queryidx); + //cout << "Coords size:\t" << coords.size() << endl; + cout << "Query point " << queryidx << ":\t(" << queryPt[0] << "," << queryPt[1] << ")" << endl; + + int maxPts = coords.size(); // Max number of data points + int nPts = coords.size(); // Actual number of data points + + int cont = 1; + int rev = 0; + double previous_length = 0; + + + int first_line_end_x, first_line_end_y; + + //while (inliers.size() < 100 && nPts){ + while (nPts && cont){ + + ANNkd_tree* kdTree; // Search structure + ANNpointArray dataPts; // Data points + dataPts = annAllocPts(maxPts, dim); // Allocate data points + + ANNidxArray nnIdx; // Near neighbor indices + nnIdx = new ANNidx[k]; // Allocate near neighbor indices + ANNdistArray dists; // Near neighbor distances + dists = new ANNdist[k]; // Allocate near neighbor distances + + //cout << "Loading dataPts..." << endl; + + for (unsigned int c = 0; c < nPts; c++){ + dataPts[c][0] = coords[c]->x; + dataPts[c][1] = coords[c]->y; + } + + //cout << "Constructing kd_tree..." << endl;; + kdTree = new ANNkd_tree(dataPts,nPts,dim); + //cout << "Searching kd_tree..." << endl; + kdTree->annkSearch(queryPt,k,nnIdx,dists,eps); + + //cout << "Query\tNN:\tIndex\tDistance\n"; + for (int i = 0; i < k; i++) { + + dists[i] = sqrt(dists[i]); + double this_length = line_length(first_x,first_y,coords[nnIdx[i]]->x,coords[nnIdx[i]]->y); + + // Stop conditions + if(dists[i] > 2){ + // Go back to the start point and go down the line in the reverse direction + if (rev == 0){ + cout << "Reversing..." << endl; + first_line_end_x = coords[nnIdx[i]]->x; + first_line_end_y = coords[nnIdx[i]]->y; + + queryPt[0] = first_x; + queryPt[1] = first_y; + previous_length = 0; + rev = 1; + }else{ + cont = 0; + } + // If we're closer to the first query point then we were before, the line is probably + // doubling back on itself + }else if (this_length < previous_length){ + cout << "Query: (" << queryPt[0] << "," << queryPt[1] << ")\t" << i << "\t" << nnIdx[i] << "\t" << dists[i] << "\t(" << coords[nnIdx[i]]->x << "," << coords[nnIdx[i]]->y << ")" << endl; + cout << "This point is closer to the start point than the previous one..." << endl; + + // Go back to the start point and go down the line in the reverse direction + if (rev == 0){ + cout << "Reversing..." << endl; + first_line_end_x = coords[nnIdx[i]]->x; + first_line_end_y = coords[nnIdx[i]]->y; + + queryPt[0] = first_x; + queryPt[1] = first_y; + previous_length = 0; + rev = 1; + }else{ + cont = 0; + } + }else{ + + cout << "Query: (" << queryPt[0] << "," << queryPt[1] << ")\t" << i << "\t" << nnIdx[i] << "\t" << dists[i] << "\t(" << coords[nnIdx[i]]->x << "," << coords[nnIdx[i]]->y << ")" << endl; + + // Set query point to NN + queryPt[0] = coords[nnIdx[i]]->x; + queryPt[1] = coords[nnIdx[i]]->y; + // Add to inliers + inliers.push_back(coords[nnIdx[i]]); + // Add distance + total_distance += dists[i]; + // Delete from coords + coords.erase(coords.begin()+nnIdx[i]); + nPts--; + previous_length = this_length; + } + + } + + // Clean up + delete [] nnIdx; + delete [] dists; + delete kdTree; + } - // Clean up - delete [] nnIdx; - delete [] dists; - delete kdTree; + + double length = line_length(first_line_end_x, first_line_end_y,inliers[inliers.size()-1]->x,inliers[inliers.size()-1]->y); + if(length >= 200){ + good_lines++; + }else{ + inliers.clear(); + } + + cout << "Length = " << length << endl; + cout << "#################################" << endl << endl; + + annClose(); } @@ -134,11 +286,7 @@ RGBValue<int,0u,1u,2u> value = image(w,h); if (value[0] != 255){ - - // Do we need to invert h, since 0 is at the top, but for - // RANSAC/line fitting 0 will be at the bottom? - //coords.push_back(make_pair(w,h)); - + coords.push_back(Point2D(w,h)); //cout << "(" << w << "," << h << ")" << endl; @@ -149,22 +297,20 @@ //ransac(coords); //plot_inliers(image,i); - // Get 5 strongest lines - for (int a = 1; a < 6; a++){ - cout << "Searching for line " << a << ":" << endl; - - - find_ann(coords); + unsigned int intital_coords_size = coords.size(); + + // Get 10 strongest lines + // Stop when only 25% of coordinates are left + unsigned int good_lines = 0; + while (good_lines < 10 && coords.size() && 100*((double)coords.size()/intital_coords_size) > 25){ + cout << "Searching for line " << good_lines+1 << ":" << endl; + + find_ann(coords,good_lines); //ransac(coords); - plot_inliers(image,a); - for (unsigned int il = 0; il < inliers.size(); il++){ - for (unsigned int c = 0; c < coords.size(); c++){ - if (inliers[il]->x == coords[c]->x && inliers[il]->y == coords[c]->y){ - coords.erase(coords.begin()+c); - } - } - } + if(inliers.size())plot_inliers(image,good_lines); + cout << "Remaining coords:\t" << coords.size() << "\t(" << 100*((double)coords.size()/intital_coords_size) << " %)" <<endl; + inliers.clear(); } @@ -282,8 +428,42 @@ } -void detect_edge(BImage& image, string& file, string& path, string& format){ +void nuke_corners(BImage& image, FImage& corners){ + //cout << "Searching for corners..." << endl; + + vigra::BRGBImage tmp(image.width(),image.height()); + vigra::initImage(srcIterRange(tmp.upperLeft(), + tmp.upperLeft() + vigra::Diff2D(image.width(),image.height())), + RGB(255,255,255) ); + + // Gather black pixels + for (unsigned int h = 0; h < corners.height(); h++){ + for (unsigned int w = 0; w < corners.width(); w++){ + + RGBValue<int,0u,1u,2u> value = image(w,h); + if (value[0] != 0){ + + vigra::initImage(srcIterRange(tmp.upperLeft() + vigra::Diff2D(w, h), + tmp.upperLeft() + vigra::Diff2D(w+1, h+1)), + RGB(0,0,0) ); + + + //cout << "(" << w << "," << h << ")" << endl; + } + } + } + + + string output = path; + output.append("nuked_corners.jpg"); + //exportImage(srcImageRange(tmp), ImageExportInfo(output.c_str()).setPixelType("UINT8")); + //exit(1); + +} + +void detect_edge(BImage& image, FImage& corners, string& file, string& path, string& format){ + try{ // Paint output image white @@ -330,6 +510,7 @@ // Slice image //sub_image(out); + nuke_corners(image, corners); extract_coords(out,1); } @@ -430,6 +611,6 @@ - detect_edge(grey, filename, path, format); + detect_edge(grey, cornerness, filename, path, format); } Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h 2009-06-09 11:40:09 UTC (rev 3932) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h 2009-06-09 18:16:37 UTC (rev 3933) @@ -4,10 +4,13 @@ #include "vigra/impex.hxx" #include "vigra/diff2d.hxx" +double line_length(int, int, int, int); void ransac(std::vector<vigra::Point2D>&); -void find_ann(std::vector<vigra::Point2D>&); +void find_ann(std::vector<vigra::Point2D>&, unsigned int&); + void plot_inliers(vigra::BImage& image, int); void extract_coords(vigra::BImage&, int); +void nuke_corners(vigra::BImage&, vigra::FImage&); void sub_image(vigra::BImage& image); void detect_edge(vigra::BImage&, std::string&, std::string&, std::string&); void process_image(std::string&); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bl...@us...> - 2009-06-09 23:25:17
|
Revision: 3935 http://hugin.svn.sourceforge.net/hugin/?rev=3935&view=rev Author: blimbo Date: 2009-06-09 23:25:15 +0000 (Tue, 09 Jun 2009) Log Message: ----------- ANN working quite well, added a quicker test image Modified Paths: -------------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h Added Paths: ----------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/dsc_0163.jpg Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp 2009-06-09 20:56:11 UTC (rev 3934) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp 2009-06-09 23:25:15 UTC (rev 3935) @@ -22,12 +22,15 @@ #include <string> #include <vector> +unsigned int verbose = 0; unsigned int resize_dimension = 800; unsigned int detector = 0; std::string path = ("output/"); //std::string path = (""); std::string format = (".jpg"); double threshold = 8; +double length_threshold = 0.25; +double min_line_length_squared; double scale = 2; double tscale = 1; unsigned int vertical_slices = 12; Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h 2009-06-09 20:56:11 UTC (rev 3934) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h 2009-06-09 23:25:15 UTC (rev 3935) @@ -5,11 +5,14 @@ #include <vector> #include "vigra/diff2d.hxx" +extern unsigned int verbose; extern unsigned int resize_dimension; extern unsigned int detector; extern std::string path; extern std::string format; extern double threshold; +extern double length_threshold; +extern double min_line_length_squared; extern double scale; extern double tscale; extern unsigned int horizontal_slices; Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp 2009-06-09 20:56:11 UTC (rev 3934) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp 2009-06-09 23:25:15 UTC (rev 3935) @@ -42,7 +42,9 @@ cout << " -s <float> Edge detector scale. Default 2" << endl; cout << " -t <float> Edge detector threshold. Default 8" << endl; cout << " -c <float> Boundary tensor scale. Default 2" << endl; + cout << " -l <float> Minimum line length as a fraction of image width. Default 0.25" << endl; cout << " -i <0|1> Generate intermediate images. Default 1" << endl; + cout << " -v <0|1> Verbose. Default 0" << endl; cout << " -h Print usage." << endl; cout << endl; exit(1); @@ -76,10 +78,12 @@ case 'p' : {path = argv[i]; break;} case 'f' : {format = argv[i]; break;} case 'e' : {detector = atoi(argv[i]); break;} + case 'v' : {verbose = atoi(argv[i]); break;} case 'd' : {resize_dimension = atoi(argv[i]); break;} case 's' : {scale = atof(argv[i]); break;} case 'c' : {tscale = atof(argv[i]); break;} case 't' : {threshold = atof(argv[i]); break;} + case 'l' : {length_threshold = atof(argv[i]); break;} case 'i' : {generate_images = atoi(argv[i]); break;} } Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-06-09 20:56:11 UTC (rev 3934) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-06-09 23:25:15 UTC (rev 3935) @@ -39,35 +39,11 @@ typedef vigra::BRGBImage::PixelType RGB; -double line_length(int x1,int y1,int x2,int y2){ +double line_length_squared(int x1,int y1,int x2,int y2){ - /* - int max_x = -1, max_y = -1; - int min_x = 100000, min_y = 100000; - - for (unsigned int c = 0; c < coords.size(); c++){ - if (coords[c]->x > max_x) max_x = coords[c]->x; - if (coords[c]->y > max_y) max_y = coords[c]->y; - if (coords[c]->x < min_x) min_x = coords[c]->x; - if (coords[c]->y < min_y) min_y = coords[c]->y; - } - int d1 = max_x - min_x; - int d2 = max_y - min_y; - - cout << "x max: " << max_x << endl; - cout << "y max: " << max_y << endl; - cout << "x min: " << min_x << endl; - cout << "y min: " << min_y << endl; - - return(sqrt(d1*d1+d2*d2)); - */ - - //cout << coords[0]->x << " - " << coords[coords.size()-1]->x << endl; - //cout << coords[0]->y << " - " << coords[coords.size()-1]->y << endl; - int d1 = x1 - x2; int d2 = y1 - y2; - return(sqrt(d1*d1+d2*d2)); + return(d1*d1+d2*d2); } @@ -101,7 +77,7 @@ tmp.upperLeft() + vigra::Diff2D(image.width(),image.height())), RGB(255,255,255) ); - cout << "Plotting inliers:\t" << inliers.size() << endl; + cout << "Plotting line " << i << ". Pixels:\t" << inliers.size() << endl << endl; for (unsigned int il = 0; il < inliers.size(); il++){ //cout << il << ": " << inliers[il]->x << "," << inliers[il]->y << endl; @@ -157,8 +133,7 @@ inliers.push_back(coords[queryidx]); coords.erase(coords.begin()+queryidx); - //cout << "Coords size:\t" << coords.size() << endl; - cout << "Query point " << queryidx << ":\t(" << queryPt[0] << "," << queryPt[1] << ")" << endl; + if(verbose) cout << "Random query point index:\t" << queryidx << endl << endl; int maxPts = coords.size(); // Max number of data points int nPts = coords.size(); // Actual number of data points @@ -170,7 +145,8 @@ int first_line_end_x, first_line_end_y; - //while (inliers.size() < 100 && nPts){ + if(verbose) cout << "Query Pixel\tNN Pixel\tIndex\tDistance" << endl; + while (nPts && cont){ ANNkd_tree* kdTree; // Search structure @@ -189,25 +165,22 @@ dataPts[c][1] = coords[c]->y; } - //cout << "Constructing kd_tree..." << endl;; kdTree = new ANNkd_tree(dataPts,nPts,dim); - //cout << "Searching kd_tree..." << endl; kdTree->annkSearch(queryPt,k,nnIdx,dists,eps); - - //cout << "Query\tNN:\tIndex\tDistance\n"; + for (int i = 0; i < k; i++) { dists[i] = sqrt(dists[i]); - double this_length = line_length(first_x,first_y,coords[nnIdx[i]]->x,coords[nnIdx[i]]->y); + double this_length = line_length_squared(first_x,first_y,coords[nnIdx[i]]->x,coords[nnIdx[i]]->y); // Stop conditions + // NN must be less than 2 away if(dists[i] > 2){ // Go back to the start point and go down the line in the reverse direction if (rev == 0){ - cout << "Reversing..." << endl; + if(verbose) cout << "End of line reached. Returning to inital query pixel..." << endl; first_line_end_x = coords[nnIdx[i]]->x; - first_line_end_y = coords[nnIdx[i]]->y; - + first_line_end_y = coords[nnIdx[i]]->y; queryPt[0] = first_x; queryPt[1] = first_y; previous_length = 0; @@ -218,15 +191,14 @@ // If we're closer to the first query point then we were before, the line is probably // doubling back on itself }else if (this_length < previous_length){ - cout << "Query: (" << queryPt[0] << "," << queryPt[1] << ")\t" << i << "\t" << nnIdx[i] << "\t" << dists[i] << "\t(" << coords[nnIdx[i]]->x << "," << coords[nnIdx[i]]->y << ")" << endl; - cout << "This point is closer to the start point than the previous one..." << endl; + if(verbose) cout << "(" << queryPt[0] << "," << queryPt[1] << ")\t(" << coords[nnIdx[i]]->x << "," << coords[nnIdx[i]]->y << ")" << "\t" << nnIdx[i] << "\t" << dists[i] << endl; + if(verbose) cout << "This point is closer to the inital query pixel than the previous one..." << endl; // Go back to the start point and go down the line in the reverse direction if (rev == 0){ - cout << "Reversing..." << endl; + if(verbose) cout << "End of line reached. Returning to inital query pixel..." << endl; first_line_end_x = coords[nnIdx[i]]->x; first_line_end_y = coords[nnIdx[i]]->y; - queryPt[0] = first_x; queryPt[1] = first_y; previous_length = 0; @@ -235,9 +207,7 @@ cont = 0; } }else{ - - cout << "Query: (" << queryPt[0] << "," << queryPt[1] << ")\t" << i << "\t" << nnIdx[i] << "\t" << dists[i] << "\t(" << coords[nnIdx[i]]->x << "," << coords[nnIdx[i]]->y << ")" << endl; - + if(verbose) cout << "(" << queryPt[0] << "," << queryPt[1] << ")\t(" << coords[nnIdx[i]]->x << "," << coords[nnIdx[i]]->y << ")" << "\t" << nnIdx[i] << "\t" << dists[i] << endl; // Set query point to NN queryPt[0] = coords[nnIdx[i]]->x; queryPt[1] = coords[nnIdx[i]]->y; @@ -261,16 +231,20 @@ } - double length = line_length(first_line_end_x, first_line_end_y,inliers[inliers.size()-1]->x,inliers[inliers.size()-1]->y); - if(length >= 200){ + double length = line_length_squared(first_line_end_x, first_line_end_y,inliers[inliers.size()-1]->x,inliers[inliers.size()-1]->y); + + if(verbose) cout << endl << "Length squared:\t" << length << "\t"; + + if(length >= min_line_length_squared){ good_lines++; + if(verbose) cout << "Above theshold (" << min_line_length_squared << ")" << endl; }else{ - inliers.clear(); + inliers.clear(); + if(verbose) cout << "Below theshold (" << min_line_length_squared << ")" << endl; } - - cout << "Length = " << length << endl; - cout << "#################################" << endl << endl; + if(verbose) cout << "#########################################" << endl << endl; + annClose(); @@ -299,19 +273,20 @@ unsigned int intital_coords_size = coords.size(); - cout << "Initial coords size:\t" << coords.size() << endl; + if(verbose) cout << "Initial 'edge' pixel count:\t" << coords.size() << endl << endl; // Get 10 strongest lines // Stop when only 25% of coordinates are left unsigned int good_lines = 0; - while (good_lines < 10 && coords.size() && 100*((double)coords.size()/intital_coords_size) > 25){ - cout << "Searching for line " << good_lines+1 << ":" << endl; + while (good_lines < 10 && coords.size() && 100*((double)coords.size()/intital_coords_size) >= 25){ + if(verbose) cout << "Searching for line " << good_lines+1 << ":" << endl; + if(verbose) cout << "=====================" << endl << endl; find_ann(coords,good_lines); //ransac(coords); if(inliers.size())plot_inliers(image,good_lines); - cout << "Remaining coords:\t" << coords.size() << "\t(" << 100*((double)coords.size()/intital_coords_size) << " %)" <<endl; + if(verbose) cout << "Remaining coords:\t" << coords.size() << "\t(" << 100*((double)coords.size()/intital_coords_size) << " %)" << endl << endl; inliers.clear(); } @@ -430,10 +405,8 @@ } -void nuke_corners(BImage& image, FImage& corners){ +void nuke_corners(BImage& image, FImage& corners, string& file){ - cout << "Searching for corners..." << endl; - for (unsigned int h = 0; h < corners.height(); h++){ for (unsigned int w = 0; w < corners.width(); w++){ @@ -469,8 +442,17 @@ } } if (generate_images){ + + // Create output file name string output = path; - output.append("nuked_corners.jpg"); + if (file.substr(file.length()-4,1) == (".")){ + output.append(file.substr(0,file.length()-4)); + }else{ + output.append(file.substr(0,file.length()-4)); + } + output.append("_no_corners"); + output.append(format); + cout << "Writing " << output << endl << endl; exportImage(srcImageRange(image), ImageExportInfo(output.c_str()).setPixelType("UINT8")); } } @@ -484,6 +466,8 @@ //cout << image.width() << " x " << image.height() << endl; out = 255; + cout << "Detecting edges..." << endl << endl; + if(detector){ // Call Shen-Castan detector algorithm @@ -516,14 +500,14 @@ output.append(ds.str()); output.append(format); - cout << "Writing " << output << endl << endl; + cout << "Writing " << output << endl; exportImage(srcImageRange(out), output.c_str()); } // Slice image //sub_image(out); - nuke_corners(out, corners); + nuke_corners(out, corners, file); extract_coords(out,1); } @@ -543,7 +527,8 @@ double sizefactor = 1; int nw = info.width(), nh = info.height(); - + min_line_length_squared = (length_threshold*nw)*(length_threshold*nw); + // Re-size to max dimension if (info.width() > resize_dimension || info.height() > resize_dimension){ @@ -562,8 +547,11 @@ } + min_line_length_squared = (length_threshold*nw)*(length_threshold*nw); cout << "Scaling by:\t\t" << sizefactor << endl; - cout << "New dimensions:\t\t" << nw << " x " << nh << endl << endl; + cout << "New dimensions:\t\t" << nw << " x " << nh << endl; + cout << "Minimum line length:\t" << (length_threshold*nw) << endl << endl; + // create an image of appropriate size UInt16RGBImage out(nw, nh); @@ -605,14 +593,13 @@ FVector3Image boundarytensor(nw, nh); // Calculate the boundary tensor + cout << "Calculating boundary tensor..." << endl; boundaryTensor(srcImageRange(grey), destImage(boundarytensor), tscale); FImage boundarystrength(nw, nh), cornerness(nw, nh); FVector2Image edgeness(nw,nh); - - cout << "Calculating boundary strength..." << endl; + tensorTrace(srcImageRange(boundarytensor), destImage(boundarystrength)); - cout << "Calculating corner strength..." << endl; tensorToEdgeCorner(srcImageRange(boundarytensor), destImage(edgeness), destImage(cornerness)); string output = path; @@ -622,8 +609,6 @@ output.append("cornerstrength.jpg"); exportImage(srcImageRange(cornerness), ImageExportInfo(output.c_str()).setPixelType("UINT8")); - - detect_edge(grey, cornerness, filename, path, format); } Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h 2009-06-09 20:56:11 UTC (rev 3934) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h 2009-06-09 23:25:15 UTC (rev 3935) @@ -4,13 +4,12 @@ #include "vigra/impex.hxx" #include "vigra/diff2d.hxx" -double line_length(int, int, int, int); +double line_length_squared(int, int, int, int); void ransac(std::vector<vigra::Point2D>&); void find_ann(std::vector<vigra::Point2D>&, unsigned int&); - void plot_inliers(vigra::BImage& image, int); void extract_coords(vigra::BImage&, int); -void nuke_corners(vigra::BImage&, vigra::FImage&); +void nuke_corners(vigra::BImage&, vigra::FImage&, std::string&); void sub_image(vigra::BImage& image); void detect_edge(vigra::BImage&, std::string&, std::string&, std::string&); void process_image(std::string&); Added: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/dsc_0163.jpg =================================================================== (Binary files differ) Property changes on: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/dsc_0163.jpg ___________________________________________________________________ Added: svn:mime-type + application/octet-stream This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bl...@us...> - 2009-06-10 15:48:31
|
Revision: 3936 http://hugin.svn.sourceforge.net/hugin/?rev=3936&view=rev Author: blimbo Date: 2009-06-10 15:48:29 +0000 (Wed, 10 Jun 2009) Log Message: ----------- Added a function to read PTO files, process an image within, then add line CPs to the file Modified Paths: -------------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h Added Paths: ----------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/dsc_0040.pto hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/dsc_0163.pto Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt 2009-06-09 23:25:15 UTC (rev 3935) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/CMakeLists.txt 2009-06-10 15:48:29 UTC (rev 3936) @@ -1,12 +1,12 @@ ADD_EXECUTABLE(calibrate_lens Main.cpp Globals.cpp -PointLineDist.cpp +#PointLineDist.cpp ProcessImage.cpp -LineParamEstimator.cpp +#LineParamEstimator.cpp #PolynomialEstimator.cpp #SplineEstimator.cpp -Spline.cpp +#Spline.cpp ) TARGET_LINK_LIBRARIES( calibrate_lens huginANN ${image_libs} ${common_libs} ) Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp 2009-06-09 23:25:15 UTC (rev 3935) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp 2009-06-10 15:48:29 UTC (rev 3936) @@ -28,6 +28,7 @@ std::string path = ("output/"); //std::string path = (""); std::string format = (".jpg"); +double sizefactor = 1; double threshold = 8; double length_threshold = 0.25; double min_line_length_squared; @@ -37,3 +38,4 @@ unsigned int horizontal_slices = 8; unsigned int generate_images = 1; std::vector<vigra::Point2D> inliers; +std::vector<std::vector<vigra::Point2D> > lines; Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h 2009-06-09 23:25:15 UTC (rev 3935) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h 2009-06-10 15:48:29 UTC (rev 3936) @@ -10,6 +10,7 @@ extern unsigned int detector; extern std::string path; extern std::string format; +extern double sizefactor; extern double threshold; extern double length_threshold; extern double min_line_length_squared; @@ -20,6 +21,7 @@ extern unsigned int generate_images; extern unsigned int generate_images; extern std::vector<vigra::Point2D> inliers; +extern std::vector<std::vector<vigra::Point2D> > lines; #endif Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp 2009-06-09 23:25:15 UTC (rev 3935) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp 2009-06-10 15:48:29 UTC (rev 3936) @@ -21,6 +21,7 @@ #include <fstream> #include <vector> #include <string> +#include <sys/stat.h> #include "Globals.h" #include "ProcessImage.h" @@ -28,6 +29,241 @@ #define VERSION 0.1 +bool fileexists(string strFilename) { + + struct stat stFileInfo; + bool blnReturn; + int intStat; + + // Attempt to get the file attributes + intStat = stat(strFilename.c_str(),&stFileInfo); + if(intStat == 0) { + + blnReturn = true; + }else{ + + blnReturn = false; + } + + return(blnReturn); +} + +static void tokenize(const string& str, vector<string>& tokens, const string& delimiters = " "){ + + // Skip delimiters at beginning + string::size_type lastPos = str.find_first_not_of(delimiters, 0); + + // Find first non-delimiter + string::size_type pos = str.find_first_of(delimiters, lastPos); + + while (string::npos != pos || string::npos != lastPos){ + + // Found a token, add it to the vector + tokens.push_back(str.substr(lastPos, pos - lastPos)); + + // Skip delimiters. Note the not_of + lastPos = str.find_first_not_of(delimiters, pos); + + // Find next non-delimiter + pos = str.find_first_of(delimiters, lastPos); + } + +} + +static void parse_pto(string& f,vector<string>& images,vector<string>& pto_file_top,vector<string>& +pto_file_cps,vector<string>& pto_file_end, unsigned int& image_number){ + + // Open the .pto file and make sure it's good to go + ifstream is(f.c_str()); + + if(!is.good()){ + cout << "Couldn't open Hugin project file " << f << endl << endl; + exit(1); + } + + // Get line from stream + string line; + unsigned int current = 0, counter = 0, at_cps = 0, done_cps = 0; + + while(getline(is,line)){ + + string start = line.substr(0, 1); + string autopano_start = line.substr(0, 9); + + if (at_cps == 0){ + pto_file_top.push_back(line); + } + + if (start == ("i") || autopano_start == ("#-imgfile")){ + + // Parse images from lines beginning 'i' + + //vector<string> tokens; + //tokenize(line, tokens); + //string imagename = tokens.back().substr(2, tokens.back().length()-3); + + size_t found; + string imagename = (""); + + // Hugin files + if (start == ("i")){ + + found = line.find("\""); + imagename = line.substr(found + 1, line.length() - found - 2); + //cout << imagename << endl; + + // (Old?) Autopano Pro files + }else{ + + found = line.find("\""); + imagename = line.substr(found + 1, line.length() - found - 2); + + } + + if (fileexists(imagename)){ + + // Put filenames into a vector + if(current == image_number) images.push_back(imagename); + + // Seach for the image if we can't find it, using path of PTO file + }else{ + + //cout << imagename << " doesn't exist." << endl; + + vector<string> tokens; + imagename = (""); + + // *nix file paths + if (f.find("/") < f.length() || f.substr(0, 1) == ("/")){ + + if (f.substr(0, 1) == ("/")){ + imagename += ("/"); + } + + tokenize(f, tokens, "/"); + for (unsigned int p = 0; p < tokens.size() - 1; p++){ + imagename += tokens[p]; + imagename += "/"; + } + imagename += line.substr(found + 1, line.length() - found - 2); + + // Windows file paths... experimental! + }else{ + + tokenize(f, tokens, "\\"); + for (unsigned int p = 0; p < tokens.size() - 1; p++){ + imagename += tokens[p]; + imagename += "\\"; + } + imagename += line.substr(found + 1, line.length() - found - 2); + + } + + //cout << "New search path " << imagename << endl; + + if (fileexists(imagename)){ + + // Put filenames into a vector + if(current == image_number) images.push_back(imagename); + + }else{ + + cout << "Couldn't open image " << line.substr(found + 2, line.length() - found - + 3) << endl; + + cout << "Also tried " << imagename << endl << endl; + exit(1); + } + } + + //cout << imagename << endl; + current++; + + }else if (start == ("c")){ + + pto_file_cps.push_back(line); + //cout << line << endl; + + // Marker - we're at CPs + at_cps = 1; + } + + if (at_cps && start != ("c")){ + + pto_file_end.push_back(line); + + } + + } + + is.close(); + +} + +static void write_pto(string& output_pto,vector<string>& pto_file_top,vector<string>& pto_file_cps,vector<string>& pto_file_end, unsigned int& pto_image, unsigned int& cps_per_line){ + + // File to write to + ofstream out; + out.open (output_pto.c_str()); + + if(!out.good()){ + cout << "Couldn't write to Hugin project file " << output_pto << endl << endl; + exit(1); + } + + // Print the top of the file + for (unsigned int l = 0; l < pto_file_top.size() - 1; l++){ + out << pto_file_top[l] << endl; + } + for (unsigned int l = 0; l < pto_file_cps.size(); l++){ + out << pto_file_cps[l] << endl; + } + + // Add lines + out << endl; + double invert_size_factor = 1.0/sizefactor; + for (unsigned int l = 0; l < lines.size(); l++){ + + unsigned int line_count = l+3; + + int d1 = abs(lines[l][0]->x - lines[l][lines[l].size()-1]->x); + int d2 = abs(lines[l][0]->y - lines[l][lines[l].size()-1]->y); + + if (d1 > d2){ + int segment_length = d1/(cps_per_line-1); + for (int x = lines[l][0]->x; x < lines[l][0]->x+(cps_per_line*segment_length); x+= segment_length){ + int y = 0; + for (unsigned int i = 0; i < lines[l].size(); i++){ + if (lines[l][i]->x == x) y = lines[l][i]->y; + } + int nx = (int)(x*invert_size_factor); + int ny = (int)(y*invert_size_factor); + if (y) out << "c n" << pto_image << " N" << pto_image << " x" << nx << " y" << ny << " X" << nx << " Y" << ny << " t" << line_count << endl; + } + }else{ + + int segment_length = d2/(cps_per_line-1); + for (int y = lines[l][0]->y; y < lines[l][0]->y+(cps_per_line*segment_length); y+= segment_length){ + int x = 0; + for (unsigned int i = 0; i < lines[l].size(); i++){ + if (lines[l][i]->y == y) x = lines[l][i]->x; + } + int nx = (int)(x*invert_size_factor); + int ny = (int)(y*invert_size_factor); + if (x) out << "c n" << pto_image << " N" << pto_image << " x" << nx << " y" << ny << " X" << nx << " Y" << ny << " t" << line_count << endl; + } + } + + } + // Print bottom of file + for (unsigned int l = 0; l < pto_file_end.size(); l++){ + out << pto_file_end[l] << endl; + } + + out.close(); + +} + static void usage(){ // Print usage and exit @@ -35,14 +271,17 @@ cout << endl << "Version " << VERSION << endl; cout << endl << "Usage: calibrate_lens [options] image1 image2.." << endl << endl; cout << "Options:" << endl << endl; + cout << " -p <filename> Input Hugin PTO file." << endl; + cout << " -n <int> Image in Hugin PTO file to process. Default 0" << endl; + cout << " -c <int> Control points to add to PTO file per line. Default 10." << endl; cout << " -e <0|1> Edge detector. 0 = Canny (default) 1 = Shen-Castan." << endl; cout << " -d <int> Maximum dimension for re-sized image prior to processing. Default 800." << endl; cout << " -f <string> Output file format. Default .JPG" << endl; - cout << " -p <path> Output path. Default output/" << endl; + cout << " -o <path> Output path. Default output/" << endl; cout << " -s <float> Edge detector scale. Default 2" << endl; cout << " -t <float> Edge detector threshold. Default 8" << endl; - cout << " -c <float> Boundary tensor scale. Default 2" << endl; - cout << " -l <float> Minimum line length as a fraction of image width. Default 0.25" << endl; + cout << " -b <float> Boundary tensor scale. Default 2" << endl; + cout << " -l <float> Minimum line length as a fraction of longest dimension. Default 0.25" << endl; cout << " -i <0|1> Generate intermediate images. Default 1" << endl; cout << " -v <0|1> Verbose. Default 0" << endl; cout << " -h Print usage." << endl; @@ -59,7 +298,10 @@ } unsigned int i = 1; - vector<string> images; + unsigned int pto_image = 0; + unsigned int cps_per_line = 10; + string pto_file = (""),output_pto = (""); + vector<string> images,pto_file_top,pto_file_cps,pto_file_end; // Deal with arguments while(i < argc){ @@ -75,13 +317,16 @@ // Put some more argument options in here later case 'h' : {usage();} - case 'p' : {path = argv[i]; break;} - case 'f' : {format = argv[i]; break;} + case 'o' : {path = argv[i]; break;} + case 'p' : {pto_file = argv[i]; break;} + case 'n' : {pto_image = atoi(argv[i]); break;} + case 'c' : {cps_per_line = atoi(argv[i]); break;} + case 'f' : {format = argv[i]; break;} case 'e' : {detector = atoi(argv[i]); break;} case 'v' : {verbose = atoi(argv[i]); break;} case 'd' : {resize_dimension = atoi(argv[i]); break;} case 's' : {scale = atof(argv[i]); break;} - case 'c' : {tscale = atof(argv[i]); break;} + case 'b' : {tscale = atof(argv[i]); break;} case 't' : {threshold = atof(argv[i]); break;} case 'l' : {length_threshold = atof(argv[i]); break;} case 'i' : {generate_images = atoi(argv[i]); break;} @@ -95,9 +340,21 @@ i++; } - //images.push_back("/home/tnugent/src/gsoc2009_lenscalibration/src/lens_calibrate/dsc_0040.jpg"); + // Set output .pto filename if not given + if (pto_file != ("")){ + output_pto = pto_file.substr(0,pto_file.length()-4).append("_calibrate.pto"); + // Process PTO file + if (fileexists(pto_file)){ + //cout << "Parsing Hugin project file " << pto_file << endl; + parse_pto(pto_file,images,pto_file_top,pto_file_cps,pto_file_end,pto_image); + }else{ + cout << endl << "Couldn't open Hugin project file " << pto_file << endl << endl; + exit(1); + } + } if (!images.size()){ + //cout << "No images provided!" << endl << endl; usage(); } @@ -116,6 +373,12 @@ } + if (pto_file != ("")){ + write_pto(output_pto,pto_file_top,pto_file_cps,pto_file_end,pto_image,cps_per_line); + cout << "Written file " << output_pto << endl; + + } + cout << endl; return(1); Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-06-09 23:25:15 UTC (rev 3935) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-06-10 15:48:29 UTC (rev 3936) @@ -28,9 +28,9 @@ #include <vigra/rgbvalue.hxx> #include "Globals.h" #include "ProcessImage.h" -#include "Ransac.h" +//#include "Ransac.h" //#include "SplineEstimator.h" -#include "LineParamEstimator.h" +//#include "LineParamEstimator.h" //#include "PolynomialEstimator.h" #include <ANN/ANN.h> @@ -47,6 +47,7 @@ } +/* void ransac(vector<Point2D>& coords){ cout << coords.size() << " 'edge' coordinates found." << endl; @@ -69,7 +70,16 @@ cout << "Percentage of points which were used for final estimate: "<< usedData/coords.size() << " % (" << usedData << ")" << endl << endl; } +*/ +bool compare_yx (const vigra::Point2D i,const vigra::Point2D j){ + return (j->x<i->x); +} + +bool compare_xy (const vigra::Point2D i,const vigra::Point2D j){ + return (i->x<j->x); +} + void plot_inliers(BImage& image, int i){ vigra::BRGBImage tmp(image.width(),image.height()); @@ -77,24 +87,34 @@ tmp.upperLeft() + vigra::Diff2D(image.width(),image.height())), RGB(255,255,255) ); + unsigned int top = 0; + unsigned int bottom = 100000; + unsigned int left = 100000; + unsigned int right = 0; + cout << "Plotting line " << i << ". Pixels:\t" << inliers.size() << endl << endl; for (unsigned int il = 0; il < inliers.size(); il++){ - //cout << il << ": " << inliers[il]->x << "," << inliers[il]->y << endl; - - //if (il == 0){ - //vigra::initImage(srcIterRange(tmp.upperLeft() + vigra::Diff2D(inliers[il]->x-4, inliers[il]->y-4), - // tmp.upperLeft() + vigra::Diff2D(inliers[il]->x+4, inliers[il]->y+4)), - // RGB(255,0,0) ); - //}else{ + + if(inliers[il]->x < left) left = inliers[il]->x; + if(inliers[il]->x > right) right = inliers[il]->x; + if(inliers[il]->y < bottom) bottom = inliers[il]->y; + if(inliers[il]->y > top) top = inliers[il]->y; + vigra::initImage(srcIterRange(tmp.upperLeft() + vigra::Diff2D(inliers[il]->x, inliers[il]->y), tmp.upperLeft() + vigra::Diff2D(inliers[il]->x+1, inliers[il]->y+1)), RGB(255,0,0) ); - //} - + } + + // Sort pixels for adding CPs to PTO file + int d1 = abs(top-bottom); + int d2 = abs(right-left); + if(d2 > d1){ + sort(inliers.begin(), inliers.end(), compare_xy); + }else{ + sort(inliers.begin(), inliers.end(), compare_yx); } - + lines.push_back(inliers); - //exit(1); if (generate_images){ // Export slice to file @@ -141,8 +161,8 @@ int cont = 1; int rev = 0; double previous_length = 0; + double gap_limit = 4; - int first_line_end_x, first_line_end_y; if(verbose) cout << "Query Pixel\tNN Pixel\tIndex\tDistance" << endl; @@ -159,7 +179,6 @@ dists = new ANNdist[k]; // Allocate near neighbor distances //cout << "Loading dataPts..." << endl; - for (unsigned int c = 0; c < nPts; c++){ dataPts[c][0] = coords[c]->x; dataPts[c][1] = coords[c]->y; @@ -175,7 +194,7 @@ // Stop conditions // NN must be less than 2 away - if(dists[i] > 2){ + if(dists[i] > gap_limit){ // Go back to the start point and go down the line in the reverse direction if (rev == 0){ if(verbose) cout << "End of line reached. Returning to inital query pixel..." << endl; @@ -244,7 +263,6 @@ } if(verbose) cout << "#########################################" << endl << endl; - annClose(); @@ -276,9 +294,9 @@ if(verbose) cout << "Initial 'edge' pixel count:\t" << coords.size() << endl << endl; // Get 10 strongest lines - // Stop when only 25% of coordinates are left + // Stop when only 35% of coordinates are left unsigned int good_lines = 0; - while (good_lines < 10 && coords.size() && 100*((double)coords.size()/intital_coords_size) >= 25){ + while (good_lines < 10 && coords.size() && 100*((double)coords.size()/intital_coords_size) >= 35){ if(verbose) cout << "Searching for line " << good_lines+1 << ":" << endl; if(verbose) cout << "=====================" << endl << endl; @@ -290,9 +308,13 @@ inliers.clear(); } + if (good_lines == 0){ + cout << "No lines found!" << endl; + } } +/* void sub_image(BImage& image){ unsigned int vertical_slice_width = image.width()/vertical_slices; @@ -404,22 +426,24 @@ } } +*/ void nuke_corners(BImage& image, FImage& corners, string& file){ for (unsigned int h = 0; h < corners.height(); h++){ for (unsigned int w = 0; w < corners.width(); w++){ - RGBValue<int,0u,1u,2u> value = corners(w,h); // Change this threshold to remove more corner pixels - if (value[0] > 250){ - - // Change the size of these boxes - int left = w-2; - int top = h-2; - int right = w+2; - int bottom = h+2; + if (corners(w,h) > 250){ + + // Change the size of the box to draw around corner pixel + int size = 2; + int left = w-size; + int top = h-size; + int right = w+size; + int bottom = h+size; + /* size = 2 = 10305 pixels remain size = 3 = 9449 pixels remain @@ -445,12 +469,13 @@ // Create output file name string output = path; - if (file.substr(file.length()-4,1) == (".")){ - output.append(file.substr(0,file.length()-4)); - }else{ - output.append(file.substr(0,file.length()-4)); - } - output.append("_no_corners"); + //if (file.substr(file.length()-4,1) == (".")){ + // output.append(file.substr(0,file.length()-4)); + //}else{ + // output.append(file.substr(0,file.length()-4)); + //} + //output.append("_no_corners"); + output.append("edges_minus_corners"); output.append(format); cout << "Writing " << output << endl << endl; exportImage(srcImageRange(image), ImageExportInfo(output.c_str()).setPixelType("UINT8")); @@ -485,16 +510,18 @@ // Create output file name string output = path; - if (file.substr(file.length()-4,1) == (".")){ - output.append(file.substr(0,file.length()-4)); - }else{ - output.append(file.substr(0,file.length()-4)); - } - output.append("_threshold"); + //if (file.substr(file.length()-4,1) == (".")){ + // output.append(file.substr(0,file.length()-4)); + //}else{ + // output.append(file.substr(0,file.length()-4)); + //} + //output.append("_threshold"); + output.append("edges_threshold_"); + stringstream dt; dt << threshold; output.append(dt.str()); - output.append("_scale"); + output.append("_scale_"); stringstream ds; ds << scale; output.append(ds.str()); @@ -525,10 +552,14 @@ importImage(info, destImage(in)); - double sizefactor = 1; int nw = info.width(), nh = info.height(); - min_line_length_squared = (length_threshold*nw)*(length_threshold*nw); + if (nw > nh){ + min_line_length_squared = (length_threshold*nw)*(length_threshold*nw); + }else{ + min_line_length_squared = (length_threshold*nh)*(length_threshold*nh); + } + // Re-size to max dimension if (info.width() > resize_dimension || info.height() > resize_dimension){ @@ -538,16 +569,18 @@ // calculate new image size nw = resize_dimension; nh = static_cast<int>(0.5 + (sizefactor*info.height())); + min_line_length_squared = (length_threshold*nw)*(length_threshold*nw); }else{ sizefactor = (double)resize_dimension/info.height(); // calculate new image size nw = static_cast<int>(0.5 + (sizefactor*info.width())); nh = resize_dimension; + min_line_length_squared = (length_threshold*nh)*(length_threshold*nh); } - min_line_length_squared = (length_threshold*nw)*(length_threshold*nw); + cout << "Scaling by:\t\t" << sizefactor << endl; cout << "New dimensions:\t\t" << nw << " x " << nh << endl; cout << "Minimum line length:\t" << (length_threshold*nw) << endl << endl; Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h 2009-06-09 23:25:15 UTC (rev 3935) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h 2009-06-10 15:48:29 UTC (rev 3936) @@ -5,12 +5,14 @@ #include "vigra/diff2d.hxx" double line_length_squared(int, int, int, int); -void ransac(std::vector<vigra::Point2D>&); +bool compare_xy (const vigra::Point2D,const vigra::Point2D); +bool compare_yx (const vigra::Point2D,const vigra::Point2D); +//void ransac(std::vector<vigra::Point2D>&); void find_ann(std::vector<vigra::Point2D>&, unsigned int&); void plot_inliers(vigra::BImage& image, int); void extract_coords(vigra::BImage&, int); void nuke_corners(vigra::BImage&, vigra::FImage&, std::string&); -void sub_image(vigra::BImage& image); +//void sub_image(vigra::BImage& image); void detect_edge(vigra::BImage&, std::string&, std::string&, std::string&); void process_image(std::string&); Added: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/dsc_0040.pto =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/dsc_0040.pto (rev 0) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/dsc_0040.pto 2009-06-10 15:48:29 UTC (rev 3936) @@ -0,0 +1,35 @@ +# hugin project file +#hugin_ptoversion 2 +p f2 w3000 h1500 v360 E10.3056 R0 n"TIFF_m c:NONE r:CROP" +m g1 i0 f0 m2 p0.00784314 + +# image lines +#-hugin cropFactor=1.5 +i w2000 h1328 f3 Eb1 Eev10.3056342190224 Er1 Ra0 Rb0 Rc0 Rd0 Re0 Va1 Vb0 Vc0 Vd0 Vx0 Vy0 a0 b0 c0 d0 e0 g0 p0 r0 t0 v137.679087101882 y0 Vm5 u10 n"dsc_0040.jpg" + + +# specify variables that should be optimized +v + +# control points + +#hugin_optimizeReferenceImage 0 +#hugin_blender enblend +#hugin_remapper nona +#hugin_enblendOptions +#hugin_enfuseOptions +#hugin_hdrmergeOptions +#hugin_outputLDRBlended true +#hugin_outputLDRLayers false +#hugin_outputLDRExposureRemapped false +#hugin_outputLDRExposureLayers false +#hugin_outputLDRExposureBlended false +#hugin_outputHDRBlended false +#hugin_outputHDRLayers false +#hugin_outputHDRStacks false +#hugin_outputLayersCompression PACKBITS +#hugin_outputImageType tif +#hugin_outputImageTypeCompression NONE +#hugin_outputJPEGQuality 100 +#hugin_outputImageTypeHDR exr +#hugin_outputImageTypeHDRCompression Added: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/dsc_0163.pto =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/dsc_0163.pto (rev 0) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/dsc_0163.pto 2009-06-10 15:48:29 UTC (rev 3936) @@ -0,0 +1,35 @@ +# hugin project file +#hugin_ptoversion 2 +p f2 w3000 h1500 v360 E0 R0 n"TIFF c:NONE r:CROP" +m g1 i0 f0 m2 p0.00784314 + +# image lines +#-hugin cropFactor=1.5 +i w1318 h2000 f3 Eb1 Eev0 Er1 Ra0 Rb0 Rc0 Rd0 Re0 Va1 Vb0 Vc0 Vd0 Vx0 Vy0 a0 b0 c0 d0 e0 g0 p0 r0 t0 v90.939505324643 y0 Vm5 u10 n"dsc_0163.jpg" + + +# specify variables that should be optimized +v + +# control points + +#hugin_optimizeReferenceImage 0 +#hugin_blender enblend +#hugin_remapper nona +#hugin_enblendOptions +#hugin_enfuseOptions +#hugin_hdrmergeOptions +#hugin_outputLDRBlended true +#hugin_outputLDRLayers false +#hugin_outputLDRExposureRemapped false +#hugin_outputLDRExposureLayers false +#hugin_outputLDRExposureBlended false +#hugin_outputHDRBlended false +#hugin_outputHDRLayers false +#hugin_outputHDRStacks false +#hugin_outputLayersCompression PACKBITS +#hugin_outputImageType tif +#hugin_outputImageTypeCompression NONE +#hugin_outputJPEGQuality 100 +#hugin_outputImageTypeHDR exr +#hugin_outputImageTypeHDRCompression This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bl...@us...> - 2009-06-11 14:17:41
|
Revision: 3938 http://hugin.svn.sourceforge.net/hugin/?rev=3938&view=rev Author: blimbo Date: 2009-06-11 14:17:33 +0000 (Thu, 11 Jun 2009) Log Message: ----------- Filter ANN search space by query proximity, huge speed increase Modified Paths: -------------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp 2009-06-10 18:16:19 UTC (rev 3937) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp 2009-06-11 14:17:33 UTC (rev 3938) @@ -30,10 +30,11 @@ std::string format = (".jpg"); double sizefactor = 1; double threshold = 8; -double length_threshold = 0.25; +double length_threshold = 0.2; double min_line_length_squared; double scale = 2; double tscale = 1; +unsigned int gap_limit = 3; unsigned int vertical_slices = 12; unsigned int horizontal_slices = 8; unsigned int generate_images = 1; Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h 2009-06-10 18:16:19 UTC (rev 3937) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h 2009-06-11 14:17:33 UTC (rev 3938) @@ -16,6 +16,7 @@ extern double min_line_length_squared; extern double scale; extern double tscale; +extern unsigned int gap_limit; extern unsigned int horizontal_slices; extern unsigned int vertical_slices; extern unsigned int generate_images; Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp 2009-06-10 18:16:19 UTC (rev 3937) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp 2009-06-11 14:17:33 UTC (rev 3938) @@ -281,7 +281,8 @@ cout << " -s <float> Edge detector scale. Default 2" << endl; cout << " -t <float> Edge detector threshold. Default 8" << endl; cout << " -b <float> Boundary tensor scale. Default 2" << endl; - cout << " -l <float> Minimum line length as a fraction of longest dimension. Default 0.25" << endl; + cout << " -g <int> Gap in pixels permitted within a line. Default 3" << endl; + cout << " -l <float> Minimum line length as a fraction of longest dimension. Default 0.2" << endl; cout << " -i <0|1> Generate intermediate images. Default 1" << endl; cout << " -v <0|1> Verbose. Default 0" << endl; cout << " -h Print usage." << endl; @@ -323,6 +324,7 @@ case 'c' : {cps_per_line = atoi(argv[i]); break;} case 'f' : {format = argv[i]; break;} case 'e' : {detector = atoi(argv[i]); break;} + case 'g' : {gap_limit = atoi(argv[i]); break;} case 'v' : {verbose = atoi(argv[i]); break;} case 'd' : {resize_dimension = atoi(argv[i]); break;} case 's' : {scale = atof(argv[i]); break;} @@ -339,6 +341,8 @@ i++; } + + if (gap_limit < 2) gap_limit = 2; // Set output .pto filename if not given if (pto_file != ("")){ Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-06-10 18:16:19 UTC (rev 3937) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-06-11 14:17:33 UTC (rev 3938) @@ -24,6 +24,7 @@ #include "vigra/stdimagefunctions.hxx" #include "vigra/tensorutilities.hxx" #include "vigra/boundarytensor.hxx" +#include <vigra/orientedtensorfilters.hxx> #include "vigra/diff2d.hxx" #include <vigra/rgbvalue.hxx> #include "Globals.h" @@ -137,9 +138,8 @@ int k = 1; // Number of nearest neighbours int dim = 2; // Dimensions double eps = 0.0; // Error bound - double total_distance = 0; - // Select query point, then remove from coords + ANNpoint queryPt; // Query point queryPt = annAllocPt(dim,0); // Allocate query point srand(time(0)); @@ -150,24 +150,22 @@ int first_x = coords[queryidx]->x; int first_y = coords[queryidx]->y; - + // Select query point, then remove from coords inliers.push_back(coords[queryidx]); coords.erase(coords.begin()+queryidx); + if(verbose) cout << "Random query point index:\t" << queryidx << endl << endl; int maxPts = coords.size(); // Max number of data points int nPts = coords.size(); // Actual number of data points - int cont = 1; int rev = 0; double previous_length = 0; - double gap_limit = 4; + int first_line_end_x = first_x, first_line_end_y = first_y; - int first_line_end_x, first_line_end_y; - if(verbose) cout << "Query Pixel\tNN Pixel\tIndex\tDistance" << endl; - while (nPts && cont){ + while (cont){ ANNkd_tree* kdTree; // Search structure ANNpointArray dataPts; // Data points @@ -178,28 +176,42 @@ ANNdistArray dists; // Near neighbor distances dists = new ANNdist[k]; // Allocate near neighbor distances - //cout << "Loading dataPts..." << endl; - for (unsigned int c = 0; c < nPts; c++){ - dataPts[c][0] = coords[c]->x; - dataPts[c][1] = coords[c]->y; + // Only load data points that are within gap_limit of query pixel + vector<Point2D> close_neighbors; + vector<int> coords_index; + for (unsigned int c = 0; c < coords.size(); c++){ + if(coords[c]->x > queryPt[0]-gap_limit && coords[c]->x < queryPt[0]+gap_limit){ + if(coords[c]->y > queryPt[1]-gap_limit && coords[c]->y < queryPt[1]+gap_limit){ + close_neighbors.push_back(coords[c]); + coords_index.push_back(c); + } + } } + + nPts = close_neighbors.size(); + if(nPts){ - kdTree = new ANNkd_tree(dataPts,nPts,dim); - kdTree->annkSearch(queryPt,k,nnIdx,dists,eps); + //cout << "nPts:\t" << nPts << endl; + for (unsigned int c = 0; c < nPts; c++){ + dataPts[c][0] = close_neighbors[c]->x; + dataPts[c][1] = close_neighbors[c]->y; + } - for (int i = 0; i < k; i++) { + kdTree = new ANNkd_tree(dataPts,nPts,dim); + kdTree->annkSearch(queryPt,k,nnIdx,dists,eps); - dists[i] = sqrt(dists[i]); - double this_length = line_length_squared(first_x,first_y,coords[nnIdx[i]]->x,coords[nnIdx[i]]->y); - - // Stop conditions - // NN must be less than 2 away - if(dists[i] > gap_limit){ + dists[0] = sqrt(dists[0]); + double this_length = line_length_squared(first_x,first_y,close_neighbors[nnIdx[0]]->x,close_neighbors[nnIdx[0]]->y); + + if (this_length < previous_length){ + if(verbose) cout << "(" << queryPt[0] << "," << queryPt[1] << ")\t(" << close_neighbors[nnIdx[0]]->x << "," << close_neighbors[nnIdx[0]]->y << ")" << "\t" << nnIdx[0] << "\t" << dists[0] << endl; + if(verbose) cout << "This point is closer to the inital query pixel than the previous one..." << endl; + // Go back to the start point and go down the line in the reverse direction if (rev == 0){ if(verbose) cout << "End of line reached. Returning to inital query pixel..." << endl; - first_line_end_x = coords[nnIdx[i]]->x; - first_line_end_y = coords[nnIdx[i]]->y; + first_line_end_x = close_neighbors[nnIdx[0]]->x; + first_line_end_y = close_neighbors[nnIdx[0]]->y; queryPt[0] = first_x; queryPt[1] = first_y; previous_length = 0; @@ -207,52 +219,52 @@ }else{ cont = 0; } - // If we're closer to the first query point then we were before, the line is probably - // doubling back on itself - }else if (this_length < previous_length){ - if(verbose) cout << "(" << queryPt[0] << "," << queryPt[1] << ")\t(" << coords[nnIdx[i]]->x << "," << coords[nnIdx[i]]->y << ")" << "\t" << nnIdx[i] << "\t" << dists[i] << endl; - if(verbose) cout << "This point is closer to the inital query pixel than the previous one..." << endl; + }else{ + if(verbose) cout << "(" << queryPt[0] << "," << queryPt[1] << ")\t(" << close_neighbors[nnIdx[0]]->x << "," << close_neighbors[nnIdx[0]]->y << ")" << "\t" << nnIdx[0] << "\t" << dists[0] << endl; - // Go back to the start point and go down the line in the reverse direction - if (rev == 0){ - if(verbose) cout << "End of line reached. Returning to inital query pixel..." << endl; - first_line_end_x = coords[nnIdx[i]]->x; - first_line_end_y = coords[nnIdx[i]]->y; + // Set query point to NN + queryPt[0] = close_neighbors[nnIdx[0]]->x; + queryPt[1] = close_neighbors[nnIdx[0]]->y; + + // Add NN to inliers + inliers.push_back(close_neighbors[nnIdx[0]]); + + // Erase it from coords so we don't see it again + coords.erase(coords.begin()+coords_index[nnIdx[0]]); + previous_length = this_length; + } + + // Clean up + delete [] nnIdx; + delete [] dists; + delete kdTree; + + }else{ + if (rev == 0){ + if(verbose) cout << "No more pixels in this region. Returning to inital query pixel..." << endl; + if (inliers.size()){ + first_line_end_x = inliers[inliers.size()-1]->x; + first_line_end_y = inliers[inliers.size()-1]->y; queryPt[0] = first_x; queryPt[1] = first_y; previous_length = 0; rev = 1; + }else{ cont = 0; - } + } }else{ - if(verbose) cout << "(" << queryPt[0] << "," << queryPt[1] << ")\t(" << coords[nnIdx[i]]->x << "," << coords[nnIdx[i]]->y << ")" << "\t" << nnIdx[i] << "\t" << dists[i] << endl; - // Set query point to NN - queryPt[0] = coords[nnIdx[i]]->x; - queryPt[1] = coords[nnIdx[i]]->y; - // Add to inliers - inliers.push_back(coords[nnIdx[i]]); - // Add distance - total_distance += dists[i]; - // Delete from coords - coords.erase(coords.begin()+nnIdx[i]); - nPts--; - previous_length = this_length; + cont = 0; } - - } - - // Clean up - delete [] nnIdx; - delete [] dists; - delete kdTree; - + } } - - + annClose(); + double length = line_length_squared(first_line_end_x, first_line_end_y,inliers[inliers.size()-1]->x,inliers[inliers.size()-1]->y); - if(verbose) cout << endl << "Length squared:\t" << length << "\t"; + if(verbose) cout << endl << "Measuring distance from " << first_line_end_x << "," << first_line_end_y << " to " << inliers[inliers.size()-1]->x << "," << + inliers[inliers.size()-1]->y <<endl; + if(verbose) cout << "Length squared:\t" << length << "\t"; if(length >= min_line_length_squared){ good_lines++; @@ -262,9 +274,7 @@ if(verbose) cout << "Below theshold (" << min_line_length_squared << ")" << endl; } - if(verbose) cout << "#########################################" << endl << endl; - - annClose(); + if(verbose) cout << "##############################################" << endl << endl; } @@ -296,7 +306,8 @@ // Get 10 strongest lines // Stop when only 35% of coordinates are left unsigned int good_lines = 0; - while (good_lines < 10 && coords.size() && 100*((double)coords.size()/intital_coords_size) >= 35){ + //while (good_lines < 10 && coords.size() && 100*((double)coords.size()/intital_coords_size) >= 25){ + while (good_lines < 10 && coords.size()){ if(verbose) cout << "Searching for line " << good_lines+1 << ":" << endl; if(verbose) cout << "=====================" << endl << endl; @@ -437,8 +448,7 @@ if (corners(w,h) > 250){ // Change the size of the box to draw around corner pixel - int size = 2; - + int size = 3; int left = w-size; int top = h-size; int right = w+size; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bl...@us...> - 2009-06-14 11:03:40
|
Revision: 3942 http://hugin.svn.sourceforge.net/hugin/?rev=3942&view=rev Author: blimbo Date: 2009-06-14 11:03:38 +0000 (Sun, 14 Jun 2009) Log Message: ----------- Fixed addition of CPs Modified Paths: -------------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/dsc_0040.pto hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/dsc_0163.pto Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp 2009-06-13 15:13:07 UTC (rev 3941) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp 2009-06-14 11:03:38 UTC (rev 3942) @@ -221,6 +221,7 @@ // Add lines out << endl; + int start = 1; double invert_size_factor = 1.0/sizefactor; for (unsigned int l = 0; l < lines.size(); l++){ @@ -231,26 +232,48 @@ if (d1 > d2){ int segment_length = d1/(cps_per_line-1); - for (int x = lines[l][0]->x; x < lines[l][0]->x+(cps_per_line*segment_length); x+= segment_length){ + for (int x = lines[l][0]->x; x < lines[l][0]->x+(2*cps_per_line*segment_length); x+= segment_length){ int y = 0; for (unsigned int i = 0; i < lines[l].size(); i++){ if (lines[l][i]->x == x) y = lines[l][i]->y; } int nx = (int)(x*invert_size_factor); int ny = (int)(y*invert_size_factor); - if (y) out << "c n" << pto_image << " N" << pto_image << " x" << nx << " y" << ny << " X" << nx << " Y" << ny << " t" << line_count << endl; + //if (y) out << "c n" << pto_image << " N" << pto_image << " x" << nx << " y" << ny << " X" << nx << " Y" << ny << " t" << line_count << endl; + if (y){ + //cout << start <<endl; + if(start){ + out << "c n" << pto_image << " N" << pto_image << " x" << nx + << " y" << ny; + start = 0; + }else{ + out << " X" << nx << " Y" << ny << " t" << line_count << endl; + start = 1; + } + } } }else{ int segment_length = d2/(cps_per_line-1); - for (int y = lines[l][0]->y; y < lines[l][0]->y+(cps_per_line*segment_length); y+= segment_length){ + for (int y = lines[l][0]->y; y < lines[l][0]->y+(2*cps_per_line*segment_length); y+= segment_length){ int x = 0; for (unsigned int i = 0; i < lines[l].size(); i++){ if (lines[l][i]->y == y) x = lines[l][i]->x; } int nx = (int)(x*invert_size_factor); int ny = (int)(y*invert_size_factor); - if (x) out << "c n" << pto_image << " N" << pto_image << " x" << nx << " y" << ny << " X" << nx << " Y" << ny << " t" << line_count << endl; + //if (x) out << "c n" << pto_image << " N" << pto_image << " x" << nx << " y" << ny << " X" << nx << " Y" << ny << " t" << line_count << endl; + if (x){ + //cout << start <<endl; + if(start){ + out << "c n" << pto_image << " N" << pto_image << " x" << nx + << " y" << ny; + start = 0; + }else{ + out << " X" << nx << " Y" << ny << " t" << line_count << endl; + start = 1; + } + } } } Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-06-13 15:13:07 UTC (rev 3941) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-06-14 11:03:38 UTC (rev 3942) @@ -445,7 +445,7 @@ for (unsigned int w = 0; w < corners.width(); w++){ // Change this threshold to remove more corner pixels - if (corners(w,h) > 250){ + if (corners(w,h) > 150){ // Change the size of the box to draw around corner pixel int size = 3; @@ -610,22 +610,21 @@ //exportImage(srcImageRange(grey), ImageExportInfo("resized.jpg").setPixelType("UINT8")); // Uncomment this block to generate images at different scales/thresholds - // - //double scale_start = 0.1 ,scale_stop = 25; - //double threshold_start = 0, threshold_stop = 10; - //double scale_increment = 2, threshold_increment = 1; - // - //for (double threshold_test = threshold_start; threshold_test <= threshold_stop; threshold_test += threshold_increment){ - // - // for (double scale_test = scale_start;scale_test <= scale_stop; scale_test += scale_increment){ - // - // detect_edge(grey, filename, path, format); - // - // } - //} - + /* - // + double scale_start = 0.1 ,scale_stop = 25; + double threshold_start = 0, threshold_stop = 10; + double scale_increment = 2, threshold_increment = 1; + + for (double threshold_test = threshold_start; threshold_test <= threshold_stop; threshold_test += threshold_increment){ + + for (double scale_test = scale_start;scale_test <= scale_stop; scale_test += scale_increment){ + + detect_edge(grey, filename, path, format); + + } + } + */ // Create image of appropriate size for boundary tensor FVector3Image boundarytensor(nw, nh); Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/dsc_0040.pto =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/dsc_0040.pto 2009-06-13 15:13:07 UTC (rev 3941) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/dsc_0040.pto 2009-06-14 11:03:38 UTC (rev 3942) @@ -1,14 +1,17 @@ # hugin project file #hugin_ptoversion 2 -p f2 w3000 h1500 v360 E10.3056 R0 n"TIFF_m c:NONE r:CROP" +p f0 w3000 h3000 v179 E10.3056 R0 n"TIFF_m c:NONE r:CROP" m g1 i0 f0 m2 p0.00784314 # image lines #-hugin cropFactor=1.5 i w2000 h1328 f3 Eb1 Eev10.3056342190224 Er1 Ra0 Rb0 Rc0 Rd0 Re0 Va1 Vb0 Vc0 Vd0 Vx0 Vy0 a0 b0 c0 d0 e0 g0 p0 r0 t0 v137.679087101882 y0 Vm5 u10 n"dsc_0040.jpg" +#-hugin cropFactor=1.5 +i w2000 h1328 f3 Eb1 Eev10.3056342190224 Er1 Ra0 Rb0 Rc0 Rd0 Re0 Va1 Vb0 Vc0 Vd0 Vx0 Vy0 a0 b0 c0 d0 e0 g0 p0 r0 t0 v137.679087101882 y0 Vm5 u10 n"dsc_0040.jpg" # specify variables that should be optimized +v b0 v # control points Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/dsc_0163.pto =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/dsc_0163.pto 2009-06-13 15:13:07 UTC (rev 3941) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/dsc_0163.pto 2009-06-14 11:03:38 UTC (rev 3942) @@ -1,14 +1,18 @@ # hugin project file #hugin_ptoversion 2 -p f2 w3000 h1500 v360 E0 R0 n"TIFF c:NONE r:CROP" +p f0 w3000 h3000 v179 E0 R0 n"TIFF_m c:NONE r:CROP" m g1 i0 f0 m2 p0.00784314 # image lines #-hugin cropFactor=1.5 i w1318 h2000 f3 Eb1 Eev0 Er1 Ra0 Rb0 Rc0 Rd0 Re0 Va1 Vb0 Vc0 Vd0 Vx0 Vy0 a0 b0 c0 d0 e0 g0 p0 r0 t0 v90.939505324643 y0 Vm5 u10 n"dsc_0163.jpg" +#-hugin cropFactor=1.5 +i w1318 h2000 f3 Eb1 Eev0 Er1 Ra0 Rb0 Rc0 Rd0 Re0 Va1 Vb0 Vc0 Vd0 Vx0 Vy0 a0 b0 c0 d0 e0 g0 p0 r0 t0 v90.939505324643 y0 Vm5 u10 n"dsc_0163.jpg" # specify variables that should be optimized +v b0 +v b1 v # control points This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bl...@us...> - 2009-06-18 19:49:30
|
Revision: 3948 http://hugin.svn.sourceforge.net/hugin/?rev=3948&view=rev Author: blimbo Date: 2009-06-18 19:49:26 +0000 (Thu, 18 Jun 2009) Log Message: ----------- Line orientation added as 3rd dimension in ANN search Modified Paths: -------------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-06-18 08:20:05 UTC (rev 3947) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-06-18 19:49:26 UTC (rev 3948) @@ -100,6 +100,17 @@ if(inliers[il]->x > right) right = inliers[il]->x; if(inliers[il]->y < bottom) bottom = inliers[il]->y; if(inliers[il]->y > top) top = inliers[il]->y; + + if(il == 0 )vigra::initImage(srcIterRange(tmp.upperLeft() + + vigra::Diff2D(inliers[il]->x-3, inliers[il]->y-3), + tmp.upperLeft() + vigra::Diff2D(inliers[il]->x+3, inliers[il]->y+3)), + RGB(255,0,0) ); + + if(il == 10 )vigra::initImage(srcIterRange(tmp.upperLeft() + + vigra::Diff2D(inliers[il]->x-3, inliers[il]->y-3), + tmp.upperLeft() + vigra::Diff2D(inliers[il]->x+3, inliers[il]->y+3)), + RGB(0,255,0) ); + vigra::initImage(srcIterRange(tmp.upperLeft() + vigra::Diff2D(inliers[il]->x, inliers[il]->y), tmp.upperLeft() + vigra::Diff2D(inliers[il]->x+1, inliers[il]->y+1)), @@ -132,14 +143,13 @@ } -void find_ann(vector<Point2D>& coords, unsigned int& good_lines){ +void find_ann(vector<Point2D>& coords, FVector2Image& edgeness, unsigned int& good_lines){ int k = 1; // Number of nearest neighbours - int dim = 2; // Dimensions + int dim = 3; // Dimensions double eps = 0.0; // Error bound - ANNpoint queryPt; // Query point queryPt = annAllocPt(dim,0); // Allocate query point srand(time(0)); @@ -147,9 +157,22 @@ queryPt[0] = coords[queryidx]->x; queryPt[1] = coords[queryidx]->y; + double orientation_scale = 1; + + // Add direction as 3rd dimension + double first_o; + if(dim > 2){ + TinyVector<float, 2> value = edgeness(queryPt[0],queryPt[1]); + queryPt[2] = value[1] * orientation_scale; + first_o = queryPt[2]; + } + int first_x = coords[queryidx]->x; int first_y = coords[queryidx]->y; + //if (verbose) cout << "Initial query:\t(" << first_x << "," << first_y << "," << first_o << + //")" << endl; + // Select query point, then remove from coords inliers.push_back(coords[queryidx]); coords.erase(coords.begin()+queryidx); @@ -195,6 +218,12 @@ for (unsigned int c = 0; c < nPts; c++){ dataPts[c][0] = close_neighbors[c]->x; dataPts[c][1] = close_neighbors[c]->y; + + // Add direction as 3rd dimension + if(dim > 2){ + TinyVector<float, 2> value = edgeness(dataPts[c][0],dataPts[c][1]); + dataPts[c][2] = value[1] * orientation_scale; + } } kdTree = new ANNkd_tree(dataPts,nPts,dim); @@ -204,28 +233,40 @@ double this_length = line_length_squared(first_x,first_y,close_neighbors[nnIdx[0]]->x,close_neighbors[nnIdx[0]]->y); if (this_length < previous_length){ - if(verbose) cout << "(" << queryPt[0] << "," << queryPt[1] << ")\t(" << close_neighbors[nnIdx[0]]->x << "," << close_neighbors[nnIdx[0]]->y << ")" << "\t" << nnIdx[0] << "\t" << dists[0] << endl; + if(verbose) cout << "(" << queryPt[0] << "," << queryPt[1] << "," << queryPt[2] << ")\t(" << close_neighbors[nnIdx[0]]->x << "," << close_neighbors[nnIdx[0]]->y << ")" << "\t" << nnIdx[0] << "\t" << dists[0] << endl; if(verbose) cout << "This point is closer to the inital query pixel than the previous one..." << endl; // Go back to the start point and go down the line in the reverse direction if (rev == 0){ if(verbose) cout << "End of line reached. Returning to inital query pixel..." << endl; + first_line_end_x = close_neighbors[nnIdx[0]]->x; first_line_end_y = close_neighbors[nnIdx[0]]->y; queryPt[0] = first_x; queryPt[1] = first_y; + + // Add direction as 3rd dimension + if(dim > 2) queryPt[2] = first_o; + previous_length = 0; rev = 1; }else{ + if(verbose) cout << "End of line reached." << endl; cont = 0; } }else{ - if(verbose) cout << "(" << queryPt[0] << "," << queryPt[1] << ")\t(" << close_neighbors[nnIdx[0]]->x << "," << close_neighbors[nnIdx[0]]->y << ")" << "\t" << nnIdx[0] << "\t" << dists[0] << endl; - + if(verbose) cout << "(" << queryPt[0] << "," << queryPt[1] << "," << queryPt[2] << ")\t(" << close_neighbors[nnIdx[0]]->x << "," << close_neighbors[nnIdx[0]]->y << ")" << "\t" << nnIdx[0] << "\t" << dists[0] << endl; + // Set query point to NN queryPt[0] = close_neighbors[nnIdx[0]]->x; queryPt[1] = close_neighbors[nnIdx[0]]->y; + // Add direction as 3rd dimension + if (dim > 2){ + TinyVector<float, 2> value = edgeness(queryPt[0],queryPt[1]); + queryPt[2] = value[1] * orientation_scale; + } + // Add NN to inliers inliers.push_back(close_neighbors[nnIdx[0]]); @@ -247,13 +288,18 @@ first_line_end_y = inliers[inliers.size()-1]->y; queryPt[0] = first_x; queryPt[1] = first_y; + + // Add direction as 3rd dimension + if(dim > 2) queryPt[2] = first_o; previous_length = 0; rev = 1; }else{ + if(verbose) cout << "No more pixels." << endl; cont = 0; } }else{ + if(verbose) cout << "No more pixels in this region." << endl; cont = 0; } } @@ -278,7 +324,7 @@ } -void extract_coords(BImage& image, int i){ +void extract_coords(BImage& image, FVector2Image& edgeness, int i){ vector<Point2D> coords; @@ -311,7 +357,7 @@ if(verbose) cout << "Searching for line " << good_lines+1 << ":" << endl; if(verbose) cout << "=====================" << endl << endl; - find_ann(coords,good_lines); + find_ann(coords, edgeness, good_lines); //ransac(coords); if(inliers.size())plot_inliers(image,good_lines); @@ -445,7 +491,7 @@ for (unsigned int w = 0; w < corners.width(); w++){ // Change this threshold to remove more corner pixels - if (corners(w,h) > 150){ + if (corners(w,h) > 200){ // Change the size of the box to draw around corner pixel int size = 3; @@ -492,7 +538,7 @@ } } -void detect_edge(BImage& image, FImage& corners, string& file, string& path, string& format){ +void detect_edge(BImage& image, FImage& corners, FVector2Image& edgeness, string& file, string& path, string& format){ try{ @@ -545,7 +591,7 @@ //sub_image(out); nuke_corners(out, corners, file); - extract_coords(out,1); + extract_coords(out, edgeness, 1); } @@ -639,6 +685,13 @@ tensorTrace(srcImageRange(boundarytensor), destImage(boundarystrength)); tensorToEdgeCorner(srcImageRange(boundarytensor), destImage(edgeness), destImage(cornerness)); + //for(int h = 0; h < nh; h++){ + // for(int w = 0; w < nw; w++){ + // TinyVector<float, 2> value = edgeness(w,h); + // cout << w << "," << h << ":\t" << value[0] << " " << value[1] << endl; + // } + //} + string output = path; output.append("boundarystrength.jpg"); exportImage(srcImageRange(boundarystrength), ImageExportInfo(output.c_str()).setPixelType("UINT8")); @@ -646,6 +699,6 @@ output.append("cornerstrength.jpg"); exportImage(srcImageRange(cornerness), ImageExportInfo(output.c_str()).setPixelType("UINT8")); - detect_edge(grey, cornerness, filename, path, format); + detect_edge(grey, cornerness, edgeness, filename, path, format); } Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h 2009-06-18 08:20:05 UTC (rev 3947) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.h 2009-06-18 19:49:26 UTC (rev 3948) @@ -8,12 +8,12 @@ bool compare_xy (const vigra::Point2D,const vigra::Point2D); bool compare_yx (const vigra::Point2D,const vigra::Point2D); //void ransac(std::vector<vigra::Point2D>&); -void find_ann(std::vector<vigra::Point2D>&, unsigned int&); +void find_ann(std::vector<vigra::Point2D>&, vigra::FVector2Image&, unsigned int&); void plot_inliers(vigra::BImage& image, int); -void extract_coords(vigra::BImage&, int); +void extract_coords(vigra::BImage&, vigra::FVector2Image&, int); void nuke_corners(vigra::BImage&, vigra::FImage&, std::string&); //void sub_image(vigra::BImage& image); -void detect_edge(vigra::BImage&, std::string&, std::string&, std::string&); +void detect_edge(vigra::BImage&, vigra::FImage&, vigra::FVector2Image&, std::string&, std::string&, std::string&); void process_image(std::string&); #endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bl...@us...> - 2009-06-23 17:22:54
|
Revision: 3961 http://hugin.svn.sourceforge.net/hugin/?rev=3961&view=rev Author: blimbo Date: 2009-06-23 17:22:53 +0000 (Tue, 23 Jun 2009) Log Message: ----------- Added hourglass filter, rho and sigma can be adjusted Modified Paths: -------------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp 2009-06-23 16:02:01 UTC (rev 3960) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp 2009-06-23 17:22:53 UTC (rev 3961) @@ -40,3 +40,5 @@ unsigned int generate_images = 1; std::vector<vigra::Point2D> inliers; std::vector<std::vector<vigra::Point2D> > lines; +double sigma = 1.4; +double rho = 0.4; Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h 2009-06-23 16:02:01 UTC (rev 3960) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.h 2009-06-23 17:22:53 UTC (rev 3961) @@ -23,6 +23,7 @@ extern unsigned int generate_images; extern std::vector<vigra::Point2D> inliers; extern std::vector<std::vector<vigra::Point2D> > lines; - +extern double sigma; +extern double rho; #endif Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp 2009-06-23 16:02:01 UTC (rev 3960) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp 2009-06-23 17:22:53 UTC (rev 3961) @@ -305,7 +305,9 @@ cout << " -t <float> Edge detector threshold. Default 8" << endl; cout << " -b <float> Boundary tensor scale. Default 2" << endl; cout << " -g <int> Gap in pixels permitted within a line. Default 3" << endl; - cout << " -l <float> Minimum line length as a fraction of longest dimension. Default 0.2" << endl; + cout << " -l <float> Minimum line length as a fraction of longest dimension. Default 0.2" << endl; + cout << " -m <float> Sigma parameter for hourglass filter. Default 1.4" << endl; + cout << " -r <float> Rho parameter for hourglass filter. Default 0.4" << endl; cout << " -i <0|1> Generate intermediate images. Default 1" << endl; cout << " -v <0|1> Verbose. Default 0" << endl; cout << " -h Print usage." << endl; @@ -354,7 +356,9 @@ case 'b' : {tscale = atof(argv[i]); break;} case 't' : {threshold = atof(argv[i]); break;} case 'l' : {length_threshold = atof(argv[i]); break;} - case 'i' : {generate_images = atoi(argv[i]); break;} + case 'i' : {generate_images = atoi(argv[i]); break;} + case 'm' : {sigma = atof(argv[i]); break;} + case 'r' : {rho = atof(argv[i]); break;} } Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-06-23 16:02:01 UTC (rev 3960) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-06-23 17:22:53 UTC (rev 3961) @@ -526,8 +526,47 @@ } } } + + // Smooth with hourglass filter + //cout << "Applying hourglass filter..." << endl; + + FVector2Image gradient(image.width(),image.height()); + FVector3Image tensor(image.width(),image.height()), smoothedTensor(image.width(),image.height()); + + gaussianGradient(srcImageRange(image), destImage(gradient), 1.0); + + /* + if (generate_images){ + + string output = path; + output.append("gaussiangradient.tif"); + exportImage(srcImageRange(gradient), ImageExportInfo(output.c_str()).setPixelType("UINT16")); + + } + */ + + vectorToTensor(srcImageRange(gradient), destImage(tensor)); + hourGlassFilter(srcImageRange(tensor), destImage(smoothedTensor), sigma, rho); + if (generate_images){ + string output = path; + output.append("hourglass_sigma_"); + stringstream dt; + dt << sigma; + output.append(dt.str()); + output.append("_rho_"); + stringstream ds; + ds << rho; + output.append(ds.str()); + output.append(format); + cout << "Writing " << output << endl; + exportImage(srcImageRange(smoothedTensor), ImageExportInfo(output.c_str()).setPixelType("UINT8")); + + } + + if (generate_images){ + // Create output file name string output = path; //if (file.substr(file.length()-4,1) == (".")){ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bl...@us...> - 2009-06-25 15:12:11
|
Revision: 3965 http://hugin.svn.sourceforge.net/hugin/?rev=3965&view=rev Author: blimbo Date: 2009-06-25 15:11:55 +0000 (Thu, 25 Jun 2009) Log Message: ----------- Added annDeallocPts() so now seems to work ok without resizing image. Corner detection uses edge detect output Modified Paths: -------------- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp 2009-06-24 21:00:46 UTC (rev 3964) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Globals.cpp 2009-06-25 15:11:55 UTC (rev 3965) @@ -33,7 +33,7 @@ double length_threshold = 0.2; double min_line_length_squared; double scale = 2; -double tscale = 1; +double tscale = 1.45; unsigned int gap_limit = 3; unsigned int vertical_slices = 12; unsigned int horizontal_slices = 8; Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp 2009-06-24 21:00:46 UTC (rev 3964) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/Main.cpp 2009-06-25 15:11:55 UTC (rev 3965) @@ -303,7 +303,7 @@ cout << " -o <path> Output path. Default output/" << endl; cout << " -s <float> Edge detector scale. Default 2" << endl; cout << " -t <float> Edge detector threshold. Default 8" << endl; - cout << " -b <float> Boundary tensor scale. Default 2" << endl; + cout << " -b <float> Boundary tensor scale. Default 1.45" << endl; cout << " -g <int> Gap in pixels permitted within a line. Default 3" << endl; cout << " -l <float> Minimum line length as a fraction of longest dimension. Default 0.2" << endl; cout << " -m <float> Sigma parameter for hourglass filter. Default 1.4" << endl; Modified: hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp =================================================================== --- hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-06-24 21:00:46 UTC (rev 3964) +++ hugin/branches/gsoc2009_lenscalibration/src/lens_calibrate/ProcessImage.cpp 2009-06-25 15:11:55 UTC (rev 3965) @@ -229,6 +229,7 @@ } } + //kdTree = new ANNkd_tree(dataPts,nPts,2); kdTree = new ANNkd_tree(dataPts,nPts,dim); kdTree->annkSearch(queryPt,k,nnIdx,dists,eps); @@ -254,8 +255,13 @@ previous_length = 0; rev = 1; }else{ - if(verbose) cout << "End of line reached." << endl; - cont = 0; + + // Erase it from coords so we don't see it again + coords.erase(coords.begin()+coords_index[nnIdx[0]]); + + + //if(verbose) cout << "End of line reached." << endl; + //cont = 0; } }else{ if(verbose) cout << "(" << queryPt[0] << "," << queryPt[1] << "," << queryPt[2] << ")\t(" << close_neighbors[nnIdx[0]]->x << "," << close_neighbors[nnIdx[0]]->y << ")" << "\t" << nnIdx[0] << "\t" << dists[0] << endl; @@ -305,11 +311,11 @@ if(verbose) cout << "No more pixels in this region." << endl; cont = 0; } - } - - annClose(); - } - + } + annDeallocPts(dataPts); + } + //annDeallocPt(queryPt); + annClose(); double length = line_length_squared(first_line_end_x, first_line_end_y,inliers[inliers.size()-1]->x,inliers[inliers.size()-1]->y); @@ -526,28 +532,16 @@ } } } + + + /* // Smooth with hourglass filter - //cout << "Applying hourglass filter..." << endl; - FVector2Image gradient(image.width(),image.height()); FVector3Image tensor(image.width(),image.height()), smoothedTensor(image.width(),image.height()); - gaussianGradient(srcImageRange(image), destImage(gradient), 1.0); - - /* - if (generate_images){ - - string output = path; - output.append("gaussiangradient.tif"); - exportImage(srcImageRange(gradient), ImageExportInfo(output.c_str()).setPixelType("UINT16")); - - } - */ - vectorToTensor(srcImageRange(gradient), destImage(tensor)); hourGlassFilter(srcImageRange(tensor), destImage(smoothedTensor), sigma, rho); - if (generate_images){ string output = path; @@ -561,9 +555,9 @@ output.append(ds.str()); output.append(format); cout << "Writing " << output << endl; - exportImage(srcImageRange(smoothedTensor), ImageExportInfo(output.c_str()).setPixelType("UINT8")); - + exportImage(srcImageRange(smoothedTensor), ImageExportInfo(output.c_str()).setPixelType("UINT8")); } + */ if (generate_images){ @@ -631,10 +625,30 @@ exportImage(srcImageRange(out), output.c_str()); } - // Slice image - //sub_image(out); + + // Get cornerness from edge detection output + // Create image of appropriate size for boundary tensor + FVector3Image boundarytensor(image.width(), image.height()); + + // Calculate the boundary tensor + cout << "Calculating boundary tensor..." << endl; + boundaryTensor(srcImageRange(out), destImage(boundarytensor), tscale); + + FImage boundarystrength(image.width(), image.height()), cornerness(image.width(), image.height()); + FVector2Image edgeness(image.width(), image.height()); + + tensorTrace(srcImageRange(boundarytensor), destImage(boundarystrength)); + tensorToEdgeCorner(srcImageRange(boundarytensor), destImage(edgeness), destImage(cornerness)); + + + + + + + + //nuke_corners(out, corners, file); - nuke_corners(out, corners, file); + nuke_corners(out, cornerness, file); extract_coords(out, edgeness, 1); } @@ -720,7 +734,7 @@ FVector3Image boundarytensor(nw, nh); // Calculate the boundary tensor - cout << "Calculating boundary tensor..." << endl; + //cout << "Calculating boundary tensor using original image..." << endl; boundaryTensor(srcImageRange(grey), destImage(boundarytensor), tscale); FImage boundarystrength(nw, nh), cornerness(nw, nh); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |