stop motion webcam calibration

Co-Authored-By: shun-iwasawa <shun.iwasawa@ghibli.jp>
This commit is contained in:
manongjohn 2022-02-22 11:55:37 -05:00
parent 7b4bc6c721
commit 39575f566d
8 changed files with 490 additions and 4 deletions

Binary file not shown.

View file

@ -0,0 +1,19 @@
### How to calibrate camera
1. Prepare the checkerboard
- Print out "checkerboard.tif" found in "tahomastuff/library/camera calibration".
- It would be better to paste the checkerboard pattern on some flat panel like cardboard.
2. Capture the pattern
- In the Stop Motion Controller's "Settings" tab, enable "Calibration" box
- Click "Start calibration".
- Take 10 snapshots of the checkerboard pattern in various positions and angles.
- Once the capturing is done, calibration will be automatically applied whenever the "Calibration" box is checked.
3. Export & load calibration settings
- Calibration settings will be saved under "tahomastuff/library/camera calibration" with name "[MACHINENAME]_[CAMERANAME]_[RESOLUTION].xml"
- The settings file will be overwritten after finishing the new calibration.
- You can export the file for backup, or load it afterwards.

View file

@ -1391,8 +1391,19 @@ void StopMotion::onTimeout() {
}
#endif
} else {
bool success = m_webcam->getWebcamImage(m_liveViewImage);
bool calibrateImage = !m_calibration.captureCue &&
m_calibration.isValid && m_calibration.isEnabled;
bool success =
m_webcam->getWebcamImage(m_liveViewImage, calibrateImage,
m_calibration.mapX, m_calibration.mapY);
if (success) {
// capture calibration reference
if (m_calibration.captureCue) {
m_calibration.captureCue = false;
emit(calibrationImageCaptured());
return;
}
setLiveViewImage();
} else {
m_hasLiveViewImage = false;

View file

@ -131,6 +131,19 @@ public:
// captured images.
TPointD m_liveViewDpi = TPointD(0.0, 0.0);
struct CalibrationData {
// Parameters
QString filePath;
bool captureCue = false;
cv::Size boardSize = {10, 7};
int refCaptured = 0;
std::vector<std::vector<cv::Point3f>> obj_points;
std::vector<std::vector<cv::Point2f>> image_points;
cv::Mat mapX, mapY;
bool isValid = false;
bool isEnabled = false;
} m_calibration;
// files and frames
void setXSheetFrameNumber(int frameNumber);
int getXSheetFrameNumber() { return m_xSheetFrameNumber; }
@ -283,6 +296,9 @@ signals:
// test shots
void updateTestShots();
// Calibration
void calibrationImageCaptured();
};
#endif // STOPMOTION_H

View file

@ -32,6 +32,7 @@
#include "flipbook.h"
#include "iocommand.h"
#include "tlevel_io.h"
#include "filebrowser.h"
// TnzQt includes
#include "toonzqt/filefield.h"
@ -64,6 +65,8 @@
#include <QToolTip>
#include <QSerialPort>
#include <QDomDocument>
#include <QHostInfo>
#include <QDesktopServices>
#ifdef _WIN32
#include <dshow.h>
@ -82,6 +85,7 @@ TEnv::StringVar CamCapSaveInPopupScene("CamCapSaveInPopupScene", "1");
TEnv::IntVar CamCapSaveInPopupAutoSubName("CamCapSaveInPopupAutoSubName", 1);
TEnv::IntVar CamCapSaveInPopupCreateSceneInFolder(
"CamCapSaveInPopupCreateSceneInFolder", 0);
TEnv::IntVar CamCapDoCalibration("CamCapDoCalibration", 0);
namespace {
@ -1233,6 +1237,26 @@ StopMotionController::StopMotionController(QWidget *parent) : QWidget(parent) {
innerSettingsLayout->addWidget(m_dslrFrame);
m_dslrFrame->hide();
// Calibration
m_calibrationUI.groupBox = new QGroupBox(tr("Calibration"), this);
m_calibrationUI.capBtn = new QPushButton(tr("Capture"), this);
m_calibrationUI.cancelBtn = new QPushButton(tr("Cancel"), this);
m_calibrationUI.newBtn = new QPushButton(tr("Start calibration"), this);
m_calibrationUI.loadBtn = new QPushButton(tr("Load"), this);
m_calibrationUI.exportBtn = new QPushButton(tr("Export"), this);
m_calibrationUI.label = new QLabel(this);
m_calibrationUI.groupBox->setCheckable(true);
m_calibrationUI.groupBox->setChecked(CamCapDoCalibration);
QAction *calibrationHelp =
new QAction(tr("Open Readme.txt for Camera calibration..."));
m_calibrationUI.groupBox->addAction(calibrationHelp);
m_calibrationUI.groupBox->setContextMenuPolicy(Qt::ActionsContextMenu);
m_calibrationUI.capBtn->hide();
m_calibrationUI.cancelBtn->hide();
m_calibrationUI.label->hide();
m_calibrationUI.exportBtn->setEnabled(false);
connect(calibrationHelp, SIGNAL(triggered()), this, SLOT(onCalibReadme()));
QVBoxLayout *webcamSettingsLayout = new QVBoxLayout;
webcamSettingsLayout->setSpacing(0);
webcamSettingsLayout->setMargin(5);
@ -1360,6 +1384,27 @@ StopMotionController::StopMotionController(QWidget *parent) : QWidget(parent) {
imageFrame->setLayout(imageLay);
webcamGridLay->addWidget(imageFrame, 6, 0, 1, 2);
// Calibration
QGridLayout *calibLay = new QGridLayout();
calibLay->setMargin(8);
calibLay->setHorizontalSpacing(3);
calibLay->setVerticalSpacing(5);
{
calibLay->addWidget(m_calibrationUI.newBtn, 0, 0);
calibLay->addWidget(m_calibrationUI.loadBtn, 0, 1);
calibLay->addWidget(m_calibrationUI.exportBtn, 0, 2);
QHBoxLayout *lay = new QHBoxLayout();
lay->setMargin(0);
lay->setSpacing(5);
lay->addWidget(m_calibrationUI.capBtn, 1);
lay->addWidget(m_calibrationUI.label, 0);
lay->addWidget(m_calibrationUI.cancelBtn, 1);
calibLay->addLayout(lay, 1, 0, 1, 3);
}
calibLay->setColumnStretch(0, 1);
m_calibrationUI.groupBox->setLayout(calibLay);
webcamGridLay->addWidget(m_calibrationUI.groupBox, 7, 0, 1, 2);
webcamSettingsLayout->addLayout(webcamGridLay);
webcamSettingsLayout->addStretch();
@ -1941,6 +1986,24 @@ StopMotionController::StopMotionController(QWidget *parent) : QWidget(parent) {
ret = ret && connect(m_stopMotion->m_webcam, SIGNAL(updateHistogram(cv::Mat)),
this, SLOT(onUpdateHistogramCalled(cv::Mat)));
// Calibration
ret = ret && connect(m_calibrationUI.groupBox, &QGroupBox::toggled,
[&](bool checked) {
CamCapDoCalibration = checked;
m_stopMotion->m_calibration.isEnabled = checked;
resetCalibSettingsFromFile();
});
ret = ret && connect(m_calibrationUI.capBtn, SIGNAL(clicked()), this,
SLOT(onCalibCapBtnClicked()));
ret = ret && connect(m_calibrationUI.newBtn, SIGNAL(clicked()), this,
SLOT(onCalibNewBtnClicked()));
ret = ret && connect(m_calibrationUI.cancelBtn, SIGNAL(clicked()), this,
SLOT(resetCalibSettingsFromFile()));
ret = ret && connect(m_calibrationUI.loadBtn, SIGNAL(clicked()), this,
SLOT(onCalibLoadBtnClicked()));
ret = ret && connect(m_calibrationUI.exportBtn, SIGNAL(clicked()), this,
SLOT(onCalibExportBtnClicked()));
// Lighting Connections
ret = ret &&
connect(m_screen1ColorFld, SIGNAL(colorChanged(const TPixel32 &, bool)),
@ -2024,6 +2087,9 @@ StopMotionController::StopMotionController(QWidget *parent) : QWidget(parent) {
ret = ret && connect(m_stopMotion, SIGNAL(updateTestShots()), this,
SLOT(onRefreshTests()));
// Calibration
ret = ret && connect(m_stopMotion, SIGNAL(calibrationImageCaptured()), this,
SLOT(onCalibImageCaptured()));
assert(ret);
m_placeOnXSheetCB->setChecked(
@ -2051,6 +2117,8 @@ StopMotionController::StopMotionController(QWidget *parent) : QWidget(parent) {
m_stopMotion->setToNextNewLevel();
m_saveInFileFld->setPath(m_stopMotion->getFilePath());
m_stopMotion->m_calibration.isEnabled = m_calibrationUI.groupBox->isChecked();
#ifndef _WIN32
m_directShowCB->hide();
#endif
@ -2773,6 +2841,12 @@ void StopMotionController::onCameraListComboActivated(int comboIndex) {
m_stopMotion->changeCameras(comboIndex);
m_stopMotion->updateStopMotionControls(m_stopMotion->m_usingWebcam);
if (m_calibrationUI.groupBox->isChecked() && comboIndex > 0) {
m_stopMotion->m_calibration.isValid = false;
m_calibrationUI.exportBtn->setEnabled(false);
if (m_stopMotion->m_usingWebcam) resetCalibSettingsFromFile();
}
}
//-----------------------------------------------------------------------------
@ -2862,6 +2936,10 @@ void StopMotionController::onNewWebcamResolutionSelected(int index) {
void StopMotionController::onResolutionComboActivated(const QString &itemText) {
m_stopMotion->setWebcamResolution(itemText);
m_stopMotion->m_calibration.isValid = false;
m_calibrationUI.exportBtn->setEnabled(false);
if (m_stopMotion->m_usingWebcam) resetCalibSettingsFromFile();
}
//-----------------------------------------------------------------------------
@ -3908,4 +3986,313 @@ void StopMotionController::clearTests() {
}
m_testHBoxes.clear();
}
}
}
//-----------------------------------------------------------------------------
void StopMotionController::onCalibCapBtnClicked() {
if (!m_stopMotion->m_hasLiveViewImage ||
m_stopMotion->m_liveViewStatus !=
m_stopMotion->LiveViewStatus::LiveViewOpen) {
DVGui::warning(tr("Cannot capture image unless live view is active."));
return;
}
m_stopMotion->m_calibration.captureCue = true;
}
//-----------------------------------------------------------------------------
void StopMotionController::onCalibNewBtnClicked() {
if (m_stopMotion->m_calibration.isValid) {
QString question = tr("Do you want to restart camera calibration?");
int ret =
DVGui::MsgBox(question, QObject::tr("Restart"), QObject::tr("Cancel"));
if (ret == 0 || ret == 2) return;
}
// initialize calibration parameter
m_stopMotion->m_calibration.filePath = getCurrentCalibFilePath();
m_stopMotion->m_calibration.captureCue = false;
m_stopMotion->m_calibration.refCaptured = 0;
m_stopMotion->m_calibration.obj_points.clear();
m_stopMotion->m_calibration.image_points.clear();
m_stopMotion->m_calibration.isValid = false;
// initialize label
m_calibrationUI.label->setText(
QString("%1/%2").arg(m_stopMotion->m_calibration.refCaptured).arg(10));
// swap UIs
m_calibrationUI.newBtn->hide();
m_calibrationUI.loadBtn->hide();
m_calibrationUI.exportBtn->hide();
m_calibrationUI.label->show();
m_calibrationUI.capBtn->show();
m_calibrationUI.cancelBtn->show();
}
//-----------------------------------------------------------------------------
void StopMotionController::resetCalibSettingsFromFile() {
if (m_calibrationUI.capBtn->isVisible()) {
// swap UIs
m_calibrationUI.label->hide();
m_calibrationUI.capBtn->hide();
m_calibrationUI.cancelBtn->hide();
m_calibrationUI.newBtn->show();
m_calibrationUI.loadBtn->show();
m_calibrationUI.exportBtn->show();
}
if (m_calibrationUI.groupBox->isChecked() &&
!m_stopMotion->m_calibration.isValid) {
QString calibFp = getCurrentCalibFilePath();
std::cout << calibFp.toStdString() << std::endl;
if (!calibFp.isEmpty() && QFileInfo(calibFp).exists()) {
cv::Mat intrinsic, distCoeffs, new_intrinsic;
cv::FileStorage fs(calibFp.toStdString(), cv::FileStorage::READ);
if (!fs.isOpened()) return;
std::string identifierStr;
fs["identifier"] >> identifierStr;
if (identifierStr != "OpenToonzCameraCalibrationSettings") return;
cv::Size resolution;
QSize currentResolution(m_stopMotion->m_webcam->getWebcamWidth(),
m_stopMotion->m_webcam->getWebcamHeight());
fs["resolution"] >> resolution;
if (currentResolution != QSize(resolution.width, resolution.height))
return;
fs["instrinsic"] >> intrinsic;
fs["distCoeffs"] >> distCoeffs;
fs["new_intrinsic"] >> new_intrinsic;
fs.release();
cv::Mat mapR = cv::Mat::eye(3, 3, CV_64F);
cv::initUndistortRectifyMap(
intrinsic, distCoeffs, mapR, new_intrinsic,
cv::Size(currentResolution.width(), currentResolution.height()),
CV_32FC1, m_stopMotion->m_calibration.mapX,
m_stopMotion->m_calibration.mapY);
m_stopMotion->m_calibration.isValid = true;
m_stopMotion->m_calibration.filePath = calibFp;
m_calibrationUI.exportBtn->setEnabled(true);
}
}
}
//-----------------------------------------------------------------------------
void StopMotionController::captureCalibrationRefImage(cv::Mat &image) {
cv::cvtColor(image, image, cv::COLOR_RGB2GRAY);
std::vector<cv::Point2f> corners;
bool found = cv::findChessboardCorners(
image, m_stopMotion->m_calibration.boardSize, corners,
cv::CALIB_CB_ADAPTIVE_THRESH | cv::CALIB_CB_FILTER_QUADS);
if (found) {
// compute corners in detail
cv::cornerSubPix(
image, corners, cv::Size(11, 11), cv::Size(-1, -1),
cv::TermCriteria(cv::TermCriteria::EPS | cv::TermCriteria::MAX_ITER, 30,
0.1));
// count up
m_stopMotion->m_calibration.refCaptured++;
// register corners
m_stopMotion->m_calibration.image_points.push_back(corners);
// register 3d points in real world space
std::vector<cv::Point3f> obj;
for (int i = 0; i < m_stopMotion->m_calibration.boardSize.width *
m_stopMotion->m_calibration.boardSize.height;
i++)
obj.push_back(cv::Point3f(i / m_stopMotion->m_calibration.boardSize.width,
i % m_stopMotion->m_calibration.boardSize.width,
0.0f));
m_stopMotion->m_calibration.obj_points.push_back(obj);
// needs 10 references
if (m_stopMotion->m_calibration.refCaptured < 10) {
// update label
m_calibrationUI.label->setText(
QString("%1/%2")
.arg(m_stopMotion->m_calibration.refCaptured)
.arg(10));
} else {
// swap UIs
m_calibrationUI.label->hide();
m_calibrationUI.capBtn->hide();
m_calibrationUI.cancelBtn->hide();
m_calibrationUI.newBtn->show();
m_calibrationUI.loadBtn->show();
m_calibrationUI.exportBtn->show();
cv::Mat intrinsic = cv::Mat(3, 3, CV_32FC1);
intrinsic.ptr<float>(0)[0] = 1.f;
intrinsic.ptr<float>(1)[1] = 1.f;
cv::Mat distCoeffs;
std::vector<cv::Mat> rvecs;
std::vector<cv::Mat> tvecs;
cv::calibrateCamera(m_stopMotion->m_calibration.obj_points,
m_stopMotion->m_calibration.image_points,
image.size(), intrinsic, distCoeffs, rvecs, tvecs);
cv::Mat mapR = cv::Mat::eye(3, 3, CV_64F);
cv::Mat new_intrinsic = cv::getOptimalNewCameraMatrix(
intrinsic, distCoeffs, image.size(),
0.0); // setting the last argument to 1.0 will include all source
// pixels in the frame
cv::initUndistortRectifyMap(
intrinsic, distCoeffs, mapR, new_intrinsic, image.size(), CV_32FC1,
m_stopMotion->m_calibration.mapX, m_stopMotion->m_calibration.mapY);
// save calibration settings
QString calibFp = getCurrentCalibFilePath();
cv::FileStorage fs(calibFp.toStdString(), cv::FileStorage::WRITE);
if (!fs.isOpened()) {
DVGui::warning(
tr("Failed to save calibration settings to %1.").arg(calibFp));
return;
}
fs << "identifier"
<< "OpenToonzCameraCalibrationSettings";
fs << "resolution" << cv::Size(m_stopMotion->m_webcam->getWebcamWidth(),
m_stopMotion->m_webcam->getWebcamHeight());
fs << "instrinsic" << intrinsic;
fs << "distCoeffs" << distCoeffs;
fs << "new_intrinsic" << new_intrinsic;
fs.release();
m_stopMotion->m_calibration.isValid = true;
m_calibrationUI.exportBtn->setEnabled(true);
}
}
}
//-----------------------------------------------------------------------------
QString StopMotionController::getCurrentCalibFilePath() {
QString cameraName = m_cameraListCombo->currentText();
if (cameraName.isEmpty()) return QString();
QString resolution = m_resolutionCombo->currentText();
QString hostName = QHostInfo::localHostName();
TFilePath folderPath = ToonzFolder::getLibraryFolder() + "camera calibration";
return folderPath.getQString() + "\\" + hostName + "_" + cameraName + "_" +
resolution + ".xml";
}
//-----------------------------------------------------------------------------
void StopMotionController::onCalibLoadBtnClicked() {
LoadCalibrationFilePopup popup(this);
QString fp = popup.getPath().getQString();
if (fp.isEmpty()) return;
try {
cv::FileStorage fs(fp.toStdString(), cv::FileStorage::READ);
if (!fs.isOpened())
throw TException(fp.toStdWString() + L": Can't open file");
std::string identifierStr;
fs["identifier"] >> identifierStr;
if (identifierStr != "OpenToonzCameraCalibrationSettings")
throw TException(fp.toStdWString() + L": Identifier does not match");
cv::Size resolution;
QSize currentResolution(m_stopMotion->m_webcam->getWebcamWidth(),
m_stopMotion->m_webcam->getWebcamHeight());
fs["resolution"] >> resolution;
if (currentResolution != QSize(resolution.width, resolution.height))
throw TException(fp.toStdWString() + L": Resolution does not match");
} catch (const TException &se) {
DVGui::warning(QString::fromStdWString(se.getMessage()));
return;
} catch (...) {
DVGui::error(tr("Couldn't load %1").arg(fp));
return;
}
if (m_stopMotion->m_calibration.isValid) {
QString question = tr("Overwriting the current calibration. Are you sure?");
int ret = DVGui::MsgBox(question, QObject::tr("OK"), QObject::tr("Cancel"));
if (ret == 0 || ret == 2) return;
m_stopMotion->m_calibration.isValid = false;
}
QString calibFp = getCurrentCalibFilePath();
TSystem::copyFile(TFilePath(calibFp), TFilePath(fp), true);
resetCalibSettingsFromFile();
}
//-----------------------------------------------------------------------------
void StopMotionController::onCalibExportBtnClicked() {
// just in case
if (!m_stopMotion->m_calibration.isValid) return;
if (!QFileInfo(getCurrentCalibFilePath()).exists()) return;
ExportCalibrationFilePopup popup(this);
QString fp = popup.getPath().getQString();
if (fp.isEmpty()) return;
try {
{
QFileInfo fs(fp);
if (fs.exists() && !fs.isWritable()) {
throw TSystemException(
TFilePath(fp),
L"The file cannot be saved: it is a read only file.");
}
}
TSystem::copyFile(TFilePath(fp), TFilePath(getCurrentCalibFilePath()),
true);
} catch (const TSystemException &se) {
DVGui::warning(QString::fromStdWString(se.getMessage()));
} catch (...) {
DVGui::error(tr("Couldn't save %1").arg(fp));
}
}
//-----------------------------------------------------------------------------
void StopMotionController::onCalibReadme() {
TFilePath readmeFp =
ToonzFolder::getLibraryFolder() + "camera calibration" + "readme.txt";
if (!TFileStatus(readmeFp).doesExist()) return;
if (TSystem::isUNC(readmeFp))
QDesktopServices::openUrl(QUrl(readmeFp.getQString()));
else
QDesktopServices::openUrl(QUrl::fromLocalFile(readmeFp.getQString()));
}
//-----------------------------------------------------------------------------
void StopMotionController::onCalibImageCaptured() {
cv::Mat camImage = m_stopMotion->m_webcam->getWebcamImage();
captureCalibrationRefImage(camImage);
}
//=============================================================================
ExportCalibrationFilePopup::ExportCalibrationFilePopup(QWidget *parent)
: GenericSaveFilePopup(tr("Export Camera Calibration Settings")) {
Qt::WindowFlags flags = windowFlags();
setParent(parent);
setWindowFlags(flags);
m_browser->enableGlobalSelection(false);
setFilterTypes(QStringList("xml"));
}
void ExportCalibrationFilePopup::showEvent(QShowEvent *e) {
FileBrowserPopup::showEvent(e);
setFolder(ToonzFolder::getLibraryFolder() + "camera calibration");
}
//=============================================================================
LoadCalibrationFilePopup::LoadCalibrationFilePopup(QWidget *parent)
: GenericLoadFilePopup(tr("Load Camera Calibration Settings")) {
Qt::WindowFlags flags = windowFlags();
setParent(parent);
setWindowFlags(flags);
m_browser->enableGlobalSelection(false);
setFilterTypes(QStringList("xml"));
}
void LoadCalibrationFilePopup::showEvent(QShowEvent *e) {
FileBrowserPopup::showEvent(e);
setFolder(ToonzFolder::getLibraryFolder() + "camera calibration");
}

View file

@ -10,6 +10,7 @@
#include "tfilepath.h"
#include "toonz/tproject.h"
#include "filebrowserpopup.h"
// TnzQt includes
#include "toonzqt/tabbar.h"
@ -236,6 +237,17 @@ class StopMotionController final : public QWidget {
QVBoxLayout *m_testsInsideLayout;
int m_testsImagesPerRow;
// calibration feature
struct CalibrationUI {
QPushButton *capBtn, *newBtn, *loadBtn, *cancelBtn, *exportBtn;
QLabel *label;
QGroupBox *groupBox;
} m_calibrationUI;
void captureCalibrationRefImage(cv::Mat &procImage);
QString getCurrentCalibFilePath();
public:
StopMotionController(QWidget *parent = 0);
~StopMotionController();
@ -415,8 +427,38 @@ protected slots:
void onRefreshTests();
void clearTests();
void onCalibCapBtnClicked();
void onCalibNewBtnClicked();
void resetCalibSettingsFromFile();
void onCalibLoadBtnClicked();
void onCalibExportBtnClicked();
void onCalibImageCaptured();
void onCalibReadme();
public slots:
void openSaveInFolderPopup();
};
//=============================================================================
class ExportCalibrationFilePopup final : public GenericSaveFilePopup {
Q_OBJECT
public:
ExportCalibrationFilePopup(QWidget *parent);
protected:
void showEvent(QShowEvent *) override;
};
//=============================================================================
class LoadCalibrationFilePopup final : public GenericLoadFilePopup {
Q_OBJECT
public:
LoadCalibrationFilePopup(QWidget *parent);
protected:
void showEvent(QShowEvent *) override;
};
#endif // STOPMOTIONCONTROLLER_H

View file

@ -92,7 +92,8 @@ int Webcam::getIndexOfResolution() {
//-----------------------------------------------------------------
bool Webcam::getWebcamImage(TRaster32P& tempImage) {
bool Webcam::getWebcamImage(TRaster32P& tempImage, bool useCalibration,
cv::Mat calibrationMapX, cv::Mat calibrationMapY) {
bool error = false;
cv::Mat imgOriginal;
cv::Mat imgCorrected;
@ -146,6 +147,14 @@ bool Webcam::getWebcamImage(TRaster32P& tempImage) {
cv::cvtColor(imgCorrected, imgCorrected, cv::COLOR_GRAY2BGRA);
}
// perform calibration
if (useCalibration) {
cv::remap(imgCorrected, imgCorrected, calibrationMapX, calibrationMapY,
cv::INTER_LINEAR);
}
m_webcamImage = imgCorrected;
int width = m_cvWebcam.get(3);
int height = m_cvWebcam.get(4);
int size = imgCorrected.total() * imgCorrected.elemSize();

View file

@ -41,7 +41,9 @@ public:
QCamera* getWebcam() { return m_webcam; }
void setWebcam(QCamera* camera);
bool initWebcam(int index = 0);
bool getWebcamImage(TRaster32P& tempImage);
bool getWebcamImage(TRaster32P& tempImage, bool useCalibration = false,
cv::Mat calibrationMapX = cv::Mat(),
cv::Mat calibrationMapY = cv::Mat());
bool translateIndex(int index);