#include "mainwindow.h"
#include "ui_mainwindow.h"
myMainWindow::myMainWindow(QWidget *parent) :
QMainWindow(parent)
{
ui.setupUi(this);
isCameraRunning = false;
isCalibrate = false;
boardSize.width = 9; // 棋盘格内角点个数
boardSize.height = 7;
numSeq = 0; // 存储照片的数量
numRequiredSnapshot = 15; // 标定需要的最少照片数
}
myMainWindow::~myMainWindow()
{
}
/******************打开相机********************/
void myMainWindow::on_startCameraButton_clicked()
{
// the webcam is not yet started
if (!isCameraRunning)
{
// open camera stream
capture.open(0);
if (!capture.isOpened())
return;
// set the acquired frame size to the size of its container
capture.set(cv::CAP_PROP_FRAME_WIDTH, ui.before_img->size().width());
capture.set(cv::CAP_PROP_FRAME_HEIGHT, ui.before_img->size().height());
isCameraRunning = true;
// start timer for acquiring the video
cameraTimer.start(33); // 33 ms = 30 fps
// at the timeout() event, execute the cameraTimerTimeout() method
connect(&cameraTimer, SIGNAL(timeout()), this, SLOT(cameraTimerTimeout()));
// update the user interface...
ui.startCameraButton->setText("Stop Camera");
ui.after_img->setText("Images needed for calibration: " + QString::number(numRequiredSnapshot));
if (numSeq < numRequiredSnapshot)
ui.startCalibrationButton->setEnabled(true);
}
else
{
if (!capture.isOpened())
return;
// stop timer
cameraTimer.stop();
// release camera stream
capture.release();
isCameraRunning = false;
// restore the user interface to the original status...
ui.startCameraButton->setText("Start Camera");
ui.before_img->clear();
ui.after_img->clear();
ui.startCalibrationButton->setEnabled(false);
ui.success_label->setText("");
}
}
void myMainWindow::cameraTimerTimeout()
{
if (isCameraRunning && capture.isOpened())
{
// store the frame to show in a Qt window
QImage frameToShow, frameUndistorted;
// get the current frame from the video stream
capture >> image;
// show the chessboard pattern
findAndDrawPoints();
// prepare the image for the Qt format...
// ... change color channel ordering (from BGR in our Mat to RGB in QImage)
cvtColor(image, image, CV_BGR2RGB);
// Qt image
// image.step is needed to properly show some images (due to padding byte added in the Mat creation)
frameToShow = QImage((const unsigned char*)(image.data), image.cols, image.rows, image.step, QImage::Format_RGB888);
// display on label
ui.before_img->setPixmap(QPixmap::fromImage(frameToShow));
// show undistorted (after calibration) frames
if (isCalibrate) {
// remap of undistorted frame and conversion in the Qt format
Mat undistorted = cameraCalib.remap(image);
frameUndistorted = QImage((uchar*)undistorted.data, undistorted.cols, undistorted.rows, undistorted.step, QImage::Format_RGB888);
ui.after_img->setPixmap(QPixmap::fromImage(frameUndistorted));
}
}
}
void myMainWindow::findAndDrawPoints()
{
std::vector<Point2f> imageCorners;
bool found = findChessboardCorners(image, boardSize, imageCorners);
// store the image to be used for the calibration process
if (found)
image.copyTo(imageSaved);
// show the found corners on screen, if any
drawChessboardCorners(image, boardSize, imageCorners, found);
}
/******************存储图片********************/
void myMainWindow::on_saveImagesButton_clicked()
{
if (isCameraRunning && imageSaved.data)
{
imageList.push_back(imageSaved);
numSeq++;
}
if (numRequiredSnapshot - numSeq >= 0) {
ui.success_label->setText("Still need to save images: " + QString::number(numRequiredSnapshot - numSeq));
}
}
/******************相机标定********************/
void myMainWindow::on_startCalibrationButton_clicked()
{
if (numSeq >= numRequiredSnapshot)
{
ui.startCalibrationButton->setEnabled(false);
// open chessboard images and extract corner points
successes = cameraCalib.addChessboardPoints(imageList, boardSize);
// calibrate the camera frames
Size calibSize = Size(ui.after_img->size().width(), ui.after_img->size().height());
cameraCalib.calibrate(calibSize);
isCalibrate = true;
ui.success_label->setText("Successful images used: " + QString::number(successes));
//显示内外参数
QString intrinsMatrix = Mat2QString(cameraCalib.cameraMatrix);
ui.intrinsParamLabel->setText("Intrinsic Matrix:\n" + intrinsMatrix);
//QString distorMatrix = Mat2QString(cameraCalib.distCoeffs);
//ui.intrinsParamLabel->setText("\n\nDistortion Matrix:\n" + distorMatrix);
QString rotationMatrix1 = Mat2QString(cameraCalib.rvecs[0]);
QString rotationMatrix2 = Mat2QString(cameraCalib.rvecs[1]);
QString rotationMatrix3 = Mat2QString(cameraCalib.rvecs[2]);
QString transMatrix = Mat2QString(cameraCalib.tvecs.front());
ui.extrinsParamLabel->setText("Rotation of Camera(the first image):\nr1:\n"+
rotationMatrix1 + "\nr2:\n" + rotationMatrix2 + "\nr3:\n"+ rotationMatrix3 +
"\n\nTranslation of Camera(the first iamge):\n" + transMatrix);
}
}
QString myMainWindow::Mat2QString(const Mat& src)
{
if (src.empty()) return QString();
stringstream stream;
stream << src;
return QString::fromStdString(stream.str());
}