Repository: sourishg/fisheye-stereo-calibration
Branch: master
Commit: e3074ab16e97
Files: 5
Total size: 7.7 KB
Directory structure:
gitextract_oy4bozyl/
├── .gitignore
├── CMakeLists.txt
├── README.md
├── calibrate.cpp
└── popt_pp.h
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
build/
================================================
FILE: CMakeLists.txt
================================================
cmake_minimum_required(VERSION 2.8.11)
project(FISHEYE_STEREO)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(OpenCV REQUIRED)
include_directories($(OpenCV_INCLUDE_DIRS))
add_executable(calibrate calibrate.cpp)
target_link_libraries(calibrate ${OpenCV_LIBS} "-lpopt")
================================================
FILE: README.md
================================================
## OpenCV C++ Stereo Fisheye Calibration
_**Note**_: I don't actively maintain this repository anymore. PRs are more than welcome to help improve it.
This contains a source file to calibrate a stereo system comprising of fisheye lenses. It calibrates the extrinsics and the intrinsics of the cameras without any initial guesses. If you are looking for stereo calibration with lenses which follow the pinhole model check [here](https://github.com/sourishg/stereo_calibration).
### Dependencies
- OpenCV
- popt
### Compilation
Compile all the files using the following commands.
```bash
mkdir build && cd build
cmake ..
make
```
Make sure your are in the `build` folder to run the executables.
### Data
Some sample calibration images are stored in the `imgs` folder.
### Running calibration
Run the executable with the following command
```bash
./calibrate -w [board_width] -h [board_height] -s [square_size] -n [num_imgs] -d [img_dir] -l [left_img_prefix] -r [right_img_prefix] -o [calib_file]
```
For example if you use the images in the `imgs` folder run the following command
```bash
./calibrate -w 9 -h 6 -s 0.02423 -n 29 -d ../imgs/ -l left -r right -o cam_stereo.yml
```
================================================
FILE: calibrate.cpp
================================================
#include <opencv2/core/core.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <stdio.h>
#include <iostream>
#include "popt_pp.h"
using namespace std;
using namespace cv;
vector< vector< Point3d > > object_points;
vector< vector< Point2f > > imagePoints1, imagePoints2;
vector< Point2f > corners1, corners2;
vector< vector< Point2d > > left_img_points, right_img_points;
Mat img1, img2, gray1, gray2, spl1, spl2;
void load_image_points(int board_width, int board_height, float square_size, int num_imgs,
char* img_dir, char* leftimg_filename, char* rightimg_filename) {
Size board_size = Size(board_width, board_height);
int board_n = board_width * board_height;
for (int i = 1; i <= num_imgs; i++) {
char left_img[100], right_img[100];
sprintf(left_img, "%s%s%d.jpg", img_dir, leftimg_filename, i);
sprintf(right_img, "%s%s%d.jpg", img_dir, rightimg_filename, i);
img1 = imread(left_img, CV_LOAD_IMAGE_COLOR);
img2 = imread(right_img, CV_LOAD_IMAGE_COLOR);
cv::cvtColor(img1, gray1, CV_BGR2GRAY);
cv::cvtColor(img2, gray2, CV_BGR2GRAY);
bool found1 = false, found2 = false;
found1 = cv::findChessboardCorners(img1, board_size, corners1,
CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);
found2 = cv::findChessboardCorners(img2, board_size, corners2,
CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);
if (found1)
{
cv::cornerSubPix(gray1, corners1, cv::Size(5, 5), cv::Size(-1, -1),
cv::TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 30, 0.1));
cv::drawChessboardCorners(gray1, board_size, corners1, found1);
}
if (found2)
{
cv::cornerSubPix(gray2, corners2, cv::Size(5, 5), cv::Size(-1, -1),
cv::TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 30, 0.1));
cv::drawChessboardCorners(gray2, board_size, corners2, found2);
}
vector<cv::Point3d> obj;
for( int i = 0; i < board_height; ++i )
for( int j = 0; j < board_width; ++j )
obj.push_back(Point3d(double( (float)j * square_size ), double( (float)i * square_size ), 0));
if (found1 && found2) {
cout << i << ". Found corners!" << endl;
imagePoints1.push_back(corners1);
imagePoints2.push_back(corners2);
object_points.push_back(obj);
}
}
for (int i = 0; i < imagePoints1.size(); i++) {
vector< Point2d > v1, v2;
for (int j = 0; j < imagePoints1[i].size(); j++) {
v1.push_back(Point2d((double)imagePoints1[i][j].x, (double)imagePoints1[i][j].y));
v2.push_back(Point2d((double)imagePoints2[i][j].x, (double)imagePoints2[i][j].y));
}
left_img_points.push_back(v1);
right_img_points.push_back(v2);
}
}
int main(int argc, char const *argv[])
{
int board_width, board_height, num_imgs;
float square_size;
char* img_dir;
char* leftimg_filename;
char* rightimg_filename;
char* out_file;
static struct poptOption options[] = {
{ "board_width",'w',POPT_ARG_INT,&board_width,0,"Checkerboard width","NUM" },
{ "board_height",'h',POPT_ARG_INT,&board_height,0,"Checkerboard height","NUM" },
{ "square_size",'s',POPT_ARG_FLOAT,&square_size,0,"Checkerboard square size","NUM" },
{ "num_imgs",'n',POPT_ARG_INT,&num_imgs,0,"Number of checkerboard images","NUM" },
{ "img_dir",'d',POPT_ARG_STRING,&img_dir,0,"Directory containing images","STR" },
{ "leftimg_filename",'l',POPT_ARG_STRING,&leftimg_filename,0,"Left image prefix","STR" },
{ "rightimg_filename",'r',POPT_ARG_STRING,&rightimg_filename,0,"Right image prefix","STR" },
{ "out_file",'o',POPT_ARG_STRING,&out_file,0,"Output calibration filename (YML)","STR" },
POPT_AUTOHELP
{ NULL, 0, 0, NULL, 0, NULL, NULL }
};
POpt popt(NULL, argc, argv, options, 0);
int c;
while((c = popt.getNextOpt()) >= 0) {}
load_image_points(board_width, board_height, square_size, num_imgs, img_dir, leftimg_filename, rightimg_filename);
printf("Starting Calibration\n");
cv::Matx33d K1, K2, R;
cv::Vec3d T;
cv::Vec4d D1, D2;
int flag = 0;
flag |= cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC;
flag |= cv::fisheye::CALIB_CHECK_COND;
flag |= cv::fisheye::CALIB_FIX_SKEW;
//flag |= cv::fisheye::CALIB_FIX_K2;
//flag |= cv::fisheye::CALIB_FIX_K3;
//flag |= cv::fisheye::CALIB_FIX_K4;
cv::fisheye::stereoCalibrate(object_points, left_img_points, right_img_points,
K1, D1, K2, D2, img1.size(), R, T, flag,
cv::TermCriteria(3, 12, 0));
cv::FileStorage fs1(out_file, cv::FileStorage::WRITE);
fs1 << "K1" << Mat(K1);
fs1 << "K2" << Mat(K2);
fs1 << "D1" << D1;
fs1 << "D2" << D2;
fs1 << "R" << Mat(R);
fs1 << "T" << T;
printf("Done Calibration\n");
printf("Starting Rectification\n");
cv::Mat R1, R2, P1, P2, Q;
cv::fisheye::stereoRectify(K1, D1, K2, D2, img1.size(), R, T, R1, R2, P1, P2,
Q, CV_CALIB_ZERO_DISPARITY, img1.size(), 0.0, 1.1);
fs1 << "R1" << R1;
fs1 << "R2" << R2;
fs1 << "P1" << P1;
fs1 << "P2" << P2;
fs1 << "Q" << Q;
printf("Done Rectification\n");
return 0;
}
================================================
FILE: popt_pp.h
================================================
#ifndef _INCLUDED_POPT_PP_H_
#define _INCLUDED_POPT_PP_H_
#include <popt.h>
class POpt{
protected:
poptContext con;
public:
// creation and deletion
POpt(const char *name, int argc, const char **argv,
const poptOption *options, int flags)
{con = poptGetContext(name,argc,argv,options,flags);}
POpt(const char *name, int argc, char **argv,
const poptOption *options, int flags)
{con = poptGetContext(name,argc,(const char **)argv,options,flags);}
~POpt()
{poptFreeContext(con);}
// functions for processing options
int getNextOpt()
{return(poptGetNextOpt(con));}
void ignoreOptions()
{while(getNextOpt() >= 0);}
const char *getOptArg()
{return(poptGetOptArg(con));}
const char *strError(int error)
{return(poptStrerror(error));}
const char *badOption(int flags = POPT_BADOPTION_NOALIAS)
{return(poptBadOption(con,flags));}
// processing other arguments
const char *getArg()
{return(poptGetArg(con));}
void ignoreArgs()
{while(getArg());}
};
#endif
gitextract_oy4bozyl/ ├── .gitignore ├── CMakeLists.txt ├── README.md ├── calibrate.cpp └── popt_pp.h
SYMBOL INDEX (6 symbols across 2 files)
FILE: calibrate.cpp
function load_image_points (line 19) | void load_image_points(int board_width, int board_height, float square_s...
function main (line 76) | int main(int argc, char const *argv[])
FILE: popt_pp.h
function class (line 6) | class POpt{
function getNextOpt (line 21) | int getNextOpt()
function ignoreOptions (line 23) | void ignoreOptions()
function ignoreArgs (line 35) | void ignoreArgs()
Condensed preview — 5 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (8K chars).
[
{
"path": ".gitignore",
"chars": 249,
"preview": "# Compiled Object files\n*.slo\n*.lo\n*.o\n*.obj\n\n# Precompiled Headers\n*.gch\n*.pch\n\n# Compiled Dynamic libraries\n*.so\n*.dyl"
},
{
"path": "CMakeLists.txt",
"chars": 270,
"preview": "cmake_minimum_required(VERSION 2.8.11)\nproject(FISHEYE_STEREO)\n\nset(CMAKE_INCLUDE_CURRENT_DIR ON)\n\nfind_package(OpenCV R"
},
{
"path": "README.md",
"chars": 1191,
"preview": "## OpenCV C++ Stereo Fisheye Calibration\n\n_**Note**_: I don't actively maintain this repository anymore. PRs are more th"
},
{
"path": "calibrate.cpp",
"chars": 5103,
"preview": "#include <opencv2/core/core.hpp>\n#include <opencv2/calib3d/calib3d.hpp>\n#include <opencv2/highgui/highgui.hpp>\n#include "
},
{
"path": "popt_pp.h",
"chars": 1034,
"preview": "#ifndef _INCLUDED_POPT_PP_H_\n#define _INCLUDED_POPT_PP_H_\n\n#include <popt.h>\n\nclass POpt{\nprotected:\n poptContext con;\n"
}
]
About this extraction
This page contains the full source code of the sourishg/fisheye-stereo-calibration GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 5 files (7.7 KB), approximately 2.6k tokens, and a symbol index with 6 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.