MYNT-EYE-S-SDK/src/mynteye/api/processor/rectify_processor.cc

194 lines
6.3 KiB
C++
Raw Normal View History

2018-05-10 14:46:34 +08:00
// Copyright 2018 Slightech Co., Ltd. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
2018-10-27 21:24:04 +08:00
#include "mynteye/api/processor/rectify_processor.h"
#include <utility>
2018-04-27 09:58:53 +08:00
2018-04-28 12:44:15 +08:00
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/imgproc/imgproc.hpp>
2018-09-04 15:12:04 +08:00
#include "mynteye/logger.h"
2018-10-27 21:24:04 +08:00
#include "mynteye/device/device.h"
2018-04-28 12:44:15 +08:00
2018-04-27 09:58:53 +08:00
MYNTEYE_BEGIN_NAMESPACE
const char RectifyProcessor::NAME[] = "RectifyProcessor";
2018-06-01 10:32:36 +08:00
RectifyProcessor::RectifyProcessor(
std::shared_ptr<Device> device, std::int32_t proc_period)
: Processor(std::move(proc_period)), device_(device) {
2018-06-01 10:32:36 +08:00
VLOG(2) << __func__ << ": proc_period=" << proc_period;
NotifyImageParamsChanged();
2018-04-27 09:58:53 +08:00
}
RectifyProcessor::~RectifyProcessor() {
VLOG(2) << __func__;
}
std::string RectifyProcessor::Name() {
return NAME;
}
void RectifyProcessor::NotifyImageParamsChanged() {
auto in_left = device_->GetIntrinsics(Stream::LEFT);
auto in_right = device_->GetIntrinsics(Stream::RIGHT);
2019-01-04 15:09:21 +08:00
if (in_left->calib_model == CalibrationModel::CALIB_MODEL_PINHOLE) {
InitParams(
*std::dynamic_pointer_cast<IntrinsicsPinhole>(in_left),
*std::dynamic_pointer_cast<IntrinsicsPinhole>(in_right),
device_->GetExtrinsics(Stream::RIGHT, Stream::LEFT));
2019-01-04 15:09:21 +08:00
} else if (in_left->calib_model ==
CalibrationModel::CALIB_MODEL_KANNALA_BRANDT) {
InitParams(
*std::dynamic_pointer_cast<IntrinsicsEquidistant>(in_left),
*std::dynamic_pointer_cast<IntrinsicsEquidistant>(in_right),
device_->GetExtrinsics(Stream::RIGHT, Stream::LEFT));
} else {
// toido
}
}
2018-04-27 09:58:53 +08:00
Object *RectifyProcessor::OnCreateOutput() {
2018-04-28 12:44:15 +08:00
return new ObjMat2();
2018-04-27 09:58:53 +08:00
}
2018-04-28 13:37:25 +08:00
bool RectifyProcessor::OnProcess(
2018-04-27 09:58:53 +08:00
Object *const in, Object *const out, Processor *const parent) {
2018-09-11 10:19:25 +08:00
MYNTEYE_UNUSED(parent)
2018-04-28 12:44:15 +08:00
const ObjMat2 *input = Object::Cast<ObjMat2>(in);
ObjMat2 *output = Object::Cast<ObjMat2>(out);
cv::remap(input->first, output->first, map11, map12, cv::INTER_LINEAR);
cv::remap(input->second, output->second, map21, map22, cv::INTER_LINEAR);
2018-10-26 15:39:34 +08:00
output->first_id = input->first_id;
2018-11-05 17:50:15 +08:00
output->first_data = input->first_data;
2018-10-26 15:39:34 +08:00
output->second_id = input->second_id;
2018-11-05 17:50:15 +08:00
output->second_data = input->second_data;
2018-04-28 13:37:25 +08:00
return true;
2018-04-28 12:44:15 +08:00
}
void RectifyProcessor::InitParams(
IntrinsicsPinhole in_left,
IntrinsicsPinhole in_right,
Extrinsics ex_right_to_left) {
2018-04-28 12:44:15 +08:00
cv::Size size{in_left.width, in_left.height};
cv::Mat M1 =
(cv::Mat_<double>(3, 3) << in_left.fx, 0, in_left.cx, 0, in_left.fy,
in_left.cy, 0, 0, 1);
cv::Mat M2 =
(cv::Mat_<double>(3, 3) << in_right.fx, 0, in_right.cx, 0, in_right.fy,
in_right.cy, 0, 0, 1);
cv::Mat D1(1, 5, CV_64F, in_left.coeffs);
cv::Mat D2(1, 5, CV_64F, in_right.coeffs);
cv::Mat R =
2018-07-22 10:42:15 +08:00
(cv::Mat_<double>(3, 3) << ex_right_to_left.rotation[0][0],
ex_right_to_left.rotation[0][1], ex_right_to_left.rotation[0][2],
ex_right_to_left.rotation[1][0], ex_right_to_left.rotation[1][1],
ex_right_to_left.rotation[1][2], ex_right_to_left.rotation[2][0],
ex_right_to_left.rotation[2][1], ex_right_to_left.rotation[2][2]);
cv::Mat T(3, 1, CV_64F, ex_right_to_left.translation);
2018-04-28 12:44:15 +08:00
VLOG(2) << "InitParams size: " << size;
VLOG(2) << "M1: " << M1;
VLOG(2) << "M2: " << M2;
VLOG(2) << "D1: " << D1;
VLOG(2) << "D2: " << D2;
VLOG(2) << "R: " << R;
VLOG(2) << "T: " << T;
cv::Rect left_roi, right_roi;
cv::stereoRectify(
M1, D1, M2, D2, size, R, T, R1, R2, P1, P2, Q, cv::CALIB_ZERO_DISPARITY,
0, size, &left_roi, &right_roi);
cv::initUndistortRectifyMap(M1, D1, R1, P1, size, CV_16SC2, map11, map12);
cv::initUndistortRectifyMap(M2, D2, R2, P2, size, CV_16SC2, map21, map22);
2018-04-27 09:58:53 +08:00
}
2019-01-04 15:09:21 +08:00
// enum class CalibrationModel : std::uint8_t {
// /** Unknow */
// CALIB_MODEL_UNKNOW = 0,
// /** Pinhole */
// CALIB_MODEL_PINHOLE = 1,
// /** Equidistant: KANNALA_BRANDT */
// CALIB_MODEL_KANNALA_BRANDT = 2,
// // CALIB_MODEL_SCARAMUZZA,
// // CALIB_MODEL_MEI,
// };
// /**
// * @ingroup calibration
// * Stream intrinsics (Equidistant: KANNALA_BRANDT)
// */
// struct MYNTEYE_API IntrinsicsEquidistant : public IntrinsicsBase {
// IntrinsicsEquidistant() {
// calib_model = CalibrationModel::CALIB_MODEL_KANNALA_BRANDT;
// }
// /** The width of the image in pixels */
// std::uint16_t width;
// /** The height of the image in pixels */
// std::uint16_t height;
// /** The distortion coefficients */
// double k2;
// double k3;
// double k4;
// double k5;
// double mu;
// double mv;
// double u0;
// double v0;
// };
void RectifyProcessor::InitParams(
IntrinsicsEquidistant in_left,
IntrinsicsEquidistant in_right,
Extrinsics ex_right_to_left) {
cv::Size size{in_left.width, in_left.height};
cv::Mat M1 =
(cv::Mat_<double>(3, 3) << 1.0, 0, 1.0, 0, 1.0,
1.0, 0, 0, 1);
cv::Mat M2 =
(cv::Mat_<double>(3, 3) << 1.0, 0, 1.0, 0, 1.0,
1.0, 0, 0, 1);
cv::Mat D1(1, 8, CV_64F, in_left.coeffs);
cv::Mat D2(1, 8, CV_64F, in_right.coeffs);
cv::Mat R =
(cv::Mat_<double>(3, 3) << ex_right_to_left.rotation[0][0],
ex_right_to_left.rotation[0][1], ex_right_to_left.rotation[0][2],
ex_right_to_left.rotation[1][0], ex_right_to_left.rotation[1][1],
ex_right_to_left.rotation[1][2], ex_right_to_left.rotation[2][0],
ex_right_to_left.rotation[2][1], ex_right_to_left.rotation[2][2]);
cv::Mat T(3, 1, CV_64F, ex_right_to_left.translation);
VLOG(2) << "InitParams size: " << size;
VLOG(2) << "M1: " << M1;
VLOG(2) << "M2: " << M2;
VLOG(2) << "D1: " << D1;
VLOG(2) << "D2: " << D2;
VLOG(2) << "R: " << R;
VLOG(2) << "T: " << T;
cv::Rect left_roi, right_roi;
cv::stereoRectify(
M1, D1, M2, D2, size, R, T, R1, R2, P1, P2, Q, cv::CALIB_ZERO_DISPARITY,
0, size, &left_roi, &right_roi);
cv::initUndistortRectifyMap(M1, D1, R1, P1, size, CV_16SC2, map11, map12);
cv::initUndistortRectifyMap(M2, D2, R2, P2, size, CV_16SC2, map21, map22);
}
2018-04-27 09:58:53 +08:00
MYNTEYE_END_NAMESPACE