三维重建:多点透视cvSolvePNP的替代函数(Code)
原函数是这样的:
void rec3D::reconstruct3D(const vector<Point2f>& image_points, Mat& rvecs, Mat& tvecs)
{
print_Matf( cam.intrinsic_Mat );
print_Matf( cam.disCoeff );
print_VecPointf(image_points);
print_VecPointf(cam.object_points ); cv::solvePnP(cam.object_points , image_points , cam.intrinsic_Mat , cam.disCoeff , rvecs , tvecs , false , CV_P3P); print_Matf( cam.intrinsic_Mat );
print_Matf( cam.disCoeff );
print_VecPointf(image_points);
print_VecPointf(cam.object_points );
print_Matf( rvecs );
print_Matf( tvecs );
}
当然,函数后面的测试时没有机会调用的,而函数前面的测试则是准确无误的....
1. 关于多点投射的函数cv::solvePnP
参考链接:http://blog.csdn.net/abc20002929/article/details/8520063
Wiki链接:CV照相机 标定和三维重建 详细资料
计算多点透视问题,有离散的方法和解方程的方法,分别为cvPOSIT 和SolePnP。
应用场景:给定物体3D点集与对应的图像2D点集,之后进行姿态计算(即求旋转与位移矩阵)。
输入输出:
1.输入都是3D点集和对应的2D点集,其中cvPOSIT的3D点包含在posit_object结构中
2.输出均包括旋转矩阵和位移向量
形式不同:
solvePnP有摄像机的一些内参
语义不同:
除了一堆数据类型检查和转化外,其实solvePnP调用的是cvFindExtrinsicCameraParams2通过已知的内参进行未知外参求解,是一个精确解;而cvPOSIT是用仿射投影模型近似透视投影模型下,不断迭代计算出来的估计值(在物体深度变化相对于物体到摄像机的距离比较大的时候,这种算法可能不收敛)。
2. 函数原型
Finds an object pose from 3D-2D point correspondences.
solvePnP(http://docs.opencv.org/modules/calib3d /doc/camera_calibration_and_3d_reconstruction.html#solvepnp)
bool solvePnP(
InputArray objectPoints, InputArray imagePoints, InputArray cameraMatrix, InputArray distCoeffs,
OutputArray rvec, OutputArray tvec,
bool useExtrinsicGuess=false, int flags=ITERATIVE )
执行POSIT算法
void cvPOSIT(
CvPOSITObject* posit_object, CvPoint2D32f* image_points,
>double focal_length,
CvTermCriteria criteria, CvMatr32f rotation_matrix, CvVect32f translation_vector );
3.Cv2.410的源代码
OpenCV参考手册第392页
bool cv::solvePnP( InputArray _opoints, InputArray _ipoints,
InputArray _cameraMatrix, InputArray _distCoeffs,
OutputArray _rvec, OutputArray _tvec, bool useExtrinsicGuess, int flags )
{
Mat opoints = _opoints.getMat(), ipoints = _ipoints.getMat();
int npoints = std::max(opoints.checkVector(3, CV_32F), opoints.checkVector(3, CV_64F));
CV_Assert( npoints >= 0 && npoints == std::max(ipoints.checkVector(2, CV_32F), ipoints.checkVector(2, CV_64F)) );
_rvec.create(3, 1, CV_64F);
_tvec.create(3, 1, CV_64F);
Mat cameraMatrix = _cameraMatrix.getMat(), distCoeffs = _distCoeffs.getMat(); if (flags == CV_EPNP)
{
cv::Mat undistortedPoints;
cv::undistortPoints(ipoints, undistortedPoints, cameraMatrix, distCoeffs);
epnp PnP(cameraMatrix, opoints, undistortedPoints); cv::Mat R, rvec = _rvec.getMat(), tvec = _tvec.getMat();
PnP.compute_pose(R, tvec);
cv::Rodrigues(R, rvec);
return true;
}
else if (flags == CV_P3P)
{
CV_Assert( npoints == 4);
cv::Mat undistortedPoints;
cv::undistortPoints(ipoints, undistortedPoints, cameraMatrix, distCoeffs);
p3p P3Psolver(cameraMatrix); cv::Mat R, rvec = _rvec.getMat(), tvec = _tvec.getMat();
bool result = P3Psolver.solve(R, tvec, opoints, undistortedPoints);
if (result)
cv::Rodrigues(R, rvec);
return result;
}
else if (flags == CV_ITERATIVE)
{
CvMat c_objectPoints = opoints, c_imagePoints = ipoints;
CvMat c_cameraMatrix = cameraMatrix, c_distCoeffs = distCoeffs;
CvMat c_rvec = _rvec.getMat(), c_tvec = _tvec.getMat();
cvFindExtrinsicCameraParams2(&c_objectPoints, &c_imagePoints, &c_cameraMatrix,
c_distCoeffs.rows*c_distCoeffs.cols ? &c_distCoeffs : 0,
&c_rvec, &c_tvec, useExtrinsicGuess );
return true;
}
else
CV_Error(CV_StsBadArg, "The flags argument must be one of CV_ITERATIVE or CV_EPNP");
return false;
}
有效代码:
else if (flags == CV_P3P)
{
CV_Assert( npoints == 4);
cv::Mat undistortedPoints;
cv::undistortPoints(ipoints, undistortedPoints, cameraMatrix, distCoeffs);
p3p P3Psolver(cameraMatrix); cv::Mat R, rvec = _rvec.getMat(), tvec = _tvec.getMat();
bool result = P3Psolver.solve(R, tvec, opoints, undistortedPoints);
if (result)
cv::Rodrigues(R, rvec);
return result;
}
4. 函数mySolvePnP()
int rec3D::mySolvePnP(
//vector<cv::Point3f> &_opoints , vector<cv::Point2f> &_ipoints ,
InputArray &_opoints , InputArray &_ipoints ,
//cv::Mat &intrinsic_Mat , cv::Mat &disCoeff ,
InputArray &_cameraMatrix , InputArray &_distCoeffs ,
//cv::Mat &rvecs , cv::Mat &tvecs ,
OutputArray &_rvec , OutputArray &_tvec ,
bool useExtrinsicGuess, int flags)
{
cv::Mat opoints = _opoints.getMat(), ipoints = _ipoints.getMat();
int npoints = std::max(opoints.checkVector(3, CV_32F), opoints.checkVector(3, CV_64F));
CV_Assert( npoints >= 0 && npoints == std::max(ipoints.checkVector(2, CV_32F), ipoints.checkVector(2, CV_64F)) );
_rvec.create(3, 1, CV_64F);
_tvec.create(3, 1, CV_64F);
cv::Mat cameraMatrix = _cameraMatrix.getMat(), distCoeffs = _distCoeffs.getMat(); {
CV_Assert( npoints == 4);
cv::Mat undistortedPoints;
cv::undistortPoints(ipoints, undistortedPoints, cameraMatrix, distCoeffs);
p3p P3Psolver(cameraMatrix); cv::Mat R, rvec = _rvec.getMat(), tvec = _tvec.getMat();
bool result = P3Psolver.solve(R, tvec, opoints, undistortedPoints);
if (result)
cv::Rodrigues(R, rvec);
return result;
}
return true;
}
暂时未完成,待修改...................
真正运行的JNI函数:
真正可以运行的JNI函数:
int rec3D::mySolvePnP(
vector<cv::Point3f> &_opoints ,const vector<cv::Point2f> &_ipoints ,
//InputArray &_opoints , InputArray &_ipoints ,
cv::Mat &intrinsic_Mat , cv::Mat &disCoeff ,
//InputArray &_cameraMatrix , InputArray &_distCoeffs ,
cv::Mat &_rvecs , cv::Mat &_tvecs ,
//OutputArray &_rvec , OutputArray &_tvec ,
bool useExtrinsicGuess, int flags)
{
cv::Mat opoints = Mat(_opoints, true);// _opoints.getMat();
cv::Mat ipoints = Mat(_ipoints , true);///_ipoints.getMat(); int npoints = std::max(opoints.checkVector(3, CV_32F), opoints.checkVector(3, CV_64F));//The error source! wishchin ! CV_Assert( npoints >= 0 && npoints == std::max(ipoints.checkVector(2, CV_32F), ipoints.checkVector(2, CV_64F)) );
//_rvecs= new Mat(3, 1, CV_64F);//_rvec.create(3, 1, CV_64F);
//_tvecs= new Mat(3, 1, CV_64F);//.create(3, 1, CV_64F); //cv::Mat cameraMatrix = _cameraMatrix.getMat(), distCoeffs = _distCoeffs.getMat();
cv::Mat cameraMatrix = intrinsic_Mat.clone();
cv::Mat distCoeffs = disCoeff.clone(); //{ CV_Assert( npoints == 4);
cv::Mat undistortedPoints(ipoints.rows,ipoints.cols, ipoints.type() );
//undistortedPoints 为输出参数!
undistortPointsMy(ipoints, undistortedPoints, cameraMatrix, distCoeffs);//undistortPoints(ipoints, undistortedPoints, cameraMatrix, distCoeffs); //1.修改函数
//p3pMy P3Psolver= new p3pMy(cameraMatrix);
p3pMy P3Psolver(cameraMatrix); //cv::Mat R, rvec = _rvec.getMat(), tvec = _tvec.getMat();
//cv::Mat R = _rvecs.clone();
//cv::Mat rvec = _rvecs.clone();
//cv::Mat tvec = _tvecs.clone();
////2.修改函数
//bool result = P3Psolver.solve(R, tvec, opoints, undistortedPoints); cv::Mat R;// = _rvecs.clone();
//cv::Mat rvec = _rvecs.clone();
//cv::Mat tvec = _tvecs.clone(); //2.修改函数
bool result = P3Psolver.solve(_rvecs, _tvecs, opoints, undistortedPoints); if (result) cv::Rodrigues(_rvecs, R);//cv::Rodrigues(R, rvec); //return result;
//}
return true;
} //void rec3D::undistortPointsMy( InputArray _src, OutputArray _dst,
// InputArray _cameraMatrix,
// InputArray _distCoeffs,
// InputArray _Rmat,
// InputArray _Pmat )
void rec3D::undistortPointsMy(
cv::Mat &_src, cv::Mat &_dst,
cv::Mat &_cameraMatrix,
cv::Mat &_distCoeffs)
{
cv::Mat src =_src;// _src.getMat();
cv::Mat cameraMatrix = _cameraMatrix;//_cameraMatrix.getMat();
cv::Mat distCoeffs = _distCoeffs;//_distCoeffs.getMat();//, R = _Rmat.getMat(), P = _Pmat.getMat();
cv::Mat R;
cv::Mat P; CV_Assert( src.isContinuous() && (src.depth() == CV_32F || src.depth() == CV_64F) &&
((src.rows == 1 && src.channels() == 2) || src.cols*src.channels() == 2)); //_dst.create(src.size(), src.type(), -1, true);
Mat dst = _dst;//_dst.getMat(); //Fuck!引用传来传去的! dst矩阵!
CvMat _csrc = src, _cdst = dst, _ccameraMatrix = cameraMatrix;
CvMat matR, matP, _cdistCoeffs, *pR=0, *pP=0, *pD=0;
if( R.data )
pR = &(matR = R);
if( P.data )
pP = &(matP = P);
if( distCoeffs.data )
pD = &(_cdistCoeffs = distCoeffs); //Fuck!引用传来传去的! dst矩阵!
//cvUndistortPoints(&_csrc, &_cdst, &_ccameraMatrix, pD, pR, pP);
cvUndistortPointsMyRf(&_csrc, &_cdst, &_ccameraMatrix, pD, pR, pP);
} //逻辑混乱!!!
void rec3D::cvUndistortPointsMy(
const CvMat* _src, CvMat* _dst, const CvMat* _cameraMatrix,const CvMat* _distCoeffs,
const CvMat* matR, const CvMat* matP )
{
double A[3][3], RR[3][3], k[8]={0,0,0,0,0,0,0,0}, fx, fy, ifx, ify, cx, cy;
CvMat matA=cvMat(3, 3, CV_64F, A), _Dk;
CvMat _RR=cvMat(3, 3, CV_64F, RR);
const CvPoint2D32f* srcf;
const CvPoint2D64f* srcd;
CvPoint2D32f* dstf;
CvPoint2D64f* dstd;
int stype, dtype;
int sstep, dstep;
int i, j, n, iters = 1; CV_Assert( CV_IS_MAT(_src) && CV_IS_MAT(_dst) &&
(_src->rows == 1 || _src->cols == 1) &&
(_dst->rows == 1 || _dst->cols == 1) &&
_src->cols + _src->rows - 1 == _dst->rows + _dst->cols - 1 &&
(CV_MAT_TYPE(_src->type) == CV_32FC2 || CV_MAT_TYPE(_src->type) == CV_64FC2) &&
(CV_MAT_TYPE(_dst->type) == CV_32FC2 || CV_MAT_TYPE(_dst->type) == CV_64FC2)); CV_Assert( CV_IS_MAT(_cameraMatrix) &&
_cameraMatrix->rows == 3 && _cameraMatrix->cols == 3 ); cvConvert( _cameraMatrix, &matA );//这一句关系到画三维坐标系,但看起来毫无用处! if( _distCoeffs )
{
CV_Assert( CV_IS_MAT(_distCoeffs) &&
(_distCoeffs->rows == 1 || _distCoeffs->cols == 1) &&
(_distCoeffs->rows*_distCoeffs->cols == 4 ||
_distCoeffs->rows*_distCoeffs->cols == 5 ||
_distCoeffs->rows*_distCoeffs->cols == 8)); _Dk = cvMat( _distCoeffs->rows, _distCoeffs->cols,
CV_MAKETYPE(CV_64F,CV_MAT_CN(_distCoeffs->type)), k); cvConvert( _distCoeffs, &_Dk );
iters = 5;
} if( matR )
{
CV_Assert( CV_IS_MAT(matR) && matR->rows == 3 && matR->cols == 3 );
cvConvert( matR, &_RR );
}
else
cvSetIdentity(&_RR); if( matP )
{
double PP[3][3];
CvMat _P3x3, _PP=cvMat(3, 3, CV_64F, PP);
CV_Assert( CV_IS_MAT(matP) && matP->rows == 3 && (matP->cols == 3 || matP->cols == 4));
cvConvert( cvGetCols(matP, &_P3x3, 0, 3), &_PP );
cvMatMul( &_PP, &_RR, &_RR );
} srcf = (const CvPoint2D32f*)_src->data.ptr;
srcd = (const CvPoint2D64f*)_src->data.ptr;
dstf = (CvPoint2D32f*)_dst->data.ptr;
dstd = (CvPoint2D64f*)_dst->data.ptr;
stype = CV_MAT_TYPE(_src->type);
dtype = CV_MAT_TYPE(_dst->type);
sstep = _src->rows == 1 ? 1 : _src->step/CV_ELEM_SIZE(stype);
dstep = _dst->rows == 1 ? 1 : _dst->step/CV_ELEM_SIZE(dtype); n = _src->rows + _src->cols - 1; fx = A[0][0];
fy = A[1][1];
ifx = 1./fx;
ify = 1./fy;
cx = A[0][2];
cy = A[1][2]; for( i = 0; i < n; i++ )
{
double x, y, x0, y0;
if( stype == CV_32FC2 )
{
x = srcf[i*sstep].x;
y = srcf[i*sstep].y;
}
else
{
x = srcd[i*sstep].x;
y = srcd[i*sstep].y;
} x0 = x = (x - cx)*ifx;
y0 = y = (y - cy)*ify; // compensate distortion iteratively
for( j = 0; j < iters; j++ )
{
double r2 = x*x + y*y;
double icdist = (1 + ((k[7]*r2 + k[6])*r2 + k[5])*r2)/(1 + ((k[4]*r2 + k[1])*r2 + k[0])*r2);
double deltaX = 2*k[2]*x*y + k[3]*(r2 + 2*x*x);
double deltaY = k[2]*(r2 + 2*y*y) + 2*k[3]*x*y;
x = (x0 - deltaX)*icdist;
y = (y0 - deltaY)*icdist;
} double xx = RR[0][0]*x + RR[0][1]*y + RR[0][2];
double yy = RR[1][0]*x + RR[1][1]*y + RR[1][2];
double ww = 1./(RR[2][0]*x + RR[2][1]*y + RR[2][2]);
x = xx*ww;
y = yy*ww; if( dtype == CV_32FC2 )
{
dstf[i*dstep].x = (float)x;
dstf[i*dstep].y = (float)y;
}
else
{
dstd[i*dstep].x = x;
dstd[i*dstep].y = y;
}
}
} void rec3D::cvUndistortPointsMyRf(
const CvMat* _src, CvMat* _dst,
const CvMat* _cameraMatrix,
const CvMat* _distCoeffs,
const CvMat* matR,
const CvMat* matP )
{
double A[3][3], RR[3][3];
double k[8]={0,0,0,0,0,0,0,0};
double fx, fy, ifx, ify, cx, cy; CvMat matA=cvMat(3, 3, CV_64F, A);
CvMat _Dk;
CvMat _RR=cvMat(3, 3, CV_64F, RR); const CvPoint2D32f* srcf;
const CvPoint2D64f* srcd;
CvPoint2D32f* dstf;
CvPoint2D64f* dstd; int stype, dtype;
int sstep, dstep;
int i, j, n, iters = 1; CV_Assert(
CV_IS_MAT(_src) && CV_IS_MAT(_dst) &&
(_src->rows == 1 || _src->cols == 1) &&
(_dst->rows == 1 || _dst->cols == 1) &&
_src->cols + _src->rows - 1 == _dst->rows + _dst->cols - 1 &&
(CV_MAT_TYPE(_src->type) == CV_32FC2 || CV_MAT_TYPE(_src->type) == CV_64FC2) &&
(CV_MAT_TYPE(_dst->type) == CV_32FC2 || CV_MAT_TYPE(_dst->type) == CV_64FC2)); CV_Assert( CV_IS_MAT(_cameraMatrix) &&
_cameraMatrix->rows == 3 && _cameraMatrix->cols == 3 ); //图像到矩阵的转换:cvConvert( src, dst );
//cvConvert( _cameraMatrix, &matA );//这一句关系到画三维坐标系,但看起来毫无用处!
cvConvertMy( _cameraMatrix, &matA ); if( _distCoeffs )
{
CV_Assert( CV_IS_MAT(_distCoeffs) &&
(_distCoeffs->rows == 1 || _distCoeffs->cols == 1) &&
(_distCoeffs->rows*_distCoeffs->cols == 4 ||
_distCoeffs->rows*_distCoeffs->cols == 5 ||
_distCoeffs->rows*_distCoeffs->cols == 8)); _Dk = cvMat( _distCoeffs->rows, _distCoeffs->cols,
CV_MAKETYPE(CV_64F,CV_MAT_CN(_distCoeffs->type)), k); //cvConvert( _distCoeffs, &_Dk );
cvConvertMy(_distCoeffs, &_Dk );
iters = 5;
} if( matR )
{
CV_Assert( CV_IS_MAT(matR) && matR->rows == 3 && matR->cols == 3 );
//cvConvert( matR, &_RR );
cvConvertMy(matR, &_RR );
}
else
cvSetIdentity(&_RR); if( matP )
{
double PP[3][3];
CvMat _P3x3, _PP=cvMat(3, 3, CV_64F, PP);
CV_Assert( CV_IS_MAT(matP) && matP->rows == 3 && (matP->cols == 3 || matP->cols == 4));
//cvConvert( cvGetCols(matP, &_P3x3, 0, 3), &_PP );
cvConvertMy( cvGetCols(matP, &_P3x3, 0, 3), &_PP );
cvMatMul( &_PP, &_RR, &_RR );
} srcf = (const CvPoint2D32f*)_src->data.ptr;
srcd = (const CvPoint2D64f*)_src->data.ptr; //dst的指针引用!
dstf = (CvPoint2D32f*)_dst->data.ptr;
dstd = (CvPoint2D64f*)_dst->data.ptr;
stype = CV_MAT_TYPE(_src->type);
dtype = CV_MAT_TYPE(_dst->type);
sstep = _src->rows == 1 ? 1 : _src->step/CV_ELEM_SIZE(stype);
dstep = _dst->rows == 1 ? 1 : _dst->step/CV_ELEM_SIZE(dtype); n = _src->rows + _src->cols - 1; fx = A[0][0];
fy = A[1][1];
ifx = 1./fx;
ify = 1./fy;
cx = A[0][2];
cy = A[1][2]; for( i = 0; i < n; i++ )
{
double x, y, x0, y0;
if( stype == CV_32FC2 )
{
x = srcf[i*sstep].x;
y = srcf[i*sstep].y;
}
else
{
x = srcd[i*sstep].x;
y = srcd[i*sstep].y;
} x0 = x = (x - cx)*ifx;
y0 = y = (y - cy)*ify; // compensate distortion iteratively
for( j = 0; j < iters; j++ )
{
double r2 = x*x + y*y;
double icdist = (1 + ((k[7]*r2 + k[6])*r2 + k[5])*r2)/(1 + ((k[4]*r2 + k[1])*r2 + k[0])*r2);
double deltaX = 2*k[2]*x*y + k[3]*(r2 + 2*x*x);
double deltaY = k[2]*(r2 + 2*y*y) + 2*k[3]*x*y;
x = (x0 - deltaX)*icdist;
y = (y0 - deltaY)*icdist;
} double xx = RR[0][0]*x + RR[0][1]*y + RR[0][2];
double yy = RR[1][0]*x + RR[1][1]*y + RR[1][2];
double ww = 1./(RR[2][0]*x + RR[2][1]*y + RR[2][2]);
x = xx*ww;
y = yy*ww; if( dtype == CV_32FC2 )
{
dstf[i*dstep].x = (float)x;
dstf[i*dstep].y = (float)y;
}
else
{
dstd[i*dstep].x = x;
dstd[i*dstep].y = y;
}
}
} //bool rec3D::cvConvertMy(const CvMat* _cameraMatrix,double matA[][3] )
//{
//
// return true;
//} bool rec3D::cvConvertMy(const CvMat* Mat, CvMat* MatA )
{
int C = Mat->step/ Mat->cols/sizeof(Mat->type);
for (int row = 0; row < Mat->rows && row < MatA->rows; row++){ float* ptr = (float*)(Mat->data.ptr + row * Mat->step);//第row行数据的起始指针
float* ptrD = (float*)(MatA->data.ptr + row * MatA->step); for (int col = 0; col < Mat->cols && col < MatA->cols; col++)
{
for (int i=0;i<C;++i)
{
*(ptrD+C*col+i) = *(ptr+C*col+i);
}
//*(ptrD+3*col) = *(ptr+3*col);//cout<<*(ptr+3*col)<<endl;
//*(ptrD+3*col+1) = *(ptr+3*col+1);//cout<<*(ptr+3*col+1)<<endl;
//*(ptrD+3*col+2) = *(ptr+3*col+2);//cout<<*(ptr+3*col+2)<<endl;
}
} return true;
}
完成!
三维重建:多点透视cvSolvePNP的替代函数(Code)的更多相关文章
- PHP正则表达式函数的替代函数
1,preg_split()函数将字符串按照某元素分割,分割后结果以数组方式返回. php中explode()可以实现此功能.array explode(string $pattern,string ...
- 相机标定:PNP基于单应面解决多点透视问题
利用二维视野内的图像,求出三维图像在场景中的位姿,这是一个三维透视投影的反向求解问题.常用方法是PNP方法,需要已知三维点集的原始模型. 本文做了大量修改,如有不适,请移步原文: ...
- 解决PHP中json_encode()不支持中文的替代函数
json_encode()是PHP中将数组转换成JSON格式的函数,因为各种原因只要是中文就会乱码= = 找到了这么一个函数替代了原有的json_encode(),能很好地输出中文~ function ...
- pandas实现excel中的数据透视表和Vlookup函数功能
在孩子王实习中做的一个小工作,方便整理数据. 目前这几行代码是实现了一个数据透视表和匹配的功能,但是将做好的结果写入了不同的excel中, 如何实现将结果连续保存到同一个Excel的同一个工作表中?还 ...
- str_split 分隔中文出现乱码 替代函数
function mbstringtoarray($str,$charset) { $strlen=mb_strlen($str); while($strlen){ $array[]=mb_subst ...
- Python 中MATLABspline函数的替代函数
调用scipy模块,其中有对应的函数UnivariateSpline.与MATLAB中spline函数不同的是,这个函数返回值是一个插值函数,而非插值结果. import scipy spline = ...
- console.log() 替代函数
var log = console.log.bind(console); log('d')
- json_encode替代函数
<?php function jsonEncode($var) { if (function_exists('json_encode')) { return json ...
- PHP常用函数和常见疑难问题解答
PHP常用库函数介绍 一.PHP字符串操作常用函数 1.确定字符串长度 int strlen(string str) 2.比较两个字符串 a. strcmp函数对两个字符串进行二进制安全的比较,并区 ...
随机推荐
- BZOJ 1724 USACO 2006 Nov. 切割木板
倒过来的合并果子? 做法与合并果子一样 维护一个小根堆,每次取出最小的两个数进行合并 #include<cstdio> #include<algorithm> #include ...
- [ZJOI2010]Perm
[ZJOI2010]Perm 题目 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少 ...
- 高三感想+跨年感想+OI回忆录
2017.12.29晚 高三感慨 与OI分别很久了,发现自己已经不会敲代码了…… 高三国庆前大概比较正常,只是某只人影响有点大(现在好多了)…… 感觉国庆以后状态就没好过. 先感冒两个星期,然后某个周 ...
- poj 2553强连通+缩点
/*先吐槽下,刚开始没看懂题,以为只能是一个连通图0T0 题意:给你一个有向图,求G图中从v可达的所有点w,也都可以达到v,这样的v称为sink.求这样的v. 解;求强连通+缩点.求所有出度为0的点即 ...
- SSM(spring mvc+spring+mybatis)学习路径——2-1、spring MVC入门
目录 2-1 Spring MVC起步 一.回顾Servlet 二.SpringMVC简介 三.搭建SpringMVC第一个案例 四.简单流程及配置 五.使用注解开发Controller 六.参数绑定 ...
- 调用BPL包中的函数
BPL就是一种DLL,DLL的EXPORTS和GETPROCADDRESS()在BPL中一样好使. 要调用BPL中的方法也和调用DLL的一样.代码略.
- Intellij Idea 13:重置设置
最近在将Windows下的Idea的设置导入到Mac下的时候,一时手贱,点了全部结果发现悲剧了,所有的快捷键都变成和Windows的一样了.于是我就在CMD+C,V和Ctrl+C,V中不断的进行头脑锻 ...
- java面向接口编程
在oop中有一种设计原则是面向接口编程,面向接口编程有非常多优点,详细百度一大片.我来谈一下详细的使用中的一些不成熟的见解.! 首先面向接口编程能够消除类之间的依赖关系,使得业务仅仅依赖接口. 这样有 ...
- 虚拟机 开发板 PC机 三者之间不能ping通的各种原因分析
这个问题事实上也相对照较简单.可是非常多网友都给我发消息说 遇到不能ping,每一个人都得回答一次确实显得心有余而力不足.如今我对遇到这几种问题给出最完整的解决方式. (说实话基本上也仅仅要这几种可能 ...
- Python内置的字符串处理函数
生成字符串变量 str='python String function' 字符串长度获取:len(str) 例:print '%s length=%d' % (str,len(str)) 连接字符 ...