关于VisualSFM中的.sift和.mat文件详细信息(包括读、存等)

编程入门 行业动态 更新时间:2024-10-09 16:22:33

关于VisualSFM中的.sift和.mat文件<a href=https://www.elefans.com/category/jswz/34/1765150.html style=详细信息(包括读、存等)"/>

关于VisualSFM中的.sift和.mat文件详细信息(包括读、存等)

windows  VS2013实测可以,我自己改了一些东西,以便能运行

在项目|属性|配置属性|C/C++|预处理器|预处理定义中加入 _CRT_SECURE_NO_DEPRECATE

头文件:

points.h


//	File:		points.h
//	Author:		Changchang Wu (ccwu1130@gmail)
//	Description : 
//
//  Copyright (c) 2011  Changchang Wu (ccwu1130@gmail)
//
//  This library 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 3 of the License, or (at your option) any later version.
//
//  This library 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.
//#ifndef POINTS_H_INCLUDED
#define POINTS_H_INCLUDED
#pragma oncetemplate <class T> class Points;
//#define USE_MEM_COLLECTtemplate <class T>
class Points
{typedef T (*TV2)[2];typedef T (*TV3)[3];typedef T (*TV5)[5];typedef T (*TV128)[128];
protected:T *		_data;T **	_matrix;int		_width;int		_height; bool	_subset;
private:void init(int width, int height){_subset	=	0;if( width >0 && height >0 ){_matrix =	(T**) malloc(sizeof(T)*width*height+sizeof(T*)*height);if(_matrix){_data	=	(T* ) (_matrix+height);T* temp =	_data;for( int i =0 ; i < height; _matrix[i++]=temp, temp+=width);_width	=	width;_height	=	height;}else{_width = _height = 0;_data = NULL;}}else{_width = _height = 0;_data = NULL;_matrix = NULL;}}public:Points(){_data = NULL;_matrix = NULL;_height = 0;_width  = 0;_subset = 0;}Points(const Points<T> &ref){init(ref.width(), ref.height());copy_from(ref, 0, 0);}Points(int width,  int height){init(width, height);}Points(int width, int height, T v){init(width, height);fill(v);}Points(T** sup, int ndim, int num){_subset	=	true;_width	=	ndim;_height	=	num;_data	=	NULL;if(num>0 && ndim>0){_matrix =  (T**) malloc(sizeof(T*)*num);for (int i = 0; i < num; i++) _matrix[i]= sup[i];}else{_matrix = NULL;}		}void setx(int width, int height, T* data){release();_subset = 1;_width = width;_height = height;_data = data;_matrix = (T**) malloc(sizeof(T*) * height);for(int i = 0; i < height; i++, data += width) _matrix[i] = data;}template <class POINTS>Points(POINTS&   sup, int index [], int num){_subset	=	true;_width	=	sup.width();_height	=	num;_data	=	sup.data();if(num>0 && _width>0){_matrix =  (T**) malloc(sizeof(T*)*num);for (int i = 0; i < num; i++) _matrix[i]=sup[index[i]];}else{_matrix  = NULL;}}private:void release(){if(_matrix)	free(_matrix);}
public:void resize(int width, int height){if(width == _width && height ==_height) return;release();init(width, height);}void resize(int width, int height, T v){resize(width, height);fill(v);}void expand(int width, int height){//make sure size are if(width < _width || height < _height) return;if(width ==_width && height ==_height && _subset ==0) return;T* newdata, **newmatrix, *temp;int i;newmatrix =	(T**) malloc(sizeof(T)*width*height+sizeof(T*)*height);temp = newdata	=	(T* ) (newmatrix+height);for( i =0 ; i < height;i++, temp+=width){newmatrix[i]=temp;}for( i = 0; i< _height;  i++){memcpy(newmatrix[i], _matrix[i], _width*sizeof(T));}release();_subset		=	0;_width		=	width;_height		=	height;_matrix		= newmatrix;_data		= newdata;}void expand(int width, int height, T v){//make sure size are if(width < _width || height < _height) return;if(width ==_width && height ==_height && _subset ==0) return;T* newdata, **newmatrix, *temp;int i, j;newmatrix =	(T**) malloc(sizeof(T)*width*height+sizeof(T*)*height);temp = newdata	=	(T* ) (newmatrix+height);for( i =0 ; i < height;i++, temp+=width){newmatrix[i]=temp;}for( i = 0; i< _height;  i++){memcpy(newmatrix[i], _matrix[i], _width*sizeof(T));for(j = _width; j < width; ++j) newmatrix[i][j] = v;}for(; i < height; i++){for(j = 0; j < width; ++j) newmatrix[i][j] = v;}release();_subset		=	0;_width		=	width;_height		=	height;_matrix		= newmatrix;_data		= newdata;}void copy_from(const Points<T>& src, int dx, int dy){int nw = min(src.width() , width() - dx);int nh = min(src.height(), height() - dy);/for(int i = 0; i < nh; ++i){for(int j = 0; j < nw; ++j){_matrix[i + dy][j + dx] = src._matrix[i][j];}}}void swap(Points<T>& temp){T *		data = _data;T **	matrix = _matrix;int		width = _width;int		height = _height; bool	subset = _subset;_data	= temp._data;_matrix = temp._matrix;_width  = temp._width;_height = temp._height;_subset = temp._subset;temp._data = data;temp._matrix = matrix;temp._width = width;temp._height = height;temp._subset = subset;}void make_sub_from(Points<T>& src, int dx, int dy){int nw = min(src.width() - dx , width());int nh = min(src.height()- dy, height() );/for(int i = 0; i < nh; ++i){for(int j = 0; j < nw; ++j){_matrix[i][j] = src._matrix[i + dy][j + dx];}}}void shrink(int width, int height){//make sure size are if(width > _width || height > _height) return;if(width ==_width && height ==_height) return;T* newdata, **newmatrix, *temp;int i;newmatrix =	(T**) malloc(sizeof(T)*width*height+sizeof(T*)*height);temp = newdata	=	(T* ) (newmatrix+height);for( i =0 ; i < height;i++, temp+=width){newmatrix[i]=temp;}for( i = 0; i< height;  i++){memcpy(newmatrix[i], _matrix[i], width*sizeof(T));}release();_subset		=	0;_width		=	width;_height		=	height;_matrix		= newmatrix;_data		= newdata;}~Points(){release();}T* data(){return _data;}T* end(){return _data + _width * _height;}int invalid(){return _width == 0 || _height == 0;}int bsize(){return _width*_height*sizeof(T);}int width() const{return _width;}int height() const{return _height;}int ndim() const{return _width;}int npoint() const{return _height;}T* operator[](int i) {return _matrix[i];}T* operator[](int i) const{return _matrix[i];}Points<T>& operator = (const Points<T>& ref){resize(ref.width(), ref.height());if(_width > 0 && _height > 0){if(ref._subset){for(int i = 0; i < _height; ++i){memcpy(_matrix[i], ref._matrix[i], _width * sizeof(T));}}else{memcpy(_data, ref._data, bsize());}}return * this; }void own_data(){if(_subset)expand(_width, _height);}operator T** const () const{return _matrix;}operator T** () {return _matrix;}operator TV2(){
#ifdef _DEBUGreturn _width==2 && _subset == 0 ? (T (*)[2]) _data : NULL;
#elsereturn (T (*)[2]) _data;
#endif}operator TV3(){
#ifdef _DEBUGreturn _width==3 && _subset == 0 ? (T (*)[3]) _data : NULL;
#elsereturn (T (*)[3]) _data ;
#endif}operator TV5(){
#ifdef _DEBUGreturn _width==5 && _subset == 0 ? (T (*)[5]) _data : NULL;
#elsereturn (T (*)[5]) _data ;
#endif}operator TV128(){
#ifdef _DEBUGreturn _width==128 && _subset == 0 ? (T (*)[128]) _data : NULL;
#elsereturn (T (*)[128]) _data ;
#endif}int checkdim(int dim){if(dim >= _width) expand(_width * 2, _height);return _width;}T* getpt(int i){return _matrix[i];}T* getpt(int i)const{return _matrix[i];}void fill(T v){int i= _width*_height;T* temp= _data;for (; i>0; i--)*temp++= v;}void reorder(const int* index){//if(0 ==_width && 0 ==_height) return;T* newdata, **newmatrix, *temp;int i;newmatrix =	(T**) malloc(sizeof(T)*_width*_height+sizeof(T*)*_height);temp = newdata	=	(T* ) (newmatrix+_height);for( i =0 ; i < _height;i++){newmatrix[i]=temp;temp+=_width;}for( i = 0; i< _height;  i++){memcpy(newmatrix[i], _matrix[index[i]], _width*sizeof(T));}release();_subset	=	0;_matrix = newmatrix;_data = newdata;}};//triangle matrix
template <class T>
class PointsT
{
protected:T **	_matrix;int		_width;
private:T** allocate(int width){if( width >0 ){T** mat = (T**) malloc(sizeof(T*) * width);for(int i = 0; i < _width; ++i){mat[i] = ((T*) malloc(sizeof(T) * (width - i))) - i;}return mat;}else{return NULL;}}
public:PointsT(){_matrix = NULL;_width  = 0;}PointsT(int width,  int height){_width = width > height ? width  :height;_matrix = allocate(_width);}void release(){if(_matrix && _width > 0)	{for(int i = 0; i < _width; ++i){free(_matrix[i] + i);}free(_matrix);_matrix = NULL;_width = 0;}}
public:void expand(int width, int height, T v){expand(width > height ? width : height, v);}void expand(int width, T v){//make sure size are if(width <= _width ) return;T** newmatrix =	(T**) malloc(sizeof(T*)*width);     int i = 0, dw = width - _width;if(dw <= _width){for(; i < dw; ++i){newmatrix[i] = ((T*) malloc(sizeof(T) * (width - i))) - i;memcpy(newmatrix[i] + i, _matrix[i] + i, (_width - i) * sizeof(T));//memset(newmatrix[i] + _width, 0, dw * sizeof(T));for(int j = _width; j < width; ++j)newmatrix[i][j] = v;}for(; i < _width; ++i){newmatrix[i] = _matrix[i - dw] - dw;memcpy(newmatrix[i] + i, _matrix[i] + i, (_width - i) * sizeof(T));//memset(newmatrix[i] + _width, 0, dw * sizeof(T));for(int j = _width; j < width; ++j)newmatrix[i][j] = v;} }else{for(; i < _width; ++i){newmatrix[i] = ((T*) malloc(sizeof(T) * (width - i))) - i;memcpy(newmatrix[i] + i, _matrix[i] + i, (_width - i) * sizeof(T));//memset(newmatrix[i] + _width, 0, dw * sizeof(T));for(int j = _width; j < width; ++j)newmatrix[i][j] = v;}for(; i < dw; ++i){newmatrix[i] = ((T*) malloc(sizeof(T) * (width - i))) - i;//memset(newmatrix[i] + _width, 0, dw * sizeof(T));for(int j = i; j < width; ++j)newmatrix[i][j] = v;}}for(; i < width; ++i){newmatrix[i] = _matrix[i - dw] - dw;for(int j = i; j < width;++j) newmatrix[i][j] = v;}free(_matrix);_matrix = newmatrix;_width		=	width;}~PointsT(){release();}int invalid(){return _width == 0;}int width() const{return _width;}int ndim() const{return _width;}T* operator[](int i) {return _matrix[i];}T* operator[](int i) const{return _matrix[i];}operator T** const () const{return _matrix;}operator T** () {return _matrix;}void fill(T v){for(int i = 0; i < _width; ++i){for(int j = i; j < _width; ++j){_matrix[i][j] = v;}}}
};#endif

FeaturePoints.h


//	File:		FeaturePoints.h
//	Author:		Changchang Wu (ccwu1130@gmail)
//	Description : 
//
//  Copyright (c) 2011  Changchang Wu (ccwu1130@gmail)
//
//  This library 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 3 of the License, or (at your option) any later version.
//
//  This library 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.
//#if !defined(FEATURE_POINTS_H_INCLUDED)
#define FEATURE_POINTS_H_INCLUDED
#pragma once#include <fstream>
#include <vector>
#include <string>
using std::vector;
using std::ifstream;
using std::ofstream;
using std::string;#include "points.h"///
//DESCRIPTOR TYPE
typedef unsigned char	DTYPE;
//FEATURE LOCATION TYPE
typedef float LTYPE;//#define DEBUG_DESCRIPTOR_BUGfeature set with position info
//#define SIFT_LOCATION_NEWclass FeatureData 
{typedef struct sift_fileheader_v2{int	 szFeature;int  szVersion;int  npoint;int  nLocDim;int  nDesDim;}sift_fileheader_v2;typedef struct sift_fileheader_v1{int  npoint;int  nLocDim;int  nDesDim;}sift_fileheader_v1;enum{
//		READ_BUFFER_SIZE = 0x100000,SIFT_NAME= ('S'+ ('I'<<8)+('F'<<16)+('T'<<24)),MSER_NAME= ('M'+ ('S'<<8)+('E'<<16)+('R'<<24)),RECT_NAME= ('R'+ ('E'<<8)+('C'<<16)+('T'<<24)), //SIFT_VERSION_2=('V'+('2'<<8)+('.'<<16)+('0'<<24)),//SIFT_VERSION_3=('V'+('3'<<8)+('.'<<16)+('0'<<24)),SIFT_VERSION_4=('V'+('4'<<8)+('.'<<16)+('0'<<24)),SIFT_VERSION_5=('V'+('5'<<8)+('.'<<16)+('0'<<24)),SIFT_EOF = (0xff+('E'<<8)+('O'<<16)+('F'<<24)),};
//	static char readBuf[READ_BUFFER_SIZE];
//	static char sift_version[8];static inline int IsValidFeatureName(int value){return value == SIFT_NAME || value == MSER_NAME;}static inline int IsValidVersionName(int value){return value == SIFT_VERSION_4 || value == SIFT_VERSION_5;}
public:class LocationData: public Points<LTYPE>{public:int              _file_version;public://each feature has x,y, z, size, orientation//for rect feature, there is x, y, width, height//for eclips feature, there is u,v,a,b,c +zpublic:void glPaint2D(int style);LocationData(int d, int n):Points<LTYPE>(d,n),  _file_version(0){	};LocationData( LocationData& sup, int index[], int n): Points<LTYPE>(sup,index,n), _file_version(0){};static void glPaintTexSIFT(const float * loc, float td[3]);static void glPaintTexFrontalVIP(const float * loc, float td[3]);static void glPaintSIFT(const LTYPE* loc);static void glPaintSIFTSQ(LTYPE*  loc);static void glPaintELIPS(LTYPE*  loc);static void glPaintRECT(LTYPE* loc);static void SetPaintColor(LTYPE sz);};class DescriptorData: public Points<DTYPE>{//generally d is 128public:DescriptorData(DescriptorData& sup, int index[], int n): Points<DTYPE>(sup,index,n){};DescriptorData(int d, int n):Points<DTYPE>(d,n){};};static float gSiftDisplayScale;static int	 gSiftVisualStyle;
protected:void ReadFeatureDataA(ifstream & is, int npt,  int locDim, int desDim, int szFeatureName);// the set of feature descriptorsDescriptorData * _desData;// the set of feature locationsLocationData *   _locData;int              _npoint;int				 _updated;
public:void SetUpdated(){_updated = 1;}int  GetUpdated(){return _updated;}void CopyToFeatureData(FeatureData &fd);int  appendSIFTB(const char* szFile,int pos);int  validate()	{		return _locData && _desData;	}void ResizeFeatureData(int npoint, int locDim = 5, int desDim = 128){if(npoint ==0){if(_locData) delete _locData;if(_desData) delete _desData;_locData = NULL;_desData = NULL;}else{if(_locData)_locData->resize(locDim, npoint);else_locData = new LocationData(locDim, npoint);if(_desData)_desData->resize(desDim, npoint);else_desData = new DescriptorData(desDim, npoint);_locData->_file_version  = SIFT_VERSION_4;}_npoint = npoint;}void operator = (FeatureData& ref) { ref.CopyToFeatureData(*this); }void ResizeLocationData(int npoint, int locDim){if(npoint ==0){if(_locData) delete _locData;if(_desData) delete _desData;_locData = NULL;_desData = NULL;}else{if(_locData)_locData->resize(locDim, npoint);else_locData = new LocationData(locDim, npoint);if(_desData){delete _desData;_desData = NULL;}_locData->_file_version  = SIFT_VERSION_4;	}}void ShrinkLocationData(int ndim = 2, int npoint = -1);void ReleaseDescriptorData(){if(_desData){delete _desData;_desData = NULL;}}
public:void SortSIFT();void SaveSIFTBClip(const char* szFileName, int x1, int x2, int y1, int y2);int ValidateIndex(int index[], int n);void ConvertA2B(const char* szFile);void SaveDescriptorFile(const char* szFeatureFile);void SaveLocationFile(const char* szFeatureFile);static int ReadRandomFeature(const char* path, double* pt, int nDim);static int ExportSIFT(const char*featurefile, Points<double>& points);static int OpenSeekSIFT(const char* featurefile, int& npoint, int& ndim);static int ExportSIFT(const char* featurefile, int fdx);int  ReadSIFTB(const char* szFile);int  ReadSIFTB_LOC(const char* szFile);int  ReadSIFTB_LOCT(const char* szFile, int fmax);int  ReadSIFTB_DES(const char* szFile, int fmax);static int ReadSIFTB_DES(const char* szFile, unsigned char * buf, int nmax);static int ReadSIFTA_DES(const char* szFile, unsigned char * buf, int nmax);static int ReadSIFTB_LOC(const char* szFile, float * buf, int nmax ); static int ReadSIFTB(const char* szFile, float * locbuf, unsigned char * desbuf, int nmax);void offsetFeatures(int ox, int oy);void saveSIFTB2(const char* szFile);void saveSIFTA(const char* szFile, const int nDesDim = 128);void Overwrite_SIFTLOC(const char* szFile);void CreateFeatureClip(FeatureData& src, int x1, int x2, int y1, int y2, int smax =100000 );void SetFeatureClip(FeatureData&src, int nsf, int index[], int subset = 1);void ReleaseFeatureData();void FlipLocation(float imheight);int ReadSIFTA(const char* szFile);FeatureData();virtual ~FeatureData();DescriptorData&  getDescriptorData() {return *_desData;}LocationData&   getLocationData()const {return *_locData;}int		IsValidFeatureData(){return getFeatureNum() > 0;}int		getFeatureNum(){return _npoint;}int		getLoadedFeatureNum(){return _locData? _locData->npoint(): 0;}
};typedef FeatureData::LocationData FeatureLocationData;
typedef FeatureData::DescriptorData FeatureDescriptorData;#endif // !defined(FEATURE_POINTS_H_INCLUDED)

MatchFile.h


//	File:		MatchFile.h
//	Author:		Changchang Wu (ccwu1130@gmail)
//	Description : 
//
//  Copyright (c) 2011  Changchang Wu (ccwu1130@gmail)
//
//  This library 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 3 of the License, or (at your option) any later version.
//
//  This library 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.
//#ifndef MATCH_FILE_H_INCLUDED
#define MATCH_FILE_H_INCLUDED
#pragma once#include <vector>
#include <string>
using std::vector;
using std::string;
#include "points.h"
#define MAX_PATH 260//+++To read the number of matches of iamge1 and image2------------------------------
//Ues member funcation  -----MatchFile::GetMatchCount--------------------------------
//int NM;		//number of putative matches
//int NF;		//number of inlier matches
//MatchFile mat(image1_full_path); //image1
//if(mat.IsValid() && mat.GetMatchCount(image2_full_path, NM, NF)) {/*we have it*/}//+++To read back putative matches----------------------------------------------------
//use member function ----MatchFile::GetPMatch----------------------------------------
//int FC;		//feature count of image2, input
//int NM;		//number of putative matches, output
//Points<int>	matches;// feature index of putative matches, output
//MatchFile mat(image1_full_path); //image1's match database
//if(mat.IsValid() && mat.GetPMatch(image2_full_path, FC, NM, matches)) {/* we have it*/};//
//+++To write puattive matching----------------------------------------------------------
//Use static function ----MatchFile::WritePMatch---------------------------------------
//You can call MatchFile::WritePMatch(
//		char* image1_full_path_no_extension,
//		char* image2_full_path_no_extension, 
//		int feature_count_of_image1, 
//		int feature_count_of_image2, 
//	    int number_of_matches,
//		Points<int>& matches)
//
//		You should call matches.resize(number_of_matches, 2) to form the matrix
//		matches[0][] are the indices of image1
//		matches[1][] are the indices of image2struct TwoViewGeometry{int   NF, NE;	// ni fundamental/essential matrixint   NH, NH2;	// ni homogrphyfloat F[3][3];	// fundamental matrixfloat R[3][3];	// rotationfloat T[3];		// translationfloat F1, F2;	//float H[3][3];	//float GE;		// geometric error float AA;		// triangulation angleTwoViewGeometry(){NF = NE = NH = NH2 = 0;AA = F1 = F2 = 0.0;	GE = 100.0f;}//simple geometryTwoViewGeometry(int Num, float FMat[3][3]){NF = Num;NE = NH = NH2 = 0;AA = F1 = F2 = 0.0;GE = 100.0f;memcpy(F, FMat, sizeof(F));}void ResetGeometry(){NF = NE = NH = NH2 = 0;AA = F1 = F2 = 0.0;GE = 100.0f;		}void ExchangeView(){float RT[3][3] = {	{R[0][0], R[1][0], R[2][0]},{R[0][1], R[1][1], R[2][1]},{R[0][2], R[1][2], R[2][2]}};float TT[3] = {	-R[0][0] * T[0] - R[1][0] * T[1] - R[2][0] * T[2],-R[0][1] * T[0] - R[1][1] * T[1] - R[2][1] * T[2],-R[0][2] * T[0] - R[1][2] * T[1] - R[2][2] * T[2]};float FT[3][3] = {	{F[0][0], F[1][0], F[2][0]},{F[0][1], F[1][1], F[2][1]},{F[0][2], F[1][2], F[2][2]}	};memcpy(F, FT, sizeof(F));memcpy(R, RT, sizeof(R));memcpy(T, TT, sizeof(T));float TF = F1;	F1 = F2;	F2 = TF;}static void TransposeMatrix33(const float M[3][3], float MT[3][3]){MT[0][0] = M[0][0];	MT[0][1] = M[1][0];	MT[0][2] = M[2][0];MT[1][0] = M[0][1];	MT[1][1] = M[1][1];	MT[1][2] = M[2][1];MT[2][0] = M[0][2];	MT[2][1] = M[1][2];	MT[2][2] = M[2][2];}void SetGeometryR(const TwoViewGeometry& g){NF = g.NF;	NE = g.NE;	NH = g.NH;	NH2 = g.NH2;GE = g.GE;	AA = g.AA;F1 = g.F2;	F2 = g.F1;if(g.NF > 0){TransposeMatrix33(g.F, F);if(g.NE > 0){/TransposeMatrix33(g.R, R);//T[0] = -R[0][0] * g.T[0] - R[0][1] * g.T[1] - R[0][2] * g.T[2];T[1] = -R[1][0] * g.T[0] - R[1][1] * g.T[1] - R[1][2] * g.T[2];T[2] = -R[2][0] * g.T[0] - R[2][1] * g.T[1] - R[2][2] * g.T[2];}}if(g.NH2 > 0)	TransposeMatrix33(g.H, H);}void SetGeometry(const TwoViewGeometry& g){NF = g.NF;	NE = g.NE;	NH = g.NH;	NH2 = g.NH2;GE = g.GE;	AA = g.AA;F1 = g.F1;	F2 = g.F2;if(g.NF > 0)	{memcpy(F, g.F, sizeof(F));if(g.NE > 0){memcpy(R, g.R, sizeof(R));T[0] = g.T[0];	T[1] = g.T[1];	T[2] = g.T[2];}}if(g.NH2 > 0)	memcpy(H, g.H, sizeof(H));}
};class NamedMutex; class MatchFile
{enum{MATCH_FILE_VERSION_3= ('M'+ ('T'<<8)+('0'<<16)+('3'<<24)),MATCH_FILE_LATEST_VERSION = MATCH_FILE_VERSION_3,MATCH_RECORD_V3 = ('M'+ ('R'<<8)+('V'<<16)+('3'<<24)),};struct MatchRecordV3{int	version;TwoViewGeometry	tvg;int	 extra[7]; //reserved data for future change;MatchRecordV3(){version = MatchFile::MATCH_RECORD_V3;memset(extra, 0, sizeof(extra));}};//image file can change..//number of features can change. //exif focal length can change. struct FileHeader{int		version;int		file_count;int		definition_size;	//int		definition_buf;		//int		feature_count;		//this might change..};struct RecordLoc{int		fcount;int		read_loc;		// read locationint		block_size;		// block sizeint		trash_size;		// trash size after int		extra_size;		//char	file_name[4];};private:static int	multi_thread_mode;static int	file_title_mode;static int	delay_header_update;static int  record_reservation;static int  num_match_verification;
private:NamedMutex*			_mutex;int					_fid; int					_opened_for_write;int					_header_changed;size_t				_recordloc_unchanged;int					_matchfile_mode;FileHeader			_header;char				_filepath[MAX_PATH];const char*			_title;vector<char>		_record_definition;vector<RecordLoc*>	_match_records;
private:void DeleteMatchRecord(const char* pattern = "extra");void GetRecordList();void MoveRecordToEnd(int i);void GetMatchFilePath(char* match_path);void GetMatchFolderPath(char* match_path);int  AddImageMatch(const char* relative_path);int  GetImageIndex(const char* relative_path);void GetRelativePath(const char* image_match, char* relative_path);void UpdateHeaderAndRecordLoc();void ResetMatchFile();
public://print out messagesstatic int (*matchfile_printf)(const char* format,... ) ;static void SetPrintFunction(int (*printf_func)(const char* format,... ));static void GetRelativePath(const char* path1, const char* path2, char* relative_path);static void SetMultiThreadMode(int multi_thread)	{	multi_thread_mode = multi_thread;			}static void SetFileTitleMode(int use_title)			{	file_title_mode = use_title;				}static void SetRecordReservation(int num)			{	record_reservation = (num > 1? num : 1);	}
public:MatchFile();MatchFile(const char* image_path, int guided = 0);~MatchFile();int IsValid(){return _fid >0;}int IsMatchFileOfImage(const char* fullpath, const char* title);
public:int  OpenMatchFile(const char* image_path, int write, int mode = 0);int  MakeWritable();int  HaveMatchRecord(const char* absolute_path);void DeleteMatchFile();void VerifyFeatureCount(int feature_count);void CloseMatchFile();void GetMatchedImageList(vector<string>& paths);void SaveSubsetMatch(vector<string>& paths, vector<int>& fc);public://read matchesint GetMatchCount(const char* image_path, int&NM, int& NF);int GetPMatch(const char* image_path, int FC, int& NM, Points<int>& matches);int GetIMatch(const char* image_path, int FC, TwoViewGeometry& tvg, Points<int>&inliers);int GetPMatchR(const char* image_path, int FC, int& NM, Points<int>& matches);int GetIMatchR(const char* image_path, int FC, TwoViewGeometry& tvg, Points<int>&inliers);
public://write matchesvoid WriteIMatch(const char* image_match, int reverse, int NM, TwoViewGeometry& tvg, Points<int>&inliers);void WritePMatch(const char* image_match, int FC, int NM, Points<int>&matches, int reverse);public:static functionsstatic void WriteIMatch(const char* image1, const char* image2, int NM, TwoViewGeometry& tvg, Points<int>&inliers);static void WriteIMatch(MatchFile* mat, const char* image1, const char* image2, int NM, TwoViewGeometry& tvg, Points<int>&inliers);static void WritePMatch(const char* image1, const char* image2, int fc1, int fc2, int NM, Points<int>& matches);static void WriteFMatch(const char* image1, const char* image2, int NF,	int * index1, int * index, float F[3][3]);///friend  struct MatchFile::MatchRecordV3;
};#endif

FeaturePoints.cpp


//	File:		FeaturePoints.cpp
//	Author:		Changchang Wu (ccwu1130@gmail)
//	Description : 
//
//  Copyright (c) 2011  Changchang Wu (ccwu1130@gmail)
//
//  This library 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 3 of the License, or (at your option) any later version.
//
//  This library 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.
//#include <io.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <math.h>
#include <string>
#include <fstream>
#include <algorithm>
using namespace std;#include "FeaturePoints.h"float FeatureData::gSiftDisplayScale = 6.0f;
int FeatureData::gSiftVisualStyle = 0;//
// Construction/DestructionFeatureData::FeatureData()
{_desData  = NULL;_locData  = NULL;_updated  = 0;_npoint = 0;
}FeatureData::~FeatureData()
{if (_desData) delete _desData;if (_locData) delete _locData;
}int FeatureData::ReadSIFTA(const char* szFile)
{int npt=0, nd=0;ifstream is(szFile);if(!is.is_open())return 0;is>> npt >> nd;if (npt <= 0 || nd <= 0 ) {_npoint = 0;is.close();return 0;}else{ReadFeatureDataA(is, npt, 4, nd, SIFT_NAME);is.close();SetUpdated();return 1;}
}void FeatureData::ReadFeatureDataA(ifstream &is, int npt, int locDim, int desDim, int szFeatureName)
{int i, j;///_npoint = npt;_locData = new LocationData( locDim +1, npt);//one more column for z_desData = new DescriptorData(desDim, npt);LTYPE * pLoc = _locData->data();DTYPE *	pDes = _desData->data();for ( i = 0 ; i< npt; i++){if( locDim ==4){is>> *(pLoc+1); //xis>> *pLoc; //}else{is>> *pLoc; //xis>> *(pLoc+1); //y}//SIFT_LOCATION_NEWpLoc[0] += 0.5f; pLoc[1] += 0.5f; pLoc[2] = 0;pLoc+=3;if (locDim ==4){is>> pLoc[0];is>> pLoc[1];pLoc[1] = - pLoc[1];//flip the anglepLoc+=2; }else{is>> *pLoc++;is>> *pLoc++;is>> *pLoc++;}for ( j = 0 ; j< desDim; j++){unsigned int value;is >> value;*pDes++ = value;}}
}void FeatureData::CopyToFeatureData(FeatureData &fd) 
{if(getFeatureNum()>0){fd.ResizeFeatureData(getFeatureNum(), getLocationData().ndim(), 128);fd.getLocationData() = getLocationData();fd.getDescriptorData() = getDescriptorData();//memcpy(fd.getLocationData().data(), getLocationData().data(), getLocationData().bsize());//memcpy(fd.getDescriptorData().data(), getDescriptorData().data(), getDescriptorData().bsize());}
}void FeatureData::FlipLocation(float imheight)
{if(_locData == NULL) return;LTYPE * feature; if(_locData->ndim()==5){for (int i = 0 ; i< _locData->npoint();i++){feature = _locData->getpt(i);feature[1] = imheight - feature[1];}}else if(_locData->ndim()==6){for (int i = 0 ; i< _locData->npoint();i++){feature = _locData->getpt(i);
//	SIFT_LOCATION_NEWfeature[1] = imheight - feature[1];feature[4] = - feature[4];}}
}void FeatureData::ReleaseFeatureData()
{if (_locData ) delete _locData;if (_desData ) delete _desData;_locData = NULL;_desData = NULL;_npoint = 0;
}void FeatureData::SetFeatureClip(FeatureData&src, int nsf, int index[], int subset)
{ReleaseFeatureData();if(subset){if(src._locData) _locData = new LocationData(src.getLocationData(), index, nsf);if(src._desData) _desData = new DescriptorData(src.getDescriptorData(), index, nsf);}else{FeatureData fd2;fd2.SetFeatureClip(src, nsf, index, 1);ResizeFeatureData(nsf, src._locData->width(), src._desData->width());getLocationData() = fd2.getLocationData();getDescriptorData() = fd2.getDescriptorData();}SetUpdated();
}void FeatureData::offsetFeatures(int ox, int oy)
{if(_locData == NULL) return;LTYPE dox = (LTYPE) ox, doy = (LTYPE) oy;LTYPE * feature;for (int i = 0 ; i< _locData->npoint();i++){feature = _locData->getpt(i);feature[0] =  feature[0]  + dox ;feature[1] =  feature[1]  + doy;}
}void FeatureData::	saveSIFTA(const char* szFile, const int nDesDim)
{if(_locData == NULL) return ;int n = _locData->npoint();if(n <=0) return;ofstream out(szFile);out << n << " " << nDesDim <<"\n";//for(int i = 0; i < n; i++){LTYPE * loc = _locData->getpt(i);unsigned char * des = _desData->getpt(i);out << loc[1] << " " << loc[0] << " " << loc[3] << " " << loc[4] << endl;for(int k = 0; k < nDesDim; k ++) {out<< ((unsigned int)des[k])<<" ";if ( (k+1)%20 == 0 ) out<<endl; }out<<endl;}
}void FeatureData::saveSIFTB2(const char* szFile)
{int i,j, sift_eof = SIFT_EOF;sift_fileheader_v2 sfh;int fd = _open(szFile, _O_BINARY|_O_CREAT|_O_WRONLY|_O_TRUNC,_S_IREAD |_S_IWRITE);if(fd<0) return;///sfh.szFeature=SIFT_NAME;sfh.szVersion=  SIFT_VERSION_4;sfh.npoint  = _locData->npoint();sfh.nLocDim = _locData->ndim();sfh.nDesDim = _desData->ndim();_write(fd, &sfh, sizeof(sfh));LTYPE * lp;DTYPE * dp;unsigned char* fph; float  *fp;unsigned char * ucp;int Max, MemNum;lp =  _locData->data();MemNum = sfh.nDesDim * sfh.npoint;Max = sfh.npoint*sfh.nLocDim;fph= new unsigned char[MemNum]; //MemCollect::Malloc(MemNum);fp = (float*) fph;for( i = 0; i < sfh.npoint; i++){lp = (*_locData)[i];for(j=0;j<sfh.nLocDim;j++){*fp++ = (float) *lp++;}}_write(fd,fph,sizeof(float)*Max);dp = _desData->data();Max = sfh.npoint*sfh.nDesDim;ucp = (unsigned char*) fph;for( i = 0; i < sfh.npoint; i++){dp = (*_desData)[i];for(j=0;j<sfh.nDesDim;j++,dp++){*ucp++ = *dp;}}_write(fd,fph,sizeof(unsigned char)*Max);_write(fd,&sift_eof, sizeof(int));_close(fd);
}int FeatureData::ReadSIFTB(const char* szFile)
{int name, version, npoint, nLocDim, nDesDim, sift_eof, sorted = 0;int fd = _open(szFile, _O_BINARY|_O_RDONLY,_S_IREAD);if (fd<0) return 0;///_read(fd, &name, sizeof(int));_read(fd, &version, sizeof(int));if(IsValidFeatureName(name) && IsValidVersionName(version)){//version 2 file_read(fd, &npoint, sizeof(int));_read(fd, &nLocDim, sizeof(int));_read(fd, &nDesDim, sizeof(int));if(npoint>0 && nLocDim >0 && nDesDim==128){ResizeFeatureData(npoint,nLocDim,nDesDim);_read(fd,_locData->data(), nLocDim *npoint*sizeof(float));_read(fd,_desData->data(), nDesDim*npoint*sizeof(unsigned char));_read(fd,&sift_eof,sizeof(int));//assert(sift_eof == SIFT_EOF);_close(fd);_locData->_file_version = version;SetUpdated();
#ifdef DEBUG_DESCRIPTOR_BUGunsigned char * pb = desData->data();int bad_descriptor_count = 0;for(int i = 0; i < npoint; ++i, pb+=128){int good_descriptor = 0;for(int j = 0; j < 128; ++j){if(pb[j]!=45){good_descriptor = 1;break;}}if(good_descriptor==0) bad_descriptor_count++;}if(bad_descriptor_count) printf("xxxxxx %d bad descriptor xxxxxx\r\n", bad_descriptor_count);
#endif}else{ResizeFeatureData(0, 0, 0);_close(fd);return 0;}return 1;}else {_close(fd);return 0;}
}int FeatureData::ReadSIFTB_DES(const char* szFile, int fmax)
{sift_fileheader_v2 sfh;	int fd = _open(szFile, _O_BINARY|_O_RDONLY,_S_IREAD);if (fd<0) return 0;///_read(fd, &sfh, sizeof(sfh));int npoint = fmax > 0 ? min(sfh.npoint, fmax) : sfh.npoint;if(_desData)_desData->resize(sfh.nDesDim, npoint);else_desData = new DescriptorData(sfh.nDesDim, npoint);_lseek(fd, sfh.nLocDim *sfh.npoint*sizeof(float), SEEK_CUR);_read(fd,_desData->data(), sfh.nDesDim*npoint*sizeof(unsigned char));_close(fd);return 1;
}int FeatureData::ReadSIFTB_LOC(const char* szFile, float * buf, int nmax )
{sift_fileheader_v2 sfh;	int fd = _open(szFile, _O_BINARY|_O_RDONLY,_S_IREAD);if (fd<0) return 0;///_read(fd, &sfh, sizeof(sfh));nmax = min(nmax, sfh.npoint);_read(fd, buf, sfh.nLocDim *sfh.npoint*sizeof(float));_close(fd);return nmax;
}int FeatureData::ReadSIFTB_DES(const char* szFile, unsigned char * buf, int nmax )
{sift_fileheader_v2 sfh;	int fd = _open(szFile, _O_BINARY|_O_RDONLY,_S_IREAD);if (fd<0) return 0;///_read(fd, &sfh, sizeof(sfh));nmax = min(nmax, sfh.npoint);_lseek(fd, sfh.nLocDim *sfh.npoint*sizeof(float), SEEK_CUR);_read(fd, buf, sfh.nDesDim* nmax*sizeof(unsigned char));_close(fd);return nmax;
}int FeatureData::ReadSIFTA_DES(const char* szFile, unsigned char * buf, int nmax )
{FeatureData fd;fd.ReadSIFTA(szFile);if(fd.getLocationData().getpt(0)[3] < fd.getLocationData().getpt(fd.getFeatureNum() -1)[3]){//sortfd.SortSIFT();}nmax = min(nmax, fd.getFeatureNum());if(nmax > 0){memcpy(buf, fd.getDescriptorData().data(), nmax * 128);}return nmax;
}int FeatureData::ReadSIFTB(const char* szFile, float * locbuf, unsigned char * desbuf, int nmax)
{sift_fileheader_v2 sfh;	int fd = _open(szFile, _O_BINARY|_O_RDONLY,_S_IREAD);if (fd<0) return 0;///_read(fd, &sfh, sizeof(sfh));nmax = min(nmax, sfh.npoint);_read(fd, locbuf, sfh.nLocDim *sfh.npoint*sizeof(float));_read(fd, desbuf, sfh.nDesDim* nmax*sizeof(unsigned char));_close(fd);return nmax;}int FeatureData::ReadSIFTB_LOC(const char* szFile)
{sift_fileheader_v2 sfh;	int fd = _open(szFile, _O_BINARY|_O_RDONLY,_S_IREAD);if (fd<0) return 0;///_read(fd, &sfh, sizeof(sfh));if(IsValidFeatureName(sfh.szFeature) && IsValidVersionName(sfh.szVersion)){//version 2 fileif(sfh.npoint>0 && sfh.nLocDim >0 && sfh.nDesDim==128){_npoint = sfh.npoint;ResizeLocationData(sfh.npoint,sfh.nLocDim);if(_locData->data()){_read(fd,_locData->data(), sfh.nLocDim *sfh.npoint*sizeof(float));_locData->_file_version  = sfh.szVersion;}else{printf("ERROR: ReadSIFTB_LOC allocatoin faled\r\n");}_close(fd);SetUpdated();}else{ResizeFeatureData(0, 0, 0);_close(fd);return 0;}return 1;}else{_npoint = 0;_close(fd);return 0;}}int FeatureData::appendSIFTB(const char* szFile, int pos)
{int npoint, nLocDim, nDesDim;int fd = _open(szFile, _O_BINARY|_O_RDONLY,_S_IREAD);if (fd<0) return pos;//////_read(fd, &npoint, sizeof(int)); _read(fd, &nLocDim, sizeof(int)); if(npoint == SIFT_NAME && IsValidVersionName(nLocDim)){_read(fd, &npoint, sizeof(int)); _read(fd, &nLocDim, sizeof(int)); //assert(nLocDim == 5);_read(fd, &nDesDim, sizeof(int)); //assert(nDesDim == 128);_read(fd,(float*)_locData->data()+ pos*nLocDim, nLocDim*npoint*sizeof(float));_read(fd,(unsigned char*)_desData->data()+ pos*nDesDim, nDesDim*npoint*sizeof(unsigned char));}_close(fd);return pos + npoint;
}int FeatureData::OpenSeekSIFT(const char *featurefile,int&npoint, int&ndim)
{sift_fileheader_v2 sfh={SIFT_NAME,SIFT_VERSION_4,0,0,0};int fd = _open(featurefile, _O_BINARY|_O_RDONLY);if (fd<0) return 0;///_read(fd, &sfh, sizeof(sfh));if(	sfh.szFeature != SIFT_NAME || 	!IsValidVersionName(sfh.szVersion)||sfh.npoint <=0 || 		sfh.nLocDim<=0 || 		sfh.nDesDim !=128){// incorrect version_close(fd);return 0;}else{_lseek(fd, sfh.nLocDim*sfh.npoint*sizeof(float), SEEK_CUR);npoint = sfh.npoint;ndim = sfh.nDesDim;return fd;}
}void FeatureData::SaveLocationFile(const char* szFeatureFile)
{int nf = _locData->npoint();if(nf ==0) return;
//	struct _stat buf;
//	if(_stat(szFeatureFile, &buf)!=-1) return; //already savedvector<float > loc(nf*2);float * p = &loc[0];int fid = _open(szFeatureFile, _O_CREAT|_O_BINARY|_O_WRONLY|_O_TRUNC,_S_IREAD | _S_IWRITE);if(fid ==-1) return;for(int i = 0; i < nf ; i++){*p++ =(float) _locData->getpt(i)[0];*p++ =(float) _locData->getpt(i)[1];}_write(fid, &loc[0], loc.size()*sizeof(float));_close(fid);
}	void FeatureData::SaveDescriptorFile(const char* szFeatureFile)
{int fid = _open(szFeatureFile, _O_CREAT|_O_BINARY|_O_WRONLY|_O_TRUNC,_S_IREAD | _S_IWRITE);int nf = _desData->npoint();DTYPE * dp = _desData->data();_write(fid, dp, nf*128*sizeof(unsigned char));_close(fid);
}void FeatureData::ConvertA2B(const char* szFile)
{//LET'S AUTOMATICALLY GENERATE A BINARY VRSION//make sure it is the same format of siftdouble normal = 0;DTYPE*  d = _desData->data();for(int i = 0; i < 128; i++) normal += d[i] * d[i];normal = sqrt(normal);if ( normal < 400){//__asm int 03h;for(int i = 0; i < _desData->npoint(); i++){d = _desData->getpt(i);normal = 0;for(int j = 0; j < 128; j ++){normal += d[j]*d[j];}normal = 512.0/sqrt(normal);for(int k = 0; k < 128; k++){d[k] = (DTYPE) floor (normal * d[k] +0.5);}}for(int j = 0; j < _locData->npoint(); j++){LTYPE* l= _locData->getpt(j);LTYPE temp = l[0];l[0] = l[1];l[1] = temp;}}int len = strlen(szFile);if(len>10 && strcmp(szFile + len -10, ".sift.sift")==0){char szNewFile[260];strcpy(szNewFile, szFile);szNewFile[len-5] = 0;saveSIFTB2(szNewFile);remove(szFile);}else if(len >5 && strcmp(szFile + len - 5, ".sift") ==0){saveSIFTB2(szFile);}}int FeatureData::ValidateIndex(int index[], int n)
{int num = getFeatureNum();for (int i = 0 ; i < n ; i ++){if( index[i]>= num || index[i] < 0){return 0;}}return 1;
}void FeatureData::SortSIFT()
{int i, j, nf = getFeatureNum();if(nf ==0 || _locData == NULL ||  _desData == NULL) return;LTYPE * loc = _locData->data();DTYPE * des = _desData->data();vector<int> orderv(nf);vector<LTYPE> sizes(nf);int* order = &orderv[0];LTYPE* size = &sizes[0];//bubble sort for( i = 0; i < nf; i++) order[i] = nf - i - 1;for( i = 0; i < nf; i++) size[i] = loc[5 * (nf - i -1) + 3];for( i =0; i < nf; i ++){int swaped = 0;for( j = nf -1 ; j > i; j--){if(size[j] > size[j-1]){//sizeLTYPE dtemp = size[j];size[j] = size[j-1];size[j-1] = dtemp;//orderint itemp = order[j];order[j] = order[j-1];order[j-1] = itemp;swaped = 1;}}if(!swaped) break;}_locData->reorder(order);_desData->reorder(order);//printf("\r\n");
}void FeatureData::ShrinkLocationData(int ndim, int npoint)
{if(_locData) _locData->shrink(ndim, npoint < 0? _locData->npoint() : min(npoint, _locData->npoint()));
}

MatchFile.cpp


//	File:		MatchFile.cpp
//	Author:		Changchang Wu (ccwu1130@gmail)
//	Description : 
//
//  Copyright (c) 2011  Changchang Wu (ccwu1130@gmail)
//
//  This library 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 3 of the License, or (at your option) any later version.
//
//  This library 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.
//#include "stdio.h"
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <algorithm>
#include <iomanip>
#include <io.h>
#include <assert.h>
using namespace std;
#include "MatchFile.h"//
int MatchFile::multi_thread_mode  = 0;
int MatchFile::file_title_mode = 0;
int MatchFile::num_match_verification = 1;
int	MatchFile::delay_header_update = 0;
int	MatchFile::record_reservation = 20;//function for printing out messages.
int (*MatchFile::matchfile_printf)(const char* format,... ) = ::printf;
#define printf matchfile_printf#ifdef _WIN64
#define _lseek _lseeki64
#endif#ifdef WIN32
#define PATH_SLASH '\\'
#define PATH_SLASH_X '/'
#define PATH_PARENT "..\\"
#else
#define PATH_SLASH '/'
#define PATH_SLASH_X '\\'
#define PATH_PARENT "../"
#endifvoid MatchFile::SetPrintFunction(int (*printf_func)(const char* format,... ))
{matchfile_printf = printf_func;
}MatchFile::MatchFile()
{_fid = 0;_header.definition_size = 0;_header.file_count = 0;_header.feature_count = 0;_recordloc_unchanged = 0;_header_changed = 0;_opened_for_write = 0;_mutex = NULL;_matchfile_mode= 0;_title = _filepath; 
}MatchFile::~MatchFile()
{CloseMatchFile();
}MatchFile::MatchFile(const char* image_path, int mode)
{_fid = 0;_mutex = NULL;_header.definition_size = 0;_header.file_count = 0;_header.feature_count = 0;_recordloc_unchanged = 0;_header_changed = 0;OpenMatchFile(image_path, 0, mode);
}int MatchFile::IsMatchFileOfImage(const char* fullpath, const char* title)
{if(file_title_mode && title) return strcmp(_title, title) == 0;else return strcmp(_filepath, fullpath) == 0; 
}void MatchFile::GetMatchFilePath(char* match_path)
{strcpy(match_path, _filepath);if(_matchfile_mode == 0) strcat(match_path, ".mat");else if(_matchfile_mode == 1)strcat(match_path, ".gmat");else strcat(match_path, ".xmat");//_title = strrchr(_filepath, PATH_SLASH);if(_title == NULL) _title = _filepath;else _title++; 
}void MatchFile::GetMatchFolderPath(char* match_path)
{strcpy(match_path, _filepath);char* p = strrchr(match_path, PATH_SLASH);	p[1] = 0;
}int  MatchFile::MakeWritable()
{char match_path[MAX_PATH];//already opened for writeif(_fid <=0) return 0;if(_opened_for_write) return 1;//GetMatchFilePath(match_path);_close(_fid);_fid = _open(match_path, _O_BINARY|_O_CREAT|_O_RDWR, _S_IWRITE|_S_IREAD);if(_fid > 0){_opened_for_write = 1;return 1;}else{_opened_for_write = 0;return 0;}
}void MatchFile::VerifyFeatureCount(int feature_count)
{if(_fid <= 0 ) return ;if(_header.feature_count <= 0){//update the feature countif(feature_count > 0){_header.feature_count = feature_count;if(MakeWritable()){_lseek(_fid, 0, SEEK_SET);_write(_fid, &_header, sizeof(_header));//printf("Update feature count [%d]!\r\n", feature_count);}}}else if(feature_count > 0 && _header.feature_count != feature_count){//destroy all match record.	DeleteMatchFile();printf("Delete match record: feature changed!\r\n");}
}void MatchFile::DeleteMatchRecord(const char* pattern)
{if(_fid <= 0) return;int changed = 0;for(int i = 0; i < _match_records.size(); ++i){if(strstr(_match_records[i]->file_name, pattern)){            int NM;	RecordLoc * loc = _match_records[i];_lseek(_fid, loc->read_loc, SEEK_SET);_read(_fid, &NM, sizeof(int));if(NM == 0) continue;MakeWritable();_lseek(_fid, loc->read_loc, SEEK_SET);NM = 0;	    _write(_fid, &NM, sizeof(int));changed = 1;}}
}void MatchFile::DeleteMatchFile()
{char match_path[MAX_PATH];GetMatchFilePath(match_path);CloseMatchFile();remove(match_path);
}int  MatchFile::OpenMatchFile(const char* imagepath, int write, int mode)
{char match_path[MAX_PATH];CloseMatchFile();//_matchfile_mode = mode;///strcpy(_filepath, imagepath);GetMatchFilePath(match_path);if(!write)_fid = _open(match_path, _O_BINARY|_O_RDONLY);else _fid = _open(match_path, _O_BINARY|_O_CREAT|_O_RDWR, _S_IWRITE|_S_IREAD);if(_fid > 0) {//read file _headerint readsz = _read(_fid, (char*) (&_header), sizeof(_header));_opened_for_write = write; if( sizeof(_header) == readsz && _header.definition_size >0 && _header.definition_buf >= _header.definition_size && _header.version == MATCH_FILE_VERSION_3){assert(_header.file_count>=0);_record_definition.resize(_header.definition_buf, 0);_read(_fid, (char*) &_record_definition[0], _header.definition_size);GetRecordList();_header_changed = 0;_recordloc_unchanged = _header.definition_size;}else if (readsz > 0){printf("Unsupported MatchFile [%s]\r\n", _filepath );ResetMatchFile();if(write)UpdateHeaderAndRecordLoc();}return 1;} else {_filepath[0] = 0;return 0;}
}void MatchFile::GetRecordList()
{char * p = &_record_definition[0];_match_records.resize(_header.file_count);for(int i = 0; i < _match_records.size(); ++i){RecordLoc* rp = (RecordLoc*) p;_match_records[i] = rp;if(rp->read_loc <= 0 || rp->block_size == 0 || rp->extra_size > MAX_PATH ||(rp->fcount > 1000000 || rp->fcount < 0)){_match_records.resize(i);_header.file_count = i;_header.definition_size = (p - &_record_definition[0]);break;}else{p += sizeof(RecordLoc) + _match_records[i]->extra_size;//convert file name for different operation systemfor(char* c = rp->file_name; *c; ++c) {if (*c == PATH_SLASH_X) *c = PATH_SLASH; }}}
}void MatchFile::GetMatchedImageList(vector<string>& paths)
{char match_path[MAX_PATH];GetMatchFolderPath(match_path);string folder = match_path;paths.resize(0);for(int i = 0; i < _match_records.size(); ++i){paths.push_back(folder + _match_records[i]->file_name);}
}void MatchFile::SaveSubsetMatch(vector<string>& paths, vector<int>&fc)
{MatchFile sub;sub.OpenMatchFile(_filepath, 1, 2);sub.ResetMatchFile();int NM; Points<int> matches;TwoViewGeometry tvg;Points<int> inliers;/for(int i = 0; i < paths.size(); ++i){if(GetPMatch(paths[i].c_str(), fc[i], NM, matches)){  sub.WritePMatch(paths[i].c_str(), fc[i], NM, matches, 0);if(GetIMatch(paths[i].c_str(), fc[i], tvg, inliers)){sub.WriteIMatch(paths[i].c_str(), 0, NM, tvg, inliers);}}}
}int MatchFile::HaveMatchRecord(const char* absolute_path)
{char relative_path[MAX_PATH];GetRelativePath(absolute_path, relative_path);return GetImageIndex(relative_path) >= 0;
}int  MatchFile::GetImageIndex(const char* relative_path)
{if(file_title_mode){const char * ps = strrchr(relative_path, PATH_SLASH);ps = (ps == NULL? relative_path : ps + 1);for(int i = 0; i < _match_records.size(); i++){RecordLoc* loc = _match_records[i];const char * p = strrchr(loc->file_name, PATH_SLASH);p = (p == NULL ) ?  loc->file_name : p + 1;if(strcmp(p, ps) == 0) return i;}}else{for(int i = 0; i < _match_records.size(); i++){if(strcmp(_match_records[i]->file_name, relative_path) == 0) return i;}}return -1;
}void MatchFile::GetRelativePath(const char* path1, const char* path2, char* relative_path)
{int i = 0;while(path2[i] == path1[i] && path2[i] && path1[i]) i++;while(i > 0 && path1[i] != PATH_SLASH) i--;if( i == 0){strcpy(relative_path, path2);}else{relative_path[0] = 0;const char* p = path1 + i + 1;char * rp = relative_path;int rc1 = 0, rc2 = 0;while(*p){if(p[0] ==  PATH_SLASH && p[1] != PATH_SLASH) {strcpy(rp, PATH_PARENT);rp += 3;rc1 ++;}p++;}p = path2 + i + 1;while(*p){if(p[0] == PATH_SLASH && p[1] != PATH_SLASH) rc2 ++;p++;}if(rc1 <=1 || rc2 <=1) strcpy(rp, path2 + i + 1); else strcpy(relative_path, path2);}
}inline void MatchFile::GetRelativePath(const char* image_match, char* relative_path)
{if(file_title_mode){const char* pslash = strrchr(image_match, PATH_SLASH);if(pslash) strcpy(relative_path, pslash + 1);else       strcpy(relative_path, image_match); }else{GetRelativePath(_filepath, image_match, relative_path);}
}void MatchFile::MoveRecordToEnd(int i)
{if(i >= _header.file_count - 1 || i < 0 || _header.file_count < 2) return;char* p0 = (char*) _match_records[0];char* p1 = (char*) _match_records[i];char* p2 = (char*) _match_records[i + 1];size_t loc1 = p1 - p0;size_t loc2 = p2 - p0;int len = loc2 - loc1;vector<char> temp;temp.insert(temp.begin(), p1, p2);_record_definition.erase(_record_definition.begin() + loc1, _record_definition.begin() + loc2);//_record_definition.insert(_record_definition.end(), temp.begin(), temp.begin() + len);_record_definition.insert(_record_definition.begin() + _header.definition_size - len, temp.begin(), temp.begin() + len);_recordloc_unchanged = min(_recordloc_unchanged, loc1);GetRecordList();if(i == 0){_header.definition_buf += len;_header_changed = 1;}else{_match_records[i -1]->trash_size += len;}//_match_records[_header.file_count -1]->read_loc = _match_records[_header.file_count - 2]->read_loc + _match_records[_header.file_count - 2]->block_size;printf("MoveRecordToEnd [%s]\r\n", _filepath );
}int  MatchFile::AddImageMatch(const char* relative_path)
{//see if the name buffer has enough space..int slen = (strlen(relative_path) / 4  + 1) * 4; int elen = slen - 4;int rlen = elen + sizeof(RecordLoc);//_header_changed = 1;//if(_header.file_count == 0){_header.version = MATCH_FILE_LATEST_VERSION;_header.file_count = 1;_header.definition_buf = max(20, record_reservation) * (MAX_PATH + sizeof(RecordLoc));_record_definition.resize(_header.definition_buf, 0);	_header.definition_size = rlen;RecordLoc* loc = (RecordLoc*) (&_record_definition[0]);_match_records.resize(1);_match_records[0] = loc;strcpy(loc->file_name, relative_path);loc->extra_size = elen;loc->trash_size = 0;loc->block_size = 0;loc->read_loc = sizeof(FileHeader) + _header.definition_buf;// should write the _header now?return 0;}else if(_header.definition_size + rlen < _header.definition_buf){RecordLoc* rec = (RecordLoc*) (&_record_definition[_header.definition_size]);rec->block_size = 0;rec->extra_size = elen;rec->read_loc = _match_records.back()->read_loc + _match_records.back()->block_size;strcpy(rec->file_name, relative_path);_match_records.push_back(rec);_header.definition_size += rlen ;_header.file_count++;return _header.file_count -1;}else {//size_t szr = max(((int) (_match_records.size() + 1)), record_reservation) * (MAX_PATH + sizeof(RecordLoc));int extra_needed = rlen + _header.definition_buf;int match_move_needed = 0;int extra_space = 0;// move the match datawhile(extra_space < extra_needed){RecordLoc* loc = _match_records[match_move_needed];extra_space+= (loc->block_size + loc->trash_size);match_move_needed++;}assert(match_move_needed > 0);//read match data that needs to movevector<char> read_buffer(extra_space);char* pbuf = &read_buffer[0];_lseek(_fid, _match_records[0]->read_loc, SEEK_SET);_read(_fid, &read_buffer[0], extra_space);//write match data to the end of fileint match_write_location = _match_records.back()->read_loc + _match_records.back()->block_size;_lseek(_fid, match_write_location, SEEK_SET);for(int i = 0; i < match_move_needed; i++){RecordLoc* loc = _match_records[i];_write(_fid, pbuf, loc->block_size);pbuf += (loc->block_size + loc->trash_size);loc->read_loc = match_write_location;match_write_location += loc->block_size;loc->trash_size = 0;}//organize file namesint definition_move = ((char*)_match_records[match_move_needed]) - &_record_definition[0];if(match_move_needed < _header.file_count){//reorganize strings..move several string to the endvector<char> temp = _record_definition;std::copy(temp.begin() + definition_move, temp.begin() + _header.definition_size, _record_definition.begin() );std::copy(temp.begin(), temp.begin() + definition_move, _record_definition.begin() + _header.definition_size - definition_move);}_header.definition_buf = _header.definition_buf * 2 + rlen;_record_definition.resize(_header.definition_buf, 0);GetRecordList();RecordLoc* rec = (RecordLoc*) (&_record_definition[_header.definition_size]);rec->read_loc = match_write_location;rec->trash_size = 0;rec->block_size = 0;rec->extra_size = elen;_match_records.push_back(rec);strcpy(rec->file_name, relative_path);//write all previous data to file_lseek(_fid, sizeof(_header), SEEK_SET);_write(_fid, &_record_definition[0], _header.definition_size);_header.definition_size += rlen;_header.file_count++;_recordloc_unchanged = 0;return _header.file_count -1; }
}void MatchFile::ResetMatchFile()
{_header.file_count = 0;_header.definition_size = 0;_header.definition_buf = 0;_header.version = MATCH_FILE_LATEST_VERSION;_match_records.resize(0);_record_definition.resize(0);_recordloc_unchanged = 0;_header_changed = 1;
}void MatchFile::CloseMatchFile()
{if(_fid > 0) {if(_opened_for_write && delay_header_update)	UpdateHeaderAndRecordLoc();ResetMatchFile();_close(_fid);_fid = 0;_opened_for_write = 0; _matchfile_mode = 0;}
}void MatchFile::WriteFMatch(const char* image1, const char* image2,int NF, int* index1, int* index2, float F[3][3])
{if(index1 == NULL || index2 == NULL) return;int* indices [2] = {index1, index2};Points<int> inliers(indices, NF, 2);TwoViewGeometry tvg(NF, F);WriteIMatch(image1, image2, 0, tvg, inliers);}void MatchFile::WriteIMatch(MatchFile* mat, const char* image1, const char* image2, int NM, TwoViewGeometry& tvg, Points<int>&inliers)
{if(mat == NULL || ! mat->IsValid()){WriteIMatch(image1, image2, NM, tvg, inliers);}else 	if(_stricmp(mat->_filepath, image1) ==0){if(mat->MakeWritable()){mat->WriteIMatch(image2, 0, NM, tvg, inliers);}MatchFile file2;if(file2.OpenMatchFile(image2, 1)){file2.WriteIMatch(image1, 1, NM, tvg, inliers);}}else if(_stricmp(mat->_filepath, image2) == 0){if(mat->MakeWritable()){mat->WriteIMatch(image1, 1, NM, tvg, inliers);}MatchFile file1;if(file1.OpenMatchFile(image1, 1)){file1.WriteIMatch(image2, 0, NM, tvg, inliers);}}}void MatchFile::WriteIMatch(const char* image1, const char* image2, int NM, TwoViewGeometry& tvg, Points<int>&inliers)
{MatchFile file1, file2;if(file1.OpenMatchFile(image1, 1)){file1.WriteIMatch(image2, 0, NM, tvg, inliers);file1.CloseMatchFile();}if(file2.OpenMatchFile(image2, 1)){file2.WriteIMatch(image1, 1, NM, tvg, inliers);file2.CloseMatchFile();}
}void MatchFile::WriteIMatch(const char* image_match, int reverse, int NM,TwoViewGeometry& tvg, Points<int>&inliers)
{int index, fnm, szmin;char relative_path[MAX_PATH];if(image_match == NULL || image_match[0] == 0) return;GetRelativePath(image_match, relative_path);index = GetImageIndex(relative_path);if(index < 0) return;RecordLoc* loc = _match_records[index];MatchRecordV3 rec;assert(loc->read_loc > 0);//read in the number of if(num_match_verification || NM == 0){_lseek(_fid, loc->read_loc, SEEK_SET);_read(_fid, &fnm, sizeof(int));NM = fnm;}else{_lseek(_fid, loc->read_loc + sizeof(int), SEEK_SET);}assert(tvg.NF<=0 || tvg.NE==0 || tvg.NF == tvg.NE);szmin = (1 + (NM + tvg.NF) * 2 )* sizeof(int) + sizeof(rec);if(szmin > loc->block_size) //this is unlikey to happen, right?{//not enough size.size_t offset = ((char*)loc) - ((char*)_match_records[0]);_recordloc_unchanged = min (_recordloc_unchanged,  offset);if(loc->block_size ==0 || index == _header.file_count - 1){int bs = sizeof(MatchRecordV3) +  max(NM + tvg.NF, 8) * sizeof(int) * 4;//last one in the fileloc->block_size = bs;}else	if(szmin > loc->block_size + loc->trash_size){// not enough space?MoveRecordToEnd(index);index = _header.file_count -1;loc = _match_records[index];loc->block_size = sizeof(MatchRecordV3) +  max(NM + tvg.NF, 8) * sizeof(int) * 4;}else{loc->block_size += loc->trash_size;loc->trash_size = 0;}if(!delay_header_update) {printf("Reallocate space fo record %d\r\n", index);UpdateHeaderAndRecordLoc();_lseek(_fid, loc->read_loc + sizeof(int), SEEK_SET);}}////Write inlier pairsif(reverse == 0){rec.tvg.SetGeometry(tvg);//write inlier match record_write(_fid, &rec, sizeof(rec));_lseek(_fid, NM * sizeof(int) * 2, SEEK_CUR);if(tvg.NF >0){_write(_fid, inliers[0], sizeof(int) * tvg.NF);_write(_fid, inliers[1], sizeof(int) * tvg.NF);}}else{rec.tvg.SetGeometryR(tvg);;//write inlier match record_write(_fid, &rec, sizeof(rec));_lseek(_fid, NM * sizeof(int) * 2, SEEK_CUR);if(tvg.NF > 0){_write(_fid, inliers[1], sizeof(int) * tvg.NF);_write(_fid, inliers[0], sizeof(int) * tvg.NF);}}
}void MatchFile::WritePMatch(const char* image1, const char* image2, int fc1, int fc2, int NM, Points<int>& matches)
{MatchFile file1, file2;if(file1.OpenMatchFile(image1, 1)){file1.WritePMatch(image2, fc2, NM, matches, 0);file1.CloseMatchFile();}if(file2.OpenMatchFile(image2, 1)){file2.WritePMatch(image1, fc1, NM, matches, 1);file2.CloseMatchFile();}
}void MatchFile::WritePMatch(const char* image_match, int FC, int NM, Points<int>&matches, int reverse)
{int index;char relative_path[MAX_PATH];if(image_match == NULL || image_match[0] == 0) return;GetRelativePath(image_match, relative_path);index = GetImageIndex(relative_path);if(index < 0) index = AddImageMatch(relative_path);RecordLoc* loc = _match_records[index];loc->fcount = FC;assert(loc->read_loc > 0);size_t offset = ((char*)loc) - ((char*)_match_records[0]);_recordloc_unchanged = min (_recordloc_unchanged, offset); if(loc->block_size ==0 || index == _header.file_count - 1){int bs = sizeof(MatchRecordV3) +  max(NM, 8) * sizeof(int) * 6;//last one in the fileloc->block_size = bs;}else{int bsmin = sizeof(MatchRecordV3) + max(NM, 0) * sizeof(int) * 4;if(bsmin > loc->block_size){if(bsmin > loc->block_size + loc->trash_size){// not enough space?MoveRecordToEnd(index);index = _header.file_count -1;loc = _match_records[index];loc->block_size = sizeof(MatchRecordV3) + max(NM, 8) * sizeof(int) * 6;}else{loc->block_size += loc->trash_size;loc->trash_size = 0;}}}//update file _header and locsif(!delay_header_update){UpdateHeaderAndRecordLoc();}MatchRecordV3 rec;//write pmatch_lseek(_fid, loc->read_loc, SEEK_SET);//write match record_write(_fid, &NM, sizeof(int));_write(_fid, &rec, sizeof(rec));//write matched pairsif(NM <=0) return;if(reverse == 0){_write(_fid, matches[0], sizeof(int) * NM);_write(_fid, matches[1], sizeof(int) * NM);}else{_write(_fid, matches[1], sizeof(int) * NM);_write(_fid, matches[0], sizeof(int) * NM);}
}void MatchFile::UpdateHeaderAndRecordLoc()
{//the file _headerif(_header_changed){_lseek(_fid, 0, SEEK_SET);//VERIFY(_header.version == MATCH_FILE_LATEST_VERSION);_write(_fid, &_header, sizeof(_header));_header_changed = 0;}if(_header.definition_size > _recordloc_unchanged){//recordloc_lseek(_fid, sizeof(_header) + _recordloc_unchanged, SEEK_SET);_write(_fid, &_record_definition[_recordloc_unchanged], _header.definition_size - _recordloc_unchanged);_recordloc_unchanged = _header.definition_size;}
}///
int MatchFile::GetPMatch(const char* image_path, int FC, int& NM, Points<int>& matches)
{int index;char relative_path[MAX_PATH];GetRelativePath(image_path, relative_path);index = GetImageIndex(relative_path);if(index < 0){NM = 0;matches.resize(0, 0);return 0;}else{RecordLoc * loc = _match_records[index];if(loc->fcount == FC){_lseek(_fid, loc->read_loc, SEEK_SET);_read(_fid, &NM, sizeof(int));_lseek(_fid, sizeof(MatchRecordV3), SEEK_CUR);if(NM >0 && NM <= FC){matches.resize(NM, 2);_read(_fid, matches[0], 2 * NM * sizeof(int));}else{matches.resize(0, 0);NM = 0;}return NM;} else {NM = 0;matches.resize(0, 0);return 0;}}}int MatchFile::GetPMatchR(const char* image_path, int FC, int& NM, Points<int>& matches)
{int index;char relative_path[MAX_PATH];GetRelativePath(image_path, relative_path);index = GetImageIndex(relative_path);if(index < 0){NM = 0;matches.resize(0, 0);return 0;}else{RecordLoc * loc = _match_records[index];if(loc->fcount == FC){_lseek(_fid, loc->read_loc, SEEK_SET);_read(_fid, &NM, sizeof(int));_lseek(_fid, sizeof(MatchRecordV3), SEEK_CUR);if(NM > 0 && NM <= FC){matches.resize(NM, 2);_read(_fid, matches[1],  NM * sizeof(int));_read(_fid, matches[0],  NM * sizeof(int));}else{matches.resize(0, 0);}return NM;} else {NM = 0;matches.resize(0, 0);return 0;}}}int MatchFile::	GetMatchCount(const char* image_path, int&NM, int& NF)
{int index;char relative_path[MAX_PATH];GetRelativePath(image_path, relative_path);index = GetImageIndex(relative_path);if(index < 0 ){NM = NF = 0;return 0;}else{int counts[3];RecordLoc * loc = _match_records[index];_lseek(_fid, loc->read_loc, SEEK_SET);_read(_fid, counts, sizeof(counts));NM = counts[0];	NF = counts[2];return 1;}}int MatchFile::GetIMatch(const char* image_path, int FC, TwoViewGeometry& tvg,  Points<int>&inliers)
{int index;char relative_path[MAX_PATH];GetRelativePath(image_path, relative_path);index = GetImageIndex(relative_path);if(index < 0 ){tvg.ResetGeometry();inliers.resize(0, 0);return 0;}else{RecordLoc * loc = _match_records[index];if(loc->fcount != FC){tvg.ResetGeometry();inliers.resize(0, 0);printf("# features changed: [%s][%d->%d]!!!\r\n", image_path, loc->fcount, FC);return 0;}else{int NM;MatchRecordV3 rec;_lseek(_fid, loc->read_loc, SEEK_SET);_read(_fid, &NM, sizeof(int));_read(_fid, &rec, sizeof(rec));if(NM > loc->fcount || NM < 0){tvg.ResetGeometry();inliers.resize(0, 0);printf("ERROR: incorrect matching count [%d, %d]\r\n", NM, loc->fcount);return 0;}else   if(NM == 0 || rec.version != MatchFile::MATCH_RECORD_V3 || rec.tvg.NF > loc->fcount){tvg.ResetGeometry();inliers.resize(0, 0);//printf("#--BAD matching record---###\r\n");return 0;}else{//tvg.SetGeometry(rec.tvg);//if(tvg.NF > 0){_lseek(_fid, NM * 2 * sizeof(int), SEEK_CUR);inliers.resize(tvg.NF, 2);_read(_fid, inliers[0], 2 * tvg.NF * sizeof(int));}else{inliers.resize(0, 0);}return NM;}}}}int MatchFile::GetIMatchR(const char* image_path, int FC, TwoViewGeometry& tvg,  Points<int>&inliers)
{int index;char relative_path[MAX_PATH];GetRelativePath(image_path, relative_path); index = GetImageIndex(relative_path);if(index < 0 ){tvg.ResetGeometry();inliers.resize(0, 0);return 0;}else{RecordLoc * loc = _match_records[index];if(loc->fcount != FC){tvg.ResetGeometry();inliers.resize(0, 0);printf("# feature changed: [%s][%d->%d]!!!\r\n", image_path, loc->fcount, FC);return 0;}else{int NM;MatchRecordV3 rec;_lseek(_fid, loc->read_loc, SEEK_SET);_read(_fid, &NM, sizeof(int));_read(_fid, &rec, sizeof(rec));if(NM > loc->fcount || NM < 0){tvg.ResetGeometry();inliers.resize(0, 0);printf("ERROR: incorrect matching count [%d, %d]\r\n", NM, loc->fcount);return 0;}else if(NM == 0  || rec.version != MatchFile::MATCH_RECORD_V3 || rec.tvg.NF > loc->fcount){tvg.ResetGeometry();inliers.resize(0, 0);//printf("#--BAD matching record---###\r\n");return 0;}else{///tvg.SetGeometryR(rec.tvg);//if(tvg.NF > 0){_lseek(_fid, NM * 2 * sizeof(int), SEEK_CUR);inliers.resize(tvg.NF, 2);_read(_fid, inliers[1],  tvg.NF * sizeof(int));_read(_fid, inliers[0],  tvg.NF * sizeof(int));}else{inliers.resize(0, 0);}return NM;}}}
}

 

然后自己随便加一个头文件,尝试读取.mat

main.cpp

/*
error C4996: '_open': This function or variable may be unsafe. Consider using _sopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.error C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.根据提示,use _CRT_SECURE_NO_DEPRECATE
在项目|属性|配置属性|C/C++|命令行|附加选项,加入{/D "_CRT_SECURE_NO_DEPRECATE"}(注:加入中括号中完整的内容)
或者在项目|属性|配置属性|C/C++|预处理器|预处理定义中加入 _CRT_SECURE_NO_DEPRECATE
*/
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <cmath>
using namespace std;#include "FeaturePoints.h"
#include "MatchFile.h"int main()
{//MatchFile match;//int flag = match.OpenMatchFile("D:\\code\\SFM\\ImageDataset_SceauxCastle-master\\images\\100_7100", 0, 0);return 0;
}

 

更多推荐

关于VisualSFM中的.sift和.mat文件详细信息(包括读、存等)

本文发布于:2024-03-15 10:37:46,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1738707.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:详细信息   文件   VisualSFM   sift   mat

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!