fixed vector size mismatch between matched and status vectors

This commit is contained in:
admin1
2022-08-22 11:28:34 +03:00
commit 1b13777c36
177 changed files with 25221 additions and 0 deletions

View File

@@ -0,0 +1,86 @@
#ifndef CHESSBOARD_H
#define CHESSBOARD_H
#include <boost/shared_ptr.hpp>
#include <opencv2/core/core.hpp>
namespace camodocal
{
// forward declarations
class ChessboardCorner;
typedef boost::shared_ptr<ChessboardCorner> ChessboardCornerPtr;
class ChessboardQuad;
typedef boost::shared_ptr<ChessboardQuad> ChessboardQuadPtr;
class Chessboard
{
public:
Chessboard(cv::Size boardSize, cv::Mat& image);
void findCorners(bool useOpenCV = false);
const std::vector<cv::Point2f>& getCorners(void) const;
bool cornersFound(void) const;
const cv::Mat& getImage(void) const;
const cv::Mat& getSketch(void) const;
private:
bool findChessboardCorners(const cv::Mat& image,
const cv::Size& patternSize,
std::vector<cv::Point2f>& corners,
int flags, bool useOpenCV);
bool findChessboardCornersImproved(const cv::Mat& image,
const cv::Size& patternSize,
std::vector<cv::Point2f>& corners,
int flags);
void cleanFoundConnectedQuads(std::vector<ChessboardQuadPtr>& quadGroup, cv::Size patternSize);
void findConnectedQuads(std::vector<ChessboardQuadPtr>& quads,
std::vector<ChessboardQuadPtr>& group,
int group_idx, int dilation);
// int checkQuadGroup(std::vector<ChessboardQuadPtr>& quadGroup,
// std::vector<ChessboardCornerPtr>& outCorners,
// cv::Size patternSize);
void labelQuadGroup(std::vector<ChessboardQuadPtr>& quad_group,
cv::Size patternSize, bool firstRun);
void findQuadNeighbors(std::vector<ChessboardQuadPtr>& quads, int dilation);
int augmentBestRun(std::vector<ChessboardQuadPtr>& candidateQuads, int candidateDilation,
std::vector<ChessboardQuadPtr>& existingQuads, int existingDilation);
void generateQuads(std::vector<ChessboardQuadPtr>& quads,
cv::Mat& image, int flags,
int dilation, bool firstRun);
bool checkQuadGroup(std::vector<ChessboardQuadPtr>& quads,
std::vector<ChessboardCornerPtr>& corners,
cv::Size patternSize);
void getQuadrangleHypotheses(const std::vector< std::vector<cv::Point> >& contours,
std::vector< std::pair<float, int> >& quads,
int classId) const;
bool checkChessboard(const cv::Mat& image, cv::Size patternSize) const;
bool checkBoardMonotony(std::vector<ChessboardCornerPtr>& corners,
cv::Size patternSize);
bool matchCorners(ChessboardQuadPtr& quad1, int corner1,
ChessboardQuadPtr& quad2, int corner2) const;
cv::Mat mImage;
cv::Mat mSketch;
std::vector<cv::Point2f> mCorners;
cv::Size mBoardSize;
bool mCornersFound;
};
}
#endif

View File

@@ -0,0 +1,45 @@
#ifndef CHESSBOARDCORNER_H
#define CHESSBOARDCORNER_H
#include <boost/shared_ptr.hpp>
#include <opencv2/core/core.hpp>
namespace camodocal
{
class ChessboardCorner;
typedef boost::shared_ptr<ChessboardCorner> ChessboardCornerPtr;
class ChessboardCorner
{
public:
ChessboardCorner() : row(0), column(0), needsNeighbor(true), count(0) {}
float meanDist(int &n) const
{
float sum = 0;
n = 0;
for (int i = 0; i < 4; ++i)
{
if (neighbors[i].get())
{
float dx = neighbors[i]->pt.x - pt.x;
float dy = neighbors[i]->pt.y - pt.y;
sum += sqrt(dx*dx + dy*dy);
n++;
}
}
return sum / std::max(n, 1);
}
cv::Point2f pt; // X and y coordinates
int row; // Row and column of the corner
int column; // in the found pattern
bool needsNeighbor; // Does the corner require a neighbor?
int count; // number of corner neighbors
ChessboardCornerPtr neighbors[4]; // pointer to all corner neighbors
};
}
#endif

View File

@@ -0,0 +1,29 @@
#ifndef CHESSBOARDQUAD_H
#define CHESSBOARDQUAD_H
#include <boost/shared_ptr.hpp>
#include "camodocal/chessboard/ChessboardCorner.h"
namespace camodocal
{
class ChessboardQuad;
typedef boost::shared_ptr<ChessboardQuad> ChessboardQuadPtr;
class ChessboardQuad
{
public:
ChessboardQuad() : count(0), group_idx(-1), edge_len(FLT_MAX), labeled(false) {}
int count; // Number of quad neighbors
int group_idx; // Quad group ID
float edge_len; // Smallest side length^2
ChessboardCornerPtr corners[4]; // Coordinates of quad corners
ChessboardQuadPtr neighbors[4]; // Pointers of quad neighbors
bool labeled; // Has this corner been labeled?
};
}
#endif

View File

@@ -0,0 +1,319 @@
/* dynamo:- Event driven molecular dynamics simulator
http://www.marcusbannerman.co.uk/dynamo
Copyright (C) 2011 Marcus N Campbell Bannerman <m.bannerman@gmail.com>
This program is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 3 as published by the Free Software Foundation.
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, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/vector_proxy.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/triangular.hpp>
#include <boost/numeric/ublas/lu.hpp>
#include <exception>
namespace ublas = boost::numeric::ublas;
class Spline : private std::vector<std::pair<double, double> >
{
public:
//The boundary conditions available
enum BC_type {
FIXED_1ST_DERIV_BC,
FIXED_2ND_DERIV_BC,
PARABOLIC_RUNOUT_BC
};
enum Spline_type {
LINEAR,
CUBIC
};
//Constructor takes the boundary conditions as arguments, this
//sets the first derivative (gradient) at the lower and upper
//end points
Spline():
_valid(false),
_BCLow(FIXED_2ND_DERIV_BC), _BCHigh(FIXED_2ND_DERIV_BC),
_BCLowVal(0), _BCHighVal(0),
_type(CUBIC)
{}
typedef std::vector<std::pair<double, double> > base;
typedef base::const_iterator const_iterator;
//Standard STL read-only container stuff
const_iterator begin() const { return base::begin(); }
const_iterator end() const { return base::end(); }
void clear() { _valid = false; base::clear(); _data.clear(); }
size_t size() const { return base::size(); }
size_t max_size() const { return base::max_size(); }
size_t capacity() const { return base::capacity(); }
bool empty() const { return base::empty(); }
//Add a point to the spline, and invalidate it so its
//recalculated on the next access
inline void addPoint(double x, double y)
{
_valid = false;
base::push_back(std::pair<double, double>(x,y));
}
//Reset the boundary conditions
inline void setLowBC(BC_type BC, double val = 0)
{ _BCLow = BC; _BCLowVal = val; _valid = false; }
inline void setHighBC(BC_type BC, double val = 0)
{ _BCHigh = BC; _BCHighVal = val; _valid = false; }
void setType(Spline_type type) { _type = type; _valid = false; }
//Check if the spline has been calculated, then generate the
//spline interpolated value
double operator()(double xval)
{
if (!_valid) generate();
//Special cases when we're outside the range of the spline points
if (xval <= x(0)) return lowCalc(xval);
if (xval >= x(size()-1)) return highCalc(xval);
//Check all intervals except the last one
for (std::vector<SplineData>::const_iterator iPtr = _data.begin();
iPtr != _data.end()-1; ++iPtr)
if ((xval >= iPtr->x) && (xval <= (iPtr+1)->x))
return splineCalc(iPtr, xval);
return splineCalc(_data.end() - 1, xval);
}
private:
///////PRIVATE DATA MEMBERS
struct SplineData { double x,a,b,c,d; };
//vector of calculated spline data
std::vector<SplineData> _data;
//Second derivative at each point
ublas::vector<double> _ddy;
//Tracks whether the spline parameters have been calculated for
//the current set of points
bool _valid;
//The boundary conditions
BC_type _BCLow, _BCHigh;
//The values of the boundary conditions
double _BCLowVal, _BCHighVal;
Spline_type _type;
///////PRIVATE FUNCTIONS
//Function to calculate the value of a given spline at a point xval
inline double splineCalc(std::vector<SplineData>::const_iterator i, double xval)
{
const double lx = xval - i->x;
return ((i->a * lx + i->b) * lx + i->c) * lx + i->d;
}
inline double lowCalc(double xval)
{
const double lx = xval - x(0);
if (_type == LINEAR)
return lx * _BCHighVal + y(0);
const double firstDeriv = (y(1) - y(0)) / h(0) - 2 * h(0) * (_data[0].b + 2 * _data[1].b) / 6;
switch(_BCLow)
{
case FIXED_1ST_DERIV_BC:
return lx * _BCLowVal + y(0);
case FIXED_2ND_DERIV_BC:
return lx * lx * _BCLowVal + firstDeriv * lx + y(0);
case PARABOLIC_RUNOUT_BC:
return lx * lx * _ddy[0] + lx * firstDeriv + y(0);
}
throw std::runtime_error("Unknown BC");
}
inline double highCalc(double xval)
{
const double lx = xval - x(size() - 1);
if (_type == LINEAR)
return lx * _BCHighVal + y(size() - 1);
const double firstDeriv = 2 * h(size() - 2) * (_ddy[size() - 2] + 2 * _ddy[size() - 1]) / 6 + (y(size() - 1) - y(size() - 2)) / h(size() - 2);
switch(_BCHigh)
{
case FIXED_1ST_DERIV_BC:
return lx * _BCHighVal + y(size() - 1);
case FIXED_2ND_DERIV_BC:
return lx * lx * _BCHighVal + firstDeriv * lx + y(size() - 1);
case PARABOLIC_RUNOUT_BC:
return lx * lx * _ddy[size()-1] + lx * firstDeriv + y(size() - 1);
}
throw std::runtime_error("Unknown BC");
}
//These just provide access to the point data in a clean way
inline double x(size_t i) const { return operator[](i).first; }
inline double y(size_t i) const { return operator[](i).second; }
inline double h(size_t i) const { return x(i+1) - x(i); }
//Invert a arbitrary matrix using the boost ublas library
template<class T>
bool InvertMatrix(ublas::matrix<T> A,
ublas::matrix<T>& inverse)
{
using namespace ublas;
// create a permutation matrix for the LU-factorization
permutation_matrix<std::size_t> pm(A.size1());
// perform LU-factorization
int res = lu_factorize(A,pm);
if( res != 0 ) return false;
// create identity matrix of "inverse"
inverse.assign(ublas::identity_matrix<T>(A.size1()));
// backsubstitute to get the inverse
lu_substitute(A, pm, inverse);
return true;
}
//This function will recalculate the spline parameters and store
//them in _data, ready for spline interpolation
void generate()
{
if (size() < 2)
throw std::runtime_error("Spline requires at least 2 points");
//If any spline points are at the same x location, we have to
//just slightly seperate them
{
bool testPassed(false);
while (!testPassed)
{
testPassed = true;
std::sort(base::begin(), base::end());
for (base::iterator iPtr = base::begin(); iPtr != base::end() - 1; ++iPtr)
if (iPtr->first == (iPtr+1)->first)
{
if ((iPtr+1)->first != 0)
(iPtr+1)->first += (iPtr+1)->first
* std::numeric_limits<double>::epsilon() * 10;
else
(iPtr+1)->first = std::numeric_limits<double>::epsilon() * 10;
testPassed = false;
break;
}
}
}
const size_t e = size() - 1;
switch (_type)
{
case LINEAR:
{
_data.resize(e);
for (size_t i(0); i < e; ++i)
{
_data[i].x = x(i);
_data[i].a = 0;
_data[i].b = 0;
_data[i].c = (y(i+1) - y(i)) / (x(i+1) - x(i));
_data[i].d = y(i);
}
break;
}
case CUBIC:
{
ublas::matrix<double> A(size(), size());
for (size_t yv(0); yv <= e; ++yv)
for (size_t xv(0); xv <= e; ++xv)
A(xv,yv) = 0;
for (size_t i(1); i < e; ++i)
{
A(i-1,i) = h(i-1);
A(i,i) = 2 * (h(i-1) + h(i));
A(i+1,i) = h(i);
}
ublas::vector<double> C(size());
for (size_t xv(0); xv <= e; ++xv)
C(xv) = 0;
for (size_t i(1); i < e; ++i)
C(i) = 6 *
((y(i+1) - y(i)) / h(i)
- (y(i) - y(i-1)) / h(i-1));
//Boundary conditions
switch(_BCLow)
{
case FIXED_1ST_DERIV_BC:
C(0) = 6 * ((y(1) - y(0)) / h(0) - _BCLowVal);
A(0,0) = 2 * h(0);
A(1,0) = h(0);
break;
case FIXED_2ND_DERIV_BC:
C(0) = _BCLowVal;
A(0,0) = 1;
break;
case PARABOLIC_RUNOUT_BC:
C(0) = 0; A(0,0) = 1; A(1,0) = -1;
break;
}
switch(_BCHigh)
{
case FIXED_1ST_DERIV_BC:
C(e) = 6 * (_BCHighVal - (y(e) - y(e-1)) / h(e-1));
A(e,e) = 2 * h(e - 1);
A(e-1,e) = h(e - 1);
break;
case FIXED_2ND_DERIV_BC:
C(e) = _BCHighVal;
A(e,e) = 1;
break;
case PARABOLIC_RUNOUT_BC:
C(e) = 0; A(e,e) = 1; A(e-1,e) = -1;
break;
}
ublas::matrix<double> AInv(size(), size());
InvertMatrix(A,AInv);
_ddy = ublas::prod(C, AInv);
_data.resize(size()-1);
for (size_t i(0); i < e; ++i)
{
_data[i].x = x(i);
_data[i].a = (_ddy(i+1) - _ddy(i)) / (6 * h(i));
_data[i].b = _ddy(i) / 2;
_data[i].c = (y(i+1) - y(i)) / h(i) - _ddy(i+1) * h(i) / 6 - _ddy(i) * h(i) / 3;
_data[i].d = y(i);
}
}
}
_valid = true;
}
};