Commit 8654f76c authored by Alexander Alekhin's avatar Alexander Alekhin

Merge pull request #1869 from alalek:move_shape_contrib

parents 299bbcc8 0b91ecce
set(the_description "Shape descriptors and matchers")
ocv_define_module(shape opencv_core opencv_imgproc opencv_calib3d WRAP python)
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009-2012, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef OPENCV_SHAPE_HPP
#define OPENCV_SHAPE_HPP
#include "opencv2/shape/emdL1.hpp"
#include "opencv2/shape/shape_transformer.hpp"
#include "opencv2/shape/hist_cost.hpp"
#include "opencv2/shape/shape_distance.hpp"
/**
@defgroup shape Shape Distance and Matching
*/
#endif
/* End of file. */
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009-2012, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef OPENCV_EMD_L1_HPP
#define OPENCV_EMD_L1_HPP
#include "opencv2/core.hpp"
namespace cv
{
/****************************************************************************************\
* EMDL1 Function *
\****************************************************************************************/
//! @addtogroup shape
//! @{
/** @brief Computes the "minimal work" distance between two weighted point configurations base on the papers
"EMD-L1: An efficient and Robust Algorithm for comparing histogram-based descriptors", by Haibin
Ling and Kazunori Okuda; and "The Earth Mover's Distance is the Mallows Distance: Some Insights from
Statistics", by Elizaveta Levina and Peter Bickel.
@param signature1 First signature, a single column floating-point matrix. Each row is the value of
the histogram in each bin.
@param signature2 Second signature of the same format and size as signature1.
*/
CV_EXPORTS float EMDL1(InputArray signature1, InputArray signature2);
//! @}
}//namespace cv
#endif
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef OPENCV_HIST_COST_HPP
#define OPENCV_HIST_COST_HPP
#include "opencv2/imgproc.hpp"
namespace cv
{
//! @addtogroup shape
//! @{
/** @brief Abstract base class for histogram cost algorithms.
*/
class CV_EXPORTS_W HistogramCostExtractor : public Algorithm
{
public:
CV_WRAP virtual void buildCostMatrix(InputArray descriptors1, InputArray descriptors2, OutputArray costMatrix) = 0;
CV_WRAP virtual void setNDummies(int nDummies) = 0;
CV_WRAP virtual int getNDummies() const = 0;
CV_WRAP virtual void setDefaultCost(float defaultCost) = 0;
CV_WRAP virtual float getDefaultCost() const = 0;
};
/** @brief A norm based cost extraction. :
*/
class CV_EXPORTS_W NormHistogramCostExtractor : public HistogramCostExtractor
{
public:
CV_WRAP virtual void setNormFlag(int flag) = 0;
CV_WRAP virtual int getNormFlag() const = 0;
};
CV_EXPORTS_W Ptr<HistogramCostExtractor>
createNormHistogramCostExtractor(int flag=DIST_L2, int nDummies=25, float defaultCost=0.2f);
/** @brief An EMD based cost extraction. :
*/
class CV_EXPORTS_W EMDHistogramCostExtractor : public HistogramCostExtractor
{
public:
CV_WRAP virtual void setNormFlag(int flag) = 0;
CV_WRAP virtual int getNormFlag() const = 0;
};
CV_EXPORTS_W Ptr<HistogramCostExtractor>
createEMDHistogramCostExtractor(int flag=DIST_L2, int nDummies=25, float defaultCost=0.2f);
/** @brief An Chi based cost extraction. :
*/
class CV_EXPORTS_W ChiHistogramCostExtractor : public HistogramCostExtractor
{};
CV_EXPORTS_W Ptr<HistogramCostExtractor> createChiHistogramCostExtractor(int nDummies=25, float defaultCost=0.2f);
/** @brief An EMD-L1 based cost extraction. :
*/
class CV_EXPORTS_W EMDL1HistogramCostExtractor : public HistogramCostExtractor
{};
CV_EXPORTS_W Ptr<HistogramCostExtractor>
createEMDL1HistogramCostExtractor(int nDummies=25, float defaultCost=0.2f);
//! @}
} // cv
#endif
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifdef __OPENCV_BUILD
#error this is a compatibility header which should not be used inside the OpenCV library
#endif
#include "opencv2/shape.hpp"
This diff is collapsed.
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef OPENCV_SHAPE_SHAPE_TRANSFORM_HPP
#define OPENCV_SHAPE_SHAPE_TRANSFORM_HPP
#include <vector>
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
namespace cv
{
//! @addtogroup shape
//! @{
/** @brief Abstract base class for shape transformation algorithms.
*/
class CV_EXPORTS_W ShapeTransformer : public Algorithm
{
public:
/** @brief Estimate the transformation parameters of the current transformer algorithm, based on point matches.
@param transformingShape Contour defining first shape.
@param targetShape Contour defining second shape (Target).
@param matches Standard vector of Matches between points.
*/
CV_WRAP virtual void estimateTransformation(InputArray transformingShape, InputArray targetShape,
std::vector<DMatch>& matches) = 0;
/** @brief Apply a transformation, given a pre-estimated transformation parameters.
@param input Contour (set of points) to apply the transformation.
@param output Output contour.
*/
CV_WRAP virtual float applyTransformation(InputArray input, OutputArray output=noArray()) = 0;
/** @brief Apply a transformation, given a pre-estimated transformation parameters, to an Image.
@param transformingImage Input image.
@param output Output image.
@param flags Image interpolation method.
@param borderMode border style.
@param borderValue border value.
*/
CV_WRAP virtual void warpImage(InputArray transformingImage, OutputArray output,
int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT,
const Scalar& borderValue=Scalar()) const = 0;
};
/***********************************************************************************/
/***********************************************************************************/
/** @brief Definition of the transformation
occupied in the paper "Principal Warps: Thin-Plate Splines and Decomposition of Deformations", by
F.L. Bookstein (PAMI 1989). :
*/
class CV_EXPORTS_W ThinPlateSplineShapeTransformer : public ShapeTransformer
{
public:
/** @brief Set the regularization parameter for relaxing the exact interpolation requirements of the TPS
algorithm.
@param beta value of the regularization parameter.
*/
CV_WRAP virtual void setRegularizationParameter(double beta) = 0;
CV_WRAP virtual double getRegularizationParameter() const = 0;
};
/** Complete constructor */
CV_EXPORTS_W Ptr<ThinPlateSplineShapeTransformer>
createThinPlateSplineShapeTransformer(double regularizationParameter=0);
/***********************************************************************************/
/***********************************************************************************/
/** @brief Wrapper class for the OpenCV Affine Transformation algorithm. :
*/
class CV_EXPORTS_W AffineTransformer : public ShapeTransformer
{
public:
CV_WRAP virtual void setFullAffine(bool fullAffine) = 0;
CV_WRAP virtual bool getFullAffine() const = 0;
};
/** Complete constructor */
CV_EXPORTS_W Ptr<AffineTransformer> createAffineTransformer(bool fullAffine);
//! @}
} // cv
#endif
/*
* shape_context.cpp -- Shape context demo for shape matching
*/
#include "opencv2/shape.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <opencv2/core/utility.hpp>
#include <iostream>
#include <string>
using namespace std;
using namespace cv;
static void help()
{
printf("\n"
"This program demonstrates a method for shape comparison based on Shape Context\n"
"You should run the program providing a number between 1 and 20 for selecting an image in the folder ../data/shape_sample.\n"
"Call\n"
"./shape_example [number between 1 and 20, 1 default]\n\n");
}
static vector<Point> simpleContour( const Mat& currentQuery, int n=300 )
{
vector<vector<Point> > _contoursQuery;
vector <Point> contoursQuery;
findContours(currentQuery, _contoursQuery, RETR_LIST, CHAIN_APPROX_NONE);
for (size_t border=0; border<_contoursQuery.size(); border++)
{
for (size_t p=0; p<_contoursQuery[border].size(); p++)
{
contoursQuery.push_back( _contoursQuery[border][p] );
}
}
// In case actual number of points is less than n
int dummy=0;
for (int add=(int)contoursQuery.size()-1; add<n; add++)
{
contoursQuery.push_back(contoursQuery[dummy++]); //adding dummy values
}
// Uniformly sampling
cv::randShuffle(contoursQuery);
vector<Point> cont;
for (int i=0; i<n; i++)
{
cont.push_back(contoursQuery[i]);
}
return cont;
}
int main(int argc, char** argv)
{
string path = "data/shape_sample/";
cv::CommandLineParser parser(argc, argv, "{help h||}{@input|1|}");
if (parser.has("help"))
{
help();
return 0;
}
int indexQuery = parser.get<int>("@input");
if (!parser.check())
{
parser.printErrors();
help();
return 1;
}
if (indexQuery < 1 || indexQuery > 20)
{
help();
return 1;
}
cv::Ptr <cv::ShapeContextDistanceExtractor> mysc = cv::createShapeContextDistanceExtractor();
Size sz2Sh(300,300);
stringstream queryName;
queryName<<path<<indexQuery<<".png";
Mat query=imread(queryName.str(), IMREAD_GRAYSCALE);
Mat queryToShow;
resize(query, queryToShow, sz2Sh, 0, 0, INTER_LINEAR_EXACT);
imshow("QUERY", queryToShow);
moveWindow("TEST", 0,0);
vector<Point> contQuery = simpleContour(query);
int bestMatch = 0;
float bestDis=FLT_MAX;
for ( int ii=1; ii<=20; ii++ )
{
if (ii==indexQuery) continue;
waitKey(30);
stringstream iiname;
iiname<<path<<ii<<".png";
cout<<"name: "<<iiname.str()<<endl;
Mat iiIm=imread(iiname.str(), 0);
Mat iiToShow;
resize(iiIm, iiToShow, sz2Sh, 0, 0, INTER_LINEAR_EXACT);
imshow("TEST", iiToShow);
moveWindow("TEST", sz2Sh.width+50,0);
vector<Point> contii = simpleContour(iiIm);
float dis = mysc->computeDistance( contQuery, contii );
if ( dis<bestDis )
{
bestMatch = ii;
bestDis = dis;
}
std::cout<<" distance between "<<queryName.str()<<" and "<<iiname.str()<<" is: "<<dis<<std::endl;
}
destroyWindow("TEST");
stringstream bestname;
bestname<<path<<bestMatch<<".png";
Mat iiIm=imread(bestname.str(), 0);
Mat bestToShow;
resize(iiIm, bestToShow, sz2Sh, 0, 0, INTER_LINEAR_EXACT);
imshow("BEST MATCH", bestToShow);
moveWindow("BEST MATCH", sz2Sh.width+50,0);
waitKey();
return 0;
}
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "precomp.hpp"
namespace cv
{
class AffineTransformerImpl : public AffineTransformer
{
public:
/* Constructors */
AffineTransformerImpl()
{
fullAffine = true;
name_ = "ShapeTransformer.AFF";
transformCost = 0;
}
AffineTransformerImpl(bool _fullAffine)
{
fullAffine = _fullAffine;
name_ = "ShapeTransformer.AFF";
transformCost = 0;
}
/* Destructor */
~AffineTransformerImpl()
{
}
//! the main operator
virtual void estimateTransformation(InputArray transformingShape, InputArray targetShape, std::vector<DMatch> &matches) CV_OVERRIDE;
virtual float applyTransformation(InputArray input, OutputArray output=noArray()) CV_OVERRIDE;
virtual void warpImage(InputArray transformingImage, OutputArray output,
int flags, int borderMode, const Scalar& borderValue) const CV_OVERRIDE;
//! Setters/Getters
virtual void setFullAffine(bool _fullAffine) CV_OVERRIDE {fullAffine=_fullAffine;}
virtual bool getFullAffine() const CV_OVERRIDE {return fullAffine;}
//! write/read
virtual void write(FileStorage& fs) const CV_OVERRIDE
{
writeFormat(fs);
fs << "name" << name_
<< "affine_type" << int(fullAffine);
}
virtual void read(const FileNode& fn) CV_OVERRIDE
{
CV_Assert( (String)fn["name"] == name_ );
fullAffine = int(fn["affine_type"])?true:false;
}
private:
bool fullAffine;
Mat affineMat;
float transformCost;
protected:
String name_;
};
void AffineTransformerImpl::warpImage(InputArray transformingImage, OutputArray output,
int flags, int borderMode, const Scalar& borderValue) const
{
CV_INSTRUMENT_REGION();
CV_Assert(!affineMat.empty());
warpAffine(transformingImage, output, affineMat, transformingImage.getMat().size(), flags, borderMode, borderValue);
}
static Mat _localAffineEstimate(const std::vector<Point2f>& shape1, const std::vector<Point2f>& shape2,
bool fullAfine)
{
Mat out(2,3,CV_32F);
int siz=2*(int)shape1.size();
if (fullAfine)
{
Mat matM(siz, 6, CV_32F);
Mat matP(siz,1,CV_32F);
int contPt=0;
for (int ii=0; ii<siz; ii++)
{
Mat therow = Mat::zeros(1,6,CV_32F);
if (ii%2==0)
{
therow.at<float>(0,0)=shape1[contPt].x;
therow.at<float>(0,1)=shape1[contPt].y;
therow.at<float>(0,2)=1;
therow.row(0).copyTo(matM.row(ii));
matP.at<float>(ii,0) = shape2[contPt].x;
}
else
{
therow.at<float>(0,3)=shape1[contPt].x;
therow.at<float>(0,4)=shape1[contPt].y;
therow.at<float>(0,5)=1;
therow.row(0).copyTo(matM.row(ii));
matP.at<float>(ii,0) = shape2[contPt].y;
contPt++;
}
}
Mat sol;
solve(matM, matP, sol, DECOMP_SVD);
out = sol.reshape(0,2);
}
else
{
Mat matM(siz, 4, CV_32F);
Mat matP(siz,1,CV_32F);
int contPt=0;
for (int ii=0; ii<siz; ii++)
{
Mat therow = Mat::zeros(1,4,CV_32F);
if (ii%2==0)
{
therow.at<float>(0,0)=shape1[contPt].x;
therow.at<float>(0,1)=shape1[contPt].y;
therow.at<float>(0,2)=1;
therow.row(0).copyTo(matM.row(ii));
matP.at<float>(ii,0) = shape2[contPt].x;
}
else
{
therow.at<float>(0,0)=shape1[contPt].y;
therow.at<float>(0,1)=-shape1[contPt].x;
therow.at<float>(0,3)=1;
therow.row(0).copyTo(matM.row(ii));
matP.at<float>(ii,0) = shape2[contPt].y;
contPt++;
}
}
Mat sol;
solve(matM, matP, sol, DECOMP_SVD);
out.at<float>(0,0)=sol.at<float>(0,0);
out.at<float>(0,1)=sol.at<float>(1,0);
out.at<float>(0,2)=sol.at<float>(2,0);
out.at<float>(1,0)=-sol.at<float>(1,0);
out.at<float>(1,1)=sol.at<float>(0,0);
out.at<float>(1,2)=sol.at<float>(3,0);
}
return out;
}
void AffineTransformerImpl::estimateTransformation(InputArray _pts1, InputArray _pts2, std::vector<DMatch>& _matches)
{
CV_INSTRUMENT_REGION();
Mat pts1 = _pts1.getMat();
Mat pts2 = _pts2.getMat();
CV_Assert((pts1.channels()==2) && (pts1.cols>0) && (pts2.channels()==2) && (pts2.cols>0));
CV_Assert(_matches.size()>1);
if (pts1.type() != CV_32F)
pts1.convertTo(pts1, CV_32F);
if (pts2.type() != CV_32F)
pts2.convertTo(pts2, CV_32F);
// Use only valid matchings //
std::vector<DMatch> matches;
for (size_t i=0; i<_matches.size(); i++)
{
if (_matches[i].queryIdx<pts1.cols &&
_matches[i].trainIdx<pts2.cols)
{
matches.push_back(_matches[i]);
}
}
// Organizing the correspondent points in vector style //
std::vector<Point2f> shape1; // transforming shape
std::vector<Point2f> shape2; // target shape
for (size_t i=0; i<matches.size(); i++)
{
Point2f pt1=pts1.at<Point2f>(0,matches[i].queryIdx);
shape1.push_back(pt1);
Point2f pt2=pts2.at<Point2f>(0,matches[i].trainIdx);
shape2.push_back(pt2);
}
Mat affine;
if (fullAffine)
{
estimateAffine2D(shape1, shape2).convertTo(affine, CV_32F);
} else
{
estimateAffinePartial2D(shape1, shape2).convertTo(affine, CV_32F);
}
if (affine.empty())
//In case there is not good solution, just give a LLS based one
affine = _localAffineEstimate(shape1, shape2, fullAffine);
affineMat = affine;
}
float AffineTransformerImpl::applyTransformation(InputArray inPts, OutputArray outPts)
{
CV_INSTRUMENT_REGION();
Mat pts1 = inPts.getMat();
CV_Assert((pts1.channels()==2) && (pts1.cols>0));
//Apply transformation in the complete set of points
Mat fAffine;
transform(pts1, fAffine, affineMat);
// Ensambling output //
if (outPts.needed())
{
outPts.create(1,fAffine.cols, CV_32FC2);
Mat outMat = outPts.getMat();
for (int i=0; i<fAffine.cols; i++)
outMat.at<Point2f>(0,i)=fAffine.at<Point2f>(0,i);
}
// Updating Transform Cost //
Mat Af(2, 2, CV_32F);
Af.at<float>(0,0)=affineMat.at<float>(0,0);
Af.at<float>(0,1)=affineMat.at<float>(1,0);
Af.at<float>(1,0)=affineMat.at<float>(0,1);
Af.at<float>(1,1)=affineMat.at<float>(1,1);
SVD mysvd(Af, SVD::NO_UV);
Mat singVals=mysvd.w;
transformCost=std::log((singVals.at<float>(0,0)+FLT_MIN)/(singVals.at<float>(1,0)+FLT_MIN));
return transformCost;
}
Ptr <AffineTransformer> createAffineTransformer(bool fullAffine)
{
return Ptr<AffineTransformer>( new AffineTransformerImpl(fullAffine) );
}
} // cv
This diff is collapsed.
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include <stdlib.h>
#include <math.h>
#include <vector>
/****************************************************************************************\
* For EMDL1 Framework *
\****************************************************************************************/
typedef struct cvEMDEdge* cvPEmdEdge;
typedef struct cvEMDNode* cvPEmdNode;
struct cvEMDNode
{
int pos[3]; // grid position
float d; // initial value
int u;
// tree maintenance
int iLevel; // level in the tree, 0 means root
cvPEmdNode pParent; // pointer to its parent
cvPEmdEdge pChild;
cvPEmdEdge pPEdge; // point to the edge coming out from its parent
};
struct cvEMDEdge
{
float flow; // initial value
int iDir; // 1:outward, 0:inward
// tree maintenance
cvPEmdNode pParent; // point to its parent
cvPEmdNode pChild; // the child node
cvPEmdEdge pNxt; // next child/edge
};
typedef std::vector<cvEMDNode> cvEMDNodeArray;
typedef std::vector<cvEMDEdge> cvEMDEdgeArray;
typedef std::vector<cvEMDNodeArray> cvEMDNodeArray2D;
typedef std::vector<cvEMDEdgeArray> cvEMDEdgeArray2D;
typedef std::vector<float> floatArray;
typedef std::vector<floatArray> floatArray2D;
/****************************************************************************************\
* EMDL1 Class *
\****************************************************************************************/
class EmdL1
{
public:
EmdL1()
{
m_pRoot = NULL;
binsDim1 = 0;
binsDim2 = 0;
binsDim3 = 0;
dimension = 0;
nMaxIt = 500;
m_pLeave = 0;
m_iEnter = 0;
nNBV = 0;
m_nItr = 0;
m_iTo = 0;
m_iFrom = 0;
m_pEnter = 0;
}
~EmdL1()
{
}
float getEMDL1(cv::Mat &sig1, cv::Mat &sig2);
void setMaxIteration(int _nMaxIt);
private:
//-- SubFunctions called in the EMD algorithm
bool initBaseTrees(int n1=0, int n2=0, int n3=0);
bool fillBaseTrees(float *H1, float *H2);
bool greedySolution();
bool greedySolution2();
bool greedySolution3();
void initBVTree();
void updateSubtree(cvPEmdNode pRoot);
bool isOptimal();
void findNewSolution();
void findLoopFromEnterBV();
float compuTotalFlow();
private:
int dimension;
int binsDim1, binsDim2, binsDim3; // the histogram contains m_n1 rows and m_n2 columns
int nNBV; // number of Non-Basic Variables (NBV)
int nMaxIt;
cvEMDNodeArray2D m_Nodes; // all nodes
cvEMDEdgeArray2D m_EdgesRight; // all edges to right
cvEMDEdgeArray2D m_EdgesUp; // all edges to upward
std::vector<cvEMDNodeArray2D> m_3dNodes; // all nodes for 3D
std::vector<cvEMDEdgeArray2D> m_3dEdgesRight; // all edges to right, 3D
std::vector<cvEMDEdgeArray2D> m_3dEdgesUp; // all edges to upward, 3D
std::vector<cvEMDEdgeArray2D> m_3dEdgesDeep; // all edges to deep, 3D
std::vector<cvPEmdEdge> m_NBVEdges; // pointers to all NON-BV edges
std::vector<cvPEmdNode> m_auxQueue; // auxiliary node queue
cvPEmdNode m_pRoot; // root of the BV Tree
cvPEmdEdge m_pEnter; // Enter BV edge
int m_iEnter; // Enter BV edge, index in m_NBVEdges
cvPEmdEdge m_pLeave; // Leave BV edge
int m_nItr; // number of iteration
// auxiliary variables for searching a new loop
std::vector<cvPEmdEdge> m_fromLoop;
std::vector<cvPEmdEdge> m_toLoop;
int m_iFrom;
int m_iTo;
};
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "precomp.hpp"
namespace cv
{
class HausdorffDistanceExtractorImpl CV_FINAL : public HausdorffDistanceExtractor
{
public:
/* Constructor */
HausdorffDistanceExtractorImpl(int _distanceFlag = NORM_L1, float _rankProportion=0.6)
{
distanceFlag = _distanceFlag;
rankProportion = _rankProportion;
name_ = "ShapeDistanceExtractor.HAU";
}
/* Destructor */
~HausdorffDistanceExtractorImpl()
{
}
//! the main operator
virtual float computeDistance(InputArray contour1, InputArray contour2) CV_OVERRIDE;
//! Setters/Getters
virtual void setDistanceFlag(int _distanceFlag) CV_OVERRIDE {distanceFlag=_distanceFlag;}
virtual int getDistanceFlag() const CV_OVERRIDE {return distanceFlag;}
virtual void setRankProportion(float _rankProportion) CV_OVERRIDE
{
CV_Assert((_rankProportion>0) && (_rankProportion<=1));
rankProportion=_rankProportion;
}
virtual float getRankProportion() const CV_OVERRIDE {return rankProportion;}
//! write/read
virtual void write(FileStorage& fs) const CV_OVERRIDE
{
writeFormat(fs);
fs << "name" << name_
<< "distance" << distanceFlag
<< "rank" << rankProportion;
}
virtual void read(const FileNode& fn) CV_OVERRIDE
{
CV_Assert( (String)fn["name"] == name_ );
distanceFlag = (int)fn["distance"];
rankProportion = (float)fn["rank"];
}
private:
int distanceFlag;
float rankProportion;
protected:
String name_;
};
//! Hausdorff distance for a pair of set of points
static float _apply(const Mat &set1, const Mat &set2, int distType, double propRank)
{
// Building distance matrix //
Mat disMat(set1.cols, set2.cols, CV_32F);
int K = int(propRank*(disMat.rows-1));
for (int r=0; r<disMat.rows; r++)
{
for (int c=0; c<disMat.cols; c++)
{
Point2f diff = set1.at<Point2f>(0,r)-set2.at<Point2f>(0,c);
disMat.at<float>(r,c) = (float)norm(Mat(diff), distType);
}
}
Mat shortest(disMat.rows,1,CV_32F);
for (int ii=0; ii<disMat.rows; ii++)
{
Mat therow = disMat.row(ii);
double mindis;
minMaxIdx(therow, &mindis);
shortest.at<float>(ii,0) = float(mindis);
}
Mat sorted;
cv::sort(shortest, sorted, SORT_EVERY_ROW | SORT_DESCENDING);
return sorted.at<float>(K,0);
}
float HausdorffDistanceExtractorImpl::computeDistance(InputArray contour1, InputArray contour2)
{
CV_INSTRUMENT_REGION();
Mat set1=contour1.getMat(), set2=contour2.getMat();
if (set1.type() != CV_32F)
set1.convertTo(set1, CV_32F);
if (set2.type() != CV_32F)
set2.convertTo(set2, CV_32F);
CV_Assert((set1.channels()==2) && (set1.cols>0));
CV_Assert((set2.channels()==2) && (set2.cols>0));
// Force vectors column-based
if (set1.dims > 1)
set1 = set1.reshape(2, 1);
if (set2.dims > 1)
set2 = set2.reshape(2, 1);
return std::max( _apply(set1, set2, distanceFlag, rankProportion),
_apply(set2, set1, distanceFlag, rankProportion) );
}
Ptr <HausdorffDistanceExtractor> createHausdorffDistanceExtractor(int distanceFlag, float rankProp)
{
return Ptr<HausdorffDistanceExtractor>(new HausdorffDistanceExtractorImpl(distanceFlag, rankProp));
}
} // cv
This diff is collapsed.
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __OPENCV_PRECOMP_H__
#define __OPENCV_PRECOMP_H__
#include <vector>
#include <cmath>
#include <iostream>
#include "opencv2/calib3d.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/shape.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/core/private.hpp"
#include "opencv2/opencv_modules.hpp"
#endif
This diff is collapsed.
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include <stdlib.h>
#include <math.h>
#include <vector>
namespace cv
{
/*
* ShapeContextDescriptor class
*/
class SCD
{
public:
//! the full constructor taking all the necessary parameters
explicit SCD(int _nAngularBins=12, int _nRadialBins=5,
double _innerRadius=0.1, double _outerRadius=1, bool _rotationInvariant=false)
{
setAngularBins(_nAngularBins);
setRadialBins(_nRadialBins);
setInnerRadius(_innerRadius);
setOuterRadius(_outerRadius);
setRotationInvariant(_rotationInvariant);
meanDistance = 0;
}
void extractSCD(cv::Mat& contour, cv::Mat& descriptors,
const std::vector<int>& queryInliers=std::vector<int>(),
const float _meanDistance=-1);
int descriptorSize() {return nAngularBins*nRadialBins;}
void setAngularBins(int angularBins) { nAngularBins=angularBins; }
void setRadialBins(int radialBins) { nRadialBins=radialBins; }
void setInnerRadius(double _innerRadius) { innerRadius=_innerRadius; }
void setOuterRadius(double _outerRadius) { outerRadius=_outerRadius; }
void setRotationInvariant(bool _rotationInvariant) { rotationInvariant=_rotationInvariant; }
int getAngularBins() const { return nAngularBins; }
int getRadialBins() const { return nRadialBins; }
double getInnerRadius() const { return innerRadius; }
double getOuterRadius() const { return outerRadius; }
bool getRotationInvariant() const { return rotationInvariant; }
float getMeanDistance() const { return meanDistance; }
private:
int nAngularBins;
int nRadialBins;
double innerRadius;
double outerRadius;
bool rotationInvariant;
float meanDistance;
protected:
void logarithmicSpaces(std::vector<double>& vecSpaces) const;
void angularSpaces(std::vector<double>& vecSpaces) const;
void buildNormalizedDistanceMatrix(cv::Mat& contour,
cv::Mat& disMatrix, const std::vector<int> &queryInliers,
const float _meanDistance=-1);
void buildAngleMatrix(cv::Mat& contour,
cv::Mat& angleMatrix) const;
};
/*
* Matcher
*/
class SCDMatcher
{
public:
// the full constructor
SCDMatcher() : minMatchCost(0)
{
}
// the matcher function using Hungarian method
void matchDescriptors(cv::Mat& descriptors1, cv::Mat& descriptors2, std::vector<cv::DMatch>& matches, cv::Ptr<cv::HistogramCostExtractor>& comparer,
std::vector<int>& inliers1, std::vector<int> &inliers2);
// matching cost
float getMatchingCost() const {return minMatchCost;}
private:
float minMatchCost;
protected:
void buildCostMatrix(const cv::Mat& descriptors1, const cv::Mat& descriptors2,
cv::Mat& costMatrix, cv::Ptr<cv::HistogramCostExtractor>& comparer) const;
void hungarian(cv::Mat& costMatrix, std::vector<cv::DMatch>& outMatches, std::vector<int> &inliers1,
std::vector<int> &inliers2, int sizeScd1=0, int sizeScd2=0);
};
}
This diff is collapsed.
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "test_precomp.hpp"
#if defined(HAVE_HPX)
#include <hpx/hpx_main.hpp>
#endif
CV_TEST_MAIN("cv")
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef __OPENCV_TEST_PRECOMP_HPP__
#define __OPENCV_TEST_PRECOMP_HPP__
#include "opencv2/ts.hpp"
#include "opencv2/shape.hpp"
#endif
This diff is collapsed.
#!/usr/bin/env python
import cv2 as cv
from tests_common import NewOpenCVTests
class shape_test(NewOpenCVTests):
def test_computeDistance(self):
a = self.get_sample('samples/data/shape_sample/1.png', cv.IMREAD_GRAYSCALE)
b = self.get_sample('samples/data/shape_sample/2.png', cv.IMREAD_GRAYSCALE)
ca, _ = cv.findContours(a, cv.RETR_CCOMP, cv.CHAIN_APPROX_TC89_KCOS)
cb, _ = cv.findContours(b, cv.RETR_CCOMP, cv.CHAIN_APPROX_TC89_KCOS)
hd = cv.createHausdorffDistanceExtractor()
sd = cv.createShapeContextDistanceExtractor()
d1 = hd.computeDistance(ca[0], cb[0])
d2 = sd.computeDistance(ca[0], cb[0])
self.assertAlmostEqual(d1, 26.4196891785, 3, "HausdorffDistanceExtractor")
self.assertAlmostEqual(d2, 0.25804194808, 3, "ShapeContextDistanceExtractor")
if __name__ == '__main__':
NewOpenCVTests.bootstrap()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment