opencv菜鸟,写的程序,可是为什么程序会报错
//
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/calib3d/calib3d.hpp>
#include"cv.h"
#include<stdio.h>
#include<cmath>
#pragma comment(lib,"opencv_core231d.lib")
#pragma comment(lib,"opencv_highgui231d.lib")
#pragma comment(lib,"opencv_flann231d.lib")
#pragma comment(lib,"opencv_core231.lib")
#pragma comment(lib,"opencv_highgui231.lib")
#pragma comment(lib,"opencv_flann231.lib")
#pragma comment(lib,"opencv_calib3d231d.lib")
#pragma comment(lib,"opencv_calib3d231.lib")
#define N 9
using namespace cv;
using namespace std;
class my_calib
{
public:
my_calib():vec(0,0),Squeare(0.02),R(0.0668/2)
{
projectMatrix=Mat::zeros(3,4,CV_64FC1);
intrinsicMatrix=Mat::zeros(3,3,CV_64FC1);
R1=Mat::zeros(3,3,CV_64FC1);
t=Mat::zeros(3,1,CV_64FC1);
};//默认构造函数
void world_frame(my_calib &calib);
void image_frame(my_calib &calib);
void show_color_corner(my_calib &calib);
void compute_Project_Matrix(my_calib &calib);
void decompase_project_matix(my_calib &calib);
void print_matix(my_calib &calib);
Size patternsize;
double R;//圆筒的半径
Mat M;
Mat projectMatrix;
Mat intrinsicMatrix;
Mat R1;
Mat t;
vector<Point2f> vec;
double Squeare;//棋盘格的边长
vector<Point3d> object;
};
void my_calib::decompase_project_matix(my_calib &calib)
{
Mat subProjectMatrix=Mat::zeros(3,3,CV_64FC1);
Mat b=Mat::zeros(3,1,CV_64FC1);
Mat K=Mat::zeros(3,3,CV_64FC1);
double u,v,bta,gama,rfa;
for (int i=0;i<3;i++)
{
for (int j=0;j<3;j++)
{
subProjectMatrix.at<double>(i,j)=calib.projectMatrix.at<double>(i,j);
}
}
b=calib.projectMatrix.col(3);
K=subProjectMatrix*subProjectMatrix.t();
//normalize K
K=K/K.at<double>(2,2);
//计算内参
u=K.at<double>(0,2);
v=K.at<double>(1,2);
bta=sqrt(K.at<double>(1,1)-v*v);
gama=(K.at<double>(0,1)-u*v)/bta;
rfa=sqrt(K.at<double>(0,0)-u*u-gama*gama);
calib.intrinsicMatrix.at<double>(0,0)=rfa;
calib.intrinsicMatrix.at<double>(0,1)=gama;
calib.intrinsicMatrix.at<double>(0,2)=u;
calib.intrinsicMatrix.at<double>(1,1)=bta;
calib.intrinsicMatrix.at<double>(1,2)=v;
calib.intrinsicMatrix.at<double>(2,2)=1;
calib.R1=calib.intrinsicMatrix.inv()*subProjectMatrix;
calib.t=calib.intrinsicMatrix.inv()*b;
}
void my_calib::compute_Project_Matrix(my_calib &calib)
{
Mat A=Mat::zeros(2*N,12,CV_64FC1);//18*12
Mat LL=Mat::zeros(2*N-1,1,CV_64FC1);//17*1
Mat C=Mat::zeros(2*N,11,CV_64FC1);//18*11
Mat B=Mat::zeros(2*N,1,CV_64FC1);//18*1
Mat D=Mat::eye(12,12,CV_64FC1);//12*12的单位阵
Mat E=Mat::eye(12,12,CV_64FC1);//12*12的单位阵
double p34=1;
//计算投影矩阵
for (int i=0;i<N;i++)
{
A.row(2*i).at<double>(0)=calib.object[3*i+5].x;//尽量取一些分散的点,这样算出来的误差可能会小一些
A.row(2*i).at<double>(1)=calib.object[3*i+5].y;
A.row(2*i).at<double>(2)=calib.object[3*i+5].z;
A.row(2*i).at<double>(3)=1;
A.row(2*i).at<double>(8)=-(calib.vec[3*i+5].x)*(calib.object[3*i+5].x);
A.row(2*i).at<double>(9)=-(calib.vec[3*i+5].x)*(calib.object[3*i+5].y);
A.row(2*i).at<double>(10)=-(calib.vec[3*i+5].x)*(calib.object[3*i+5].z);
A.row(2*i).at<double>(11)=calib.vec[3*i+5].x;
A.row(2*i+1).at<double>(4)=calib.object[3*i+5].x;
A.row(2*i+1).at<double>(5)=calib.object[3*i+5].y;
A.row(2*i+1).at<double>(6)=calib.object[3*i+5].z;
A.row(2*i+1).at<double>(7)=1;
A.row(2*i+1).at<double>(8)=-(calib.vec[3*i+5].y)*(calib.object[3*i+5].x);
A.row(2*i+1).at<double>(9)=-(calib.vec[3*i+5].y)*(calib.object[3*i+5].y);
A.row(2*i+1).at<double>(10)=-(calib.vec[3*i+5].y)*(calib.object[3*i+5].z);
A.row(2*i+1).at<double>(11)=calib.vec[3*i+5].y;
}
C=A.colRange(0,11);
B=-A.col(11);//C*M=B;M即为投影矩阵
//B=-H;
SVD mySvd=SVD(C,0);
//mySvd.backSubst(B,LL);
mySvd.backSubst(D,A,E,B,LL);//解出A*B=LL,D,E都是单位阵。
//calib.projectMatrix.at<double>(0,0)=LL.at<double>(0);原来是这个类型的赋值有问题,问题出在哪里呢?,看看mat.hpp的552行,原来是忘了对投影矩阵什么的进行初始化
calib.projectMatrix.at<double>(0,0)=LL.at<double>(0);
calib.projectMatrix.at<double>(0,1)=LL.at<double>(1);
calib.projectMatrix.at<double>(0,2)=LL.at<double>(2);
calib.projectMatrix.at<double>(0,3)=LL.at<double>(3);
calib.projectMatrix.at<double>(1,0)=LL.at<double>(4);
calib.projectMatrix.at<double>(1,1)=LL.at<double>(5);
calib.projectMatrix.at<double>(1,2)=LL.at<double>(6);
calib.projectMatrix.at<double>(1,3)=LL.at<double>(7);
calib.projectMatrix.at<double>(2,0)=LL.at<double>(8);
calib.projectMatrix.at<double>(2,1)=LL.at<double>(9);
calib.projectMatrix.at<double>(2,2)=LL.at<double>(10);
calib.projectMatrix.at<double>(2,3)=1;
}
/*点的世界坐标*/
void my_calib::world_frame(my_calib &calib)
{
//typedef calib.object obj;
//typedef calib.R R1;
//typedef calib.Squeare S1;
for(int k=1;k!=13;k++)
{
for(int i=1;i!=5;i++)
{
calib.object.push_back(Point3d(calib.R*cos(i*calib.Squeare/calib.R),calib.R*sin(i*calib.Squeare/calib.R),calib.R*(k*calib.Squeare)));
//calib.object[i+k].y=calib.R*sin(i*calib.Squeare/calib.R);//为什么这样赋值不行呢?
//calib.object[i+k].z=calib.R*(calib.Squeare);//为什么这样赋值不行呢?
}
}
//cout<<calib.object[1]<<endl;
}
void my_calib::image_frame(my_calib &calib)//Mat &M,vector<Point2f> &vec,Size &boardSize
{
if(!calib.M.data)
{
cout<<"打开文件失败"<<endl;
}
static bool patternfound=findChessboardCorners(calib.M,calib.patternsize, calib.vec,
CALIB_CB_ADAPTIVE_THRESH );
drawChessboardCorners(calib.M, calib.patternsize, Mat(calib.vec), patternfound);
}
/*为什么不输出结果呢?难道是这个函数有问题*/
void my_calib::print_matix(my_calib &calib)
{
MatConstIterator_<double> it1=calib.intrinsicMatrix.begin<double>(),it1_end=calib.intrinsicMatrix.end<double>();
for(;it1!=it1_end;it1++)
{
cout<<*it1<<endl;
}
MatConstIterator_<double> it2=calib.R1.begin<double>(),it2_end=calib.R1.end<double>();
for(;it2!=it2_end;it2++)
{
cout<<*it2<<endl;
}
MatConstIterator_<double> it3=calib.t.begin<double>(),it3_end=calib.t.end<double>();
for(;it3!=it3_end;it3++)
{
cout<<*it3<<endl;
}
}
void my_calib::show_color_corner(my_calib &calib)
{
namedWindow("a",1);
imshow("a",calib.M);
waitKey(0);
}
/*
void test(my_calib &calib)
{
if(!(calib.vec.empty()))
{
Mat a11=imread("2.jpg");
namedWindow("b",1);
imshow("b",a11);
}
}*/
/*4,5,6,7,8检测到一样的角点,9,10,11检测到一样的的角点,12与前面的有重合。12检测到四行,15,16,18,20,21,22,23检测到四行选择8,18,22.取22的3,7,11,15,19,23,27,31,35,39,43,47元素就好*/
/*4,5,6一直到26都可以采用(3,12),能用的好像只有4到26.*/
int main(int argc,char *argv[])
{
static Size A(3,12);
static Size B(4,12);
my_calib cylinder1;
cylinder1.patternsize=A;
//Mat image=imread("IMG_1388.jpg");
//Rect roi(450,950,3000,1850);//(左,上,长度,高度)
//Mat D(image,roi);
//cylinder1.M=D;
cylinder1.M=imread("8.jpg");
cylinder1.image_frame(cylinder1);
//cylinder1.show_color_corner(cylinder1);
cylinder1.world_frame(cylinder1);
cylinder1.compute_Project_Matrix(cylinder1);
cylinder1.decompase_project_matix(cylinder1);
cylinder1.print_matix(cylinder1);
my_calib cylinder2;
//Mat image2=imread("IMG_1389.jpg");
//Rect roi2(450,950,3000,1850);//(左,上,长度,高度)
//Mat D2(image2,roi2);
//cylinder2.M=D2;
cylinder2.M=imread("9.jpg");
cylinder2.patternsize=A;
cylinder2.image_frame(cylinder2);
//cylinder1.show_color_corner(cylinder2);
cylinder2.world_frame(cylinder2);
cylinder2.compute_Project_Matrix(cylinder2);
cylinder2.decompase_project_matix(cylinder2);
cylinder2.print_matix(cylinder2);
waitKey(0);
return 1;
} opencv 计算机视觉?C++
[解决办法]
错误提示向量下标越界了。
建议可以将程序分段注释掉,看哪里出错,直到定位错误。
或者设置断点调试,直到我找到错误。
[解决办法]
试在以下第2行设断点:
static bool patternfound=findChessboardCorners(calib.M,calib.patternsize, calib.vec,
CALIB_CB_ADAPTIVE_THRESH );
drawChessboardCorners(calib.M, calib.patternsize, Mat(calib.vec), patternfound);
执行了前一行后,检查patternfound是否为真,calib.vec是否有返回值。出错提示中的vector很可能就是calib.vec,即在执行如下这类语句时出错:
A.row(2*i).at<double>(8)=-(calib.vec[3*i+5].x)*(calib.object[3*i+5].x);