Итак, что я хочу сделать, это исправить набор стереоизображений типа «рыбий глаз», не искажая их. Я проецирую изображения «рыбий глаз» внутрь сферы в Unity 3D игровой движок, поэтому мне действительно нужны радиальные искажения. Все, что мне нужно, это «выравнивание» изображений, чтобы я мог использовать их для создания карты диспаратности.
Как вы можете заметить, я даже пытался исключить коэффициенты искажения из функции fisheye::initUndistortRectifyMap
но без удачи.
Это возможно?
Вот мой текущий код, который будет исправлять и неискажать мои изображения «рыбий глаз»:
#include "opencv2/core/core.hpp"#include "opencv2/calib3d/calib3d.hpp"#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
//#include "opencv2/contrib/contrib.hpp"#include <stdio.h>
using namespace cv;
using namespace std;
int main(int argc, char* argv[])
{
int numBoards = 13;
int board_w = 7;
int board_h = 6;
int skipnum = 15; //5=2.42 , 7=2.43
Size board_sz = Size(board_w, board_h);
int board_n = board_w*board_h;
vector<vector<Point3f> > object_points;
vector<vector<Point2f> > imagePoints1, imagePoints2;
vector<Point2f> corners1, corners2;
vector<Point3f> obj;
for (int j=0; j<board_n; j++)
{
obj.push_back(Point3f(j/board_w, j%board_w, 0.0f));
}
Mat img1, img2, gray1, gray2, image1, image2;int success = 0, k = 0, foundcount = 0
, imagenum = 0;
bool found1 = false, found2 = false;
Mat distCoeffs0;
Mat intrinsic0;
cv::FileStorage storage0("CamData0.yml", cv::FileStorage::READ);
storage0["distCoeffs"] >> distCoeffs0;
storage0["intrinsic"] >> intrinsic0;
storage0.release();
Mat distCoeffs1;
Mat intrinsic1;
cv::FileStorage storage1("CamData1.yml", cv::FileStorage::READ);
storage1["distCoeffs"] >> distCoeffs1;
storage1["intrinsic"] >> intrinsic1;
storage1.release();Mat map1x, map1y, map2x, map2y, R;
image1 = imread("/home/ubuntu/opencv-apps/images/L_img1.png",CV_LOAD_IMAGE_GRAYSCALE);
fisheye::initUndistortRectifyMap (intrinsic0, distCoeffs0, R, intrinsic0, image1.size(),CV_32FC1, map1x, map1y );
fisheye::initUndistortRectifyMap (intrinsic1, distCoeffs1, R, intrinsic1, image1.size(),CV_32FC1, map2x, map2y );
while (success < numBoards)
{
imagenum ++;
if (imagenum != 5 && imagenum != 7) {
char nameL[50];
sprintf(nameL,"/home/ubuntu/opencv-apps/images/L_img%d.png",imagenum);
char nameR[50];
sprintf(nameR,"/home/ubuntu/opencv-apps/images/R_img%d.png",imagenum);image1 = imread(nameL,CV_LOAD_IMAGE_GRAYSCALE);
image2 = imread(nameR,CV_LOAD_IMAGE_GRAYSCALE);
//resize(img1, img1, Size(320, 280));
//resize(img2, img2, Size(320, 280));
remap(image1, img1, map1x, map1y, INTER_LINEAR, BORDER_CONSTANT, Scalar());
remap(image2, img2, map2x, map2y, INTER_LINEAR, BORDER_CONSTANT, Scalar());
// cvtColor(img1, gray1, CV_BGR2GRAY);
// cvtColor(img2, gray2, CV_BGR2GRAY);found1 = findChessboardCorners(img1, board_sz, corners1, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FAST_CHECK | CALIB_CB_NORMALIZE_IMAGE);
found2 = findChessboardCorners(img2, board_sz, corners2, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FAST_CHECK | CALIB_CB_NORMALIZE_IMAGE);
if (found1)
{
cornerSubPix(img1, corners1, Size(11, 11), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 30, 0.1));
drawChessboardCorners(img1, board_sz, corners1, found1);
}
if (found2)
{
cornerSubPix(img2, corners2, Size(11, 11), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 30, 0.1));
drawChessboardCorners(img2, board_sz, corners2, found2);
}k = waitKey(10);
// if (found1 && found2)
// {
// k = waitKey(0);
// }
if (k == 27)
{
break;
}
if (found1 !=0 && found2 != 0)
{
foundcount++;
imagePoints1.push_back(corners1);
imagePoints2.push_back(corners2);
object_points.push_back(obj);
printf ("Corners stored (%d)\n",foundcount);
success++;
if (success >= numBoards)
{
break;
}
}
}
}
destroyAllWindows();
printf("Starting Calibration\n");
Mat CM1 = intrinsic0.clone();//Mat(3, 3, CV_64FC1);
Mat CM2 = intrinsic1.clone();//Mat(3, 3, CV_64FC1);
Mat D1;
Mat D2;
Mat T, E, F;
double error = stereoCalibrate(object_points, imagePoints1, imagePoints2,
CM1, D1, CM2, D2, img1.size(), R, T, E, F,
CV_CALIB_USE_INTRINSIC_GUESS,
cvTermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 100, 1e-5));
printf("%s%f\n","error: ", error );
FileStorage fs1("mystereocalib.yml", FileStorage::WRITE);
fs1 << "CM1" << CM1;
fs1 << "CM2" << CM2;
fs1 << "R" << R;
fs1 << "T" << T;
fs1 << "E" << E;
fs1 << "F" << F;
printf("Done Calibration\n");
printf("Starting Rectification\n");
Mat R1, R2, P1, P2, Q;
stereoRectify(CM1, D1, CM2, D2, img1.size(), R, T, R1, R2, P1, P2, Q);
fs1 << "R1" << R1;
fs1 << "R2" << R2;
fs1 << "P1" << P1;
fs1 << "P2" << P2;
fs1 << "Q" << Q;
fs1 << "D1" << distCoeffs0;
fs1 << "D2" << distCoeffs1;
fs1.release();
printf("Done Rectification\n");
printf("Applying Undistort\n");Mat imgU1, imgU2, disp, disp8 , o1, o2;
Mat empty, empty8;
empty8.convertTo(empty,5);
// printf("%s\n",empty.empty() );
map1x = Scalar();
map1y = Scalar();
map2x = Scalar();
map2y = Scalar();
// Mat map1x, map1y, map2x, map2y, R;fisheye::initUndistortRectifyMap(CM1, empty, R1, P1, img1.size(), CV_32FC1, map1x, map1y);
fisheye::initUndistortRectifyMap(CM2, empty, R2, P2, img2.size(), CV_32FC1, map2x, map2y);
printf("Undistort complete\n");int lambda = 200; //< Range of disparity
int ndisparities = 16*4; //< Range of disparity
int SADWindowSize = 7 ;
int sigcol = 15;
//Create trackbar to change brightness
static Ptr< StereoSGBM > sgbm = StereoSGBM::create (0, ndisparities, SADWindowSize, 8*o1.channels()*SADWindowSize*SADWindowSize, 32*o1.channels()*SADWindowSize*SADWindowSize, 0, 81,10,100, 1);int imgnum = 0;
while(1)
{
imgnum ++;
if (imgnum > 14){
imgnum = 1;
}
char nameL[10];
sprintf(nameL,"images/L_img%d.png",imgnum);
char nameR[10];
sprintf(nameR,"images/R_img%d.png",imgnum);
image1 = imread(nameL,CV_LOAD_IMAGE_COLOR);
image2 = imread(nameR,CV_LOAD_IMAGE_COLOR);
remap(image1, imgU1, map1x, map1y, INTER_LINEAR, BORDER_CONSTANT, Scalar(1));
remap(image2, imgU2, map2x, map2y, INTER_LINEAR, BORDER_CONSTANT, Scalar(1));sgbm->compute( imgU2, imgU1, disp );
normalize(disp, disp8, 0, 255, CV_MINMAX, CV_8U);
imshow("image1", disp8);
imshow("image2", imgU2);
k = waitKey(5);
if(k==27)
{
break;
}
}return(0);
}
Задача ещё не решена.
Других решений пока нет …