|
[Hugin-cvs] /hgroot/hugin/hugin: Linefind: Also load and process
grayscale i...
From: <hugin-cvs@li...> - 2012-11-14 19:10
|
branch: details: http://hugin.hg.sourceforge.net/hgweb/hugin/hugin/hgroot/hugin/hugin/rev/f6f26d87a9b5 changeset: 6031:f6f26d87a9b5 user: tmodes date: Wed Nov 14 20:09:56 2012 +0100 description: Linefind: Also load and process grayscale images correctly diffstat: src/hugin_base/lines/FindLines.cpp | 33 +++++- src/hugin_base/lines/FindLines.h | 2 + src/tools/linefind.cpp | 206 ++++++++++++++++++++++++++++-------- 3 files changed, 190 insertions(+), 51 deletions(-) diffs (358 lines): diff -r d9792f1308da -r f6f26d87a9b5 src/hugin_base/lines/FindLines.cpp --- a/src/hugin_base/lines/FindLines.cpp Wed Nov 14 20:09:09 2012 +0100 +++ b/src/hugin_base/lines/FindLines.cpp Wed Nov 14 20:09:56 2012 +0100 @@ -39,7 +39,8 @@ namespace HuginLines { -double resize_image(UInt8RGBImage& in, UInt8RGBImage& out, int resize_dimension) +template <class ImageType> +double resize_image(ImageType& in, ImageType& out, int resize_dimension) { // Re-size to max dimension double sizefactor=1.0; @@ -92,6 +93,19 @@ return image; }; +vigra::BImage* detectEdges(BImage input,double scale,double threshold,unsigned int resize_dimension, double& size_factor) +{ + // Resize image + UInt8Image scaled; + size_factor=resize_image(input, scaled, resize_dimension); + input.resize(0,0); + + // Run Canny edge detector + BImage* image=new BImage(scaled.width(), scaled.height(), 255); + cannyEdgeImage(srcImageRange(scaled), destImage(*image), scale, threshold, 0); + return image; +}; + double calculate_focal_length_pixels(double focal_length,double cropFactor,double width, double height) { double pixels_per_mm = 0; @@ -238,7 +252,8 @@ return cp1.error<cp2.error; }; -HuginBase::CPVector GetVerticalLines(const HuginBase::Panorama& pano,const unsigned int imgNr,vigra::UInt8RGBImage& image, const unsigned int nrLines) +template <class ImageType> +HuginBase::CPVector _getVerticalLines(const HuginBase::Panorama& pano,const unsigned int imgNr,ImageType& image, const unsigned int nrLines) { HuginBase::CPVector verticalLines; HuginBase::CPVector detectedLines; @@ -285,11 +300,11 @@ tempPano.setOptions(opts); //finally remap image - HuginBase::Nona::RemappedPanoImage<vigra::UInt8RGBImage,vigra::BImage>* remapped=new HuginBase::Nona::RemappedPanoImage<vigra::UInt8RGBImage,vigra::BImage>; + HuginBase::Nona::RemappedPanoImage<ImageType,vigra::BImage>* remapped=new HuginBase::Nona::RemappedPanoImage<ImageType,vigra::BImage>; AppBase::MultiProgressDisplay* progress=new AppBase::DummyMultiProgressDisplay(); remapped->setPanoImage(remappedImage,opts,opts.getROI()); remapped->remapImage(vigra::srcImageRange(image),vigra_ext::INTERP_CUBIC,*progress); - vigra::UInt8RGBImage remappedBitmap=remapped->m_image; + ImageType remappedBitmap=remapped->m_image; //detect edges edge=detectEdges(remappedBitmap,2,4,std::max(remappedBitmap.width(),remappedBitmap.height())+10,size_factor); delete remapped; @@ -443,4 +458,14 @@ return verticalLines; }; +HuginBase::CPVector GetVerticalLines(const HuginBase::Panorama& pano,const unsigned int imgNr,vigra::UInt8RGBImage& image, const unsigned int nrLines) +{ + return _getVerticalLines(pano, imgNr, image, nrLines); +}; + +HuginBase::CPVector GetVerticalLines(const HuginBase::Panorama& pano,const unsigned int imgNr,vigra::BImage& image, const unsigned int nrLines) +{ + return _getVerticalLines(pano, imgNr, image, nrLines); +}; + }; //namespace \ No newline at end of file diff -r d9792f1308da -r f6f26d87a9b5 src/hugin_base/lines/FindLines.h --- a/src/hugin_base/lines/FindLines.h Wed Nov 14 20:09:09 2012 +0100 +++ b/src/hugin_base/lines/FindLines.h Wed Nov 14 20:09:56 2012 +0100 @@ -44,6 +44,7 @@ * @return image with the marked edges */ LINESIMPEX vigra::BImage* detectEdges(vigra::UInt8RGBImage input,double scale,double threshold,unsigned int resize_dimension, double &size_factor); + LINESIMPEX vigra::BImage* detectEdges(vigra::BImage input,double scale,double threshold,unsigned int resize_dimension, double &size_factor); /** @brief find straightish non-crossing lines * find straightish non-crossing lines in an edge map * using 8-neighborhood operations. (Points on the edges @@ -76,5 +77,6 @@ * @return HuginBase::CPVector with all vertical control points */ LINESIMPEX HuginBase::CPVector GetVerticalLines(const HuginBase::Panorama& pano,const unsigned int imgNr,vigra::UInt8RGBImage& image,const unsigned int nrLines); + LINESIMPEX HuginBase::CPVector GetVerticalLines(const HuginBase::Panorama& pano,const unsigned int imgNr,vigra::BImage& image,const unsigned int nrLines); }; #endif diff -r d9792f1308da -r f6f26d87a9b5 src/tools/linefind.cpp --- a/src/tools/linefind.cpp Wed Nov 14 20:09:09 2012 +0100 +++ b/src/tools/linefind.cpp Wed Nov 14 20:09:56 2012 +0100 @@ -77,12 +77,13 @@ return 1; } -/** converts the given image to UInt16RGBImage - * only this image is correctly processed by celeste +/** converts the given image to UInt8RGBImage + * only this image is correctly processed by linefind * @param src input image * @param origType pixel type of input image * @param dest converted image */ +// 2 versions: one for color images, the other for gray images template <class SrcIMG> void convertToUInt8(SrcIMG & src, const std::string & origType, vigra::UInt8RGBImage & dest) { @@ -109,11 +110,76 @@ }; } -vigra::UInt8RGBImage loadAndConvertImage(string imagefile) +template <class SrcIMG> +void convertGrayToUInt8(SrcIMG & src, const std::string & origType, vigra::BImage & dest) { - vigra::ImageImportInfo info(imagefile.c_str()); + dest.resize(src.size()); + long newMax=vigra_ext::getMaxValForPixelType("UINT8"); + // float needs to be from min ... max. + if (origType == "FLOAT" || origType == "DOUBLE") + { + /** @TODO this convert routine scale the input values range into the full scale of UInt16 + * this is not fully correct + */ + vigra::FindMinMax<float> minmax; // init functor + vigra::inspectImage(srcImageRange(src), minmax); + double minVal = minmax.min; + double maxVal = minmax.max; + vigra_ext::applyMapping(srcImageRange(src), destImage(dest), minVal, maxVal, 0); + } + else + { + vigra::transformImage(srcImageRange(src), destImage(dest), + vigra::functor::Arg1()*vigra::functor::Param( newMax/ vigra_ext::getMaxValForPixelType(origType))); + }; +} + +template <class SrcIMG> +vigra::BImage LoadGrayImageAndConvert(vigra::ImageImportInfo & info) +{ + vigra::BImage image; + SrcIMG imageIn(info.width(),info.height()); + if(info.numExtraBands()==1) + { + vigra::BImage mask(info.size()); + vigra::importImageAlpha(info,destImage(imageIn),destImage(mask)); + mask.resize(0,0); + } + else + { + importImage(info,destImage(imageIn)); + }; + convertGrayToUInt8(imageIn,info.getPixelType(),image); + imageIn.resize(0,0); + return image; +}; + +template <class SrcIMG> +vigra::UInt8RGBImage LoadImageAndConvert(vigra::ImageImportInfo & info) +{ + vigra::UInt8RGBImage image; + SrcIMG imageIn(info.width(),info.height()); + if(info.numExtraBands()==1) + { + vigra::BImage mask(info.size()); + vigra::importImageAlpha(info,destImage(imageIn),destImage(mask)); + mask.resize(0,0); + } + else + { + importImage(info,destImage(imageIn)); + }; + convertToUInt8(imageIn,info.getPixelType(),image); + imageIn.resize(0,0); + return image; +}; + +// loads the gray images and finds vertical lines, returns a CPVector with found vertical lines +HuginBase::CPVector LoadGrayImageAndFindLines(vigra::ImageImportInfo info, Panorama & pano, size_t imgNr, int nrLines) +{ + vigra::BImage image; + HuginBase::CPVector lineCp; std::string pixelType=info.getPixelType(); - vigra::UInt8RGBImage image; if(pixelType=="UINT8") { image.resize(info.width(),info.height()); @@ -132,55 +198,19 @@ { if(pixelType=="UINT16" || pixelType=="INT16") { - vigra::UInt16RGBImage imageIn(info.width(),info.height()); - if(info.numExtraBands()==1) - { - vigra::BImage mask(info.size()); - vigra::importImageAlpha(info,destImage(imageIn),destImage(mask)); - mask.resize(0,0); - } - else - { - importImage(info,destImage(imageIn)); - }; - convertToUInt8(imageIn,pixelType,image); - imageIn.resize(0,0); + image=LoadGrayImageAndConvert<vigra::UInt16Image>(info); } else { if(pixelType=="INT32" || pixelType=="UINT32") { - vigra::UInt32RGBImage imageIn(info.width(),info.height()); - if(info.numExtraBands()==1) - { - vigra::BImage mask(info.size()); - vigra::importImageAlpha(info,destImage(imageIn),destImage(mask)); - mask.resize(0,0); - } - else - { - importImage(info,destImage(imageIn)); - }; - convertToUInt8(imageIn,pixelType,image); - imageIn.resize(0,0); + image=LoadGrayImageAndConvert<vigra::UInt32Image>(info); } else { if(pixelType=="FLOAT" || pixelType=="DOUBLE") { - vigra::FRGBImage imagefloat(info.width(),info.height()); - if(info.numExtraBands()==1) - { - vigra::BImage mask(info.size()); - vigra::importImageAlpha(info,destImage(imagefloat),destImage(mask)); - mask.resize(0,0); - } - else - { - importImage(info,destImage(imagefloat)); - }; - convertToUInt8(imagefloat,pixelType,image); - imagefloat.resize(0,0); + image=LoadGrayImageAndConvert<vigra::FImage>(info); } else { @@ -189,7 +219,63 @@ }; }; }; - return image; + if(image.width()>0 && image.height()>0) + { + lineCp=HuginLines::GetVerticalLines(pano, imgNr, image, nrLines); + }; + return lineCp; +}; + +// loads the color images and finds vertical lines, returns a CPVector with found vertical lines +HuginBase::CPVector LoadImageAndFindLines(vigra::ImageImportInfo info, Panorama & pano, size_t imgNr, int nrLines) +{ + vigra::UInt8RGBImage image; + HuginBase::CPVector lineCp; + std::string pixelType=info.getPixelType(); + if(pixelType=="UINT8") + { + image.resize(info.width(),info.height()); + if(info.numExtraBands()==1) + { + vigra::BImage mask(info.size()); + vigra::importImageAlpha(info,destImage(image),destImage(mask)); + mask.resize(0,0); + } + else + { + importImage(info,destImage(image)); + }; + } + else + { + if(pixelType=="UINT16" || pixelType=="INT16") + { + image=LoadImageAndConvert<vigra::UInt16RGBImage>(info); + } + else + { + if(pixelType=="INT32" || pixelType=="UINT32") + { + image=LoadImageAndConvert<vigra::UInt32RGBImage>(info); + } + else + { + if(pixelType=="FLOAT" || pixelType=="DOUBLE") + { + image=LoadImageAndConvert<vigra::FRGBImage>(info); + } + else + { + std::cerr << "Unsupported pixel type" << std::endl; + }; + }; + }; + }; + if(image.width()>0 && image.height()>0) + { + lineCp=HuginLines::GetVerticalLines(pano, imgNr, image, nrLines); + }; + return lineCp; }; int main(int argc, char* argv[]) @@ -314,6 +400,12 @@ PT_setInfoDlgFcn(ptinfoDlg); cout << argv[0] << " is searching for vertical lines" << endl; +#if _WINDOWS + //multi threading of image loading results sometime in a race condition + //try to prevent this by initialisation of codecManager before + //running multi threading part + std::string s=vigra::impexListExtensions(); +#endif #ifdef HAS_PPL size_t nrCPS=pano.getNrOfCtrlPoints(); Concurrency::parallel_for<size_t>(0,imagesToProcess.size(),[&pano,imagesToProcess,nrLines](size_t i) @@ -323,8 +415,28 @@ { unsigned int imgNr=imagesToProcess[i]; cout << "Working on image " << pano.getImage(imgNr).getFilename() << endl; - vigra::UInt8RGBImage image=loadAndConvertImage(pano.getImage(imgNr).getFilename().c_str()); - CPVector foundLines=HuginLines::GetVerticalLines(pano,imgNr,image,nrLines); + // now load and process all images + vigra::ImageImportInfo info(pano.getImage(imgNr).getFilename().c_str()); + HuginBase::CPVector foundLines; + if(info.isGrayscale()) + { + foundLines=LoadGrayImageAndFindLines(info, pano, imgNr, nrLines); + } + else + { + if(info.isColor()) + { + //colour images + foundLines=LoadImageAndFindLines(info, pano, imgNr, nrLines); + } + else + { + std::cerr << "Image " << pano.getImage(imgNr).getFilename().c_str() << " has " + << info.numBands() << " channels." << std::endl + << "Linefind works only with grayscale or color images." << std::endl + << "Skipping image." << std::endl; + }; + }; #ifndef HAS_PPL cout << "Found " << foundLines.size() << " vertical lines" << endl; #endif |
| Thread | Author | Date |
|---|---|---|
| [Hugin-cvs] /hgroot/hugin/hugin: Linefind: Also load and process grayscale i... | <hugin-cvs@li...> |