/*
* stitcher.h - stitcher interface
*
* Copyright (c) 2017 Intel Corporation
*
* 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.
*
* Author: Wind Yuan <feng.yuan@intel.com>
* Author: Yinhang Liu <yinhangx.liu@intel.com>
*/
#ifndef XCAM_INTERFACE_STITCHER_H
#define XCAM_INTERFACE_STITCHER_H
#include <xcam_std.h>
#include <interface/data_types.h>
#include <vector>
#include <video_buffer.h>
#define XCAM_STITCH_FISHEYE_MAX_NUM 6
#define XCAM_STITCH_MAX_CAMERAS XCAM_STITCH_FISHEYE_MAX_NUM
#define XCAM_STITCH_MIN_SEAM_WIDTH 56
#define INVALID_INDEX (uint32_t)(-1)
namespace XCam {
enum StitchResMode {
StitchRes1080P,
StitchRes1080P4,
StitchRes4K
};
struct StitchInfo {
uint32_t merge_width[XCAM_STITCH_FISHEYE_MAX_NUM];
ImageCropInfo crop[XCAM_STITCH_FISHEYE_MAX_NUM];
FisheyeInfo fisheye_info[XCAM_STITCH_FISHEYE_MAX_NUM];
StitchInfo () {
xcam_mem_clear (merge_width);
}
};
struct ImageMergeInfo {
Rect left;
Rect right;
};
class Stitcher;
struct CalibrationInfo {
ExtrinsicParameter extrinsic;
IntrinsicParameter intrinsic;
};
struct CameraInfo {
CalibrationInfo calibration;
float round_angle_start;
float angle_range;;
};
class Stitcher
{
public:
struct RoundViewSlice {
float hori_angle_start;
float hori_angle_range;
uint32_t width;
uint32_t height;
RoundViewSlice ()
: hori_angle_start (0.0f), hori_angle_range (0.0f)
, width (0), height (0)
{}
};
struct CenterMark {
uint32_t slice_center_x;
uint32_t out_center_x;
CenterMark ()
: slice_center_x (0)
, out_center_x (0)
{}
};
struct ScaleFactor {
float left_scale;
float right_scale;
ScaleFactor ()
: left_scale (1.0f)
, right_scale (1.0f)
{}
};
struct ImageOverlapInfo {
Rect left;
Rect right;
Rect out_area;
};
struct CopyArea {
uint32_t in_idx;
Rect in_area;
Rect out_area;
CopyArea ()
: in_idx (INVALID_INDEX)
{}
};
typedef std::vector<CopyArea> CopyAreaArray;
public:
explicit Stitcher (uint32_t align_x, uint32_t align_y = 1);
virtual ~Stitcher ();
static SmartPtr<Stitcher> create_ocl_stitcher ();
static SmartPtr<Stitcher> create_soft_stitcher ();
bool set_bowl_config (const BowlDataConfig &config);
const BowlDataConfig &get_bowl_config () {
return _bowl_config;
}
bool set_camera_num (uint32_t num);
uint32_t get_camera_num () const {
return _camera_num;
}
bool set_camera_info (uint32_t index, const CameraInfo &info);
bool get_camera_info (uint32_t index, CameraInfo &info) const;
bool set_crop_info (uint32_t index, const ImageCropInfo &info);
bool get_crop_info (uint32_t index, ImageCropInfo &info) const;
bool is_crop_info_set () const {
return _is_crop_set;
}
//bool set_overlap_info (uint32_t index, const ImageOverlapInfo &info);
bool is_overlap_info_set () const {
return _is_overlap_set;
}
//bool set_stitch_info (const StitchInfo &stitch_info);
void set_output_size (uint32_t width, uint32_t height) {
_output_width = width; //XCAM_ALIGN_UP (width, XCAM_BLENDER_ALIGNED_WIDTH);
_output_height = height;
}
void get_output_size (uint32_t &width, uint32_t &height) const {
width = _output_width;
height = _output_height;
}
virtual XCamReturn stitch_buffers (const VideoBufferList &in_bufs, SmartPtr<VideoBuffer> &out_buf) = 0;
protected:
XCamReturn estimate_round_slices ();
virtual XCamReturn estimate_coarse_crops ();
XCamReturn mark_centers ();
XCamReturn estimate_overlap ();
XCamReturn update_copy_areas ();
const CenterMark &get_center (uint32_t idx) const {
return _center_marks[idx];
}
const RoundViewSlice &get_round_view_slice (uint32_t idx) const {
return _round_view_slices[idx];
}
const ImageOverlapInfo &get_overlap (uint32_t idx) const {
return _overlap_info[idx];
}
const ImageCropInfo &get_crop (uint32_t idx) const {
return _crop_info[idx];
}
const CopyAreaArray &get_copy_area () const {
return _copy_areas;
}
private:
XCAM_DEAD_COPY (Stitcher);
protected:
ImageCropInfo _crop_info[XCAM_STITCH_MAX_CAMERAS];
bool _is_crop_set;
//update after each feature match
ScaleFactor _scale_factors[XCAM_STITCH_MAX_CAMERAS];
private:
uint32_t _alignment_x, _alignment_y;
uint32_t _output_width, _output_height;
float _out_start_angle;
uint32_t _camera_num;
CameraInfo _camera_info[XCAM_STITCH_MAX_CAMERAS];
RoundViewSlice _round_view_slices[XCAM_STITCH_MAX_CAMERAS];
bool _is_round_view_set;
ImageOverlapInfo _overlap_info[XCAM_STITCH_MAX_CAMERAS];
BowlDataConfig _bowl_config;
bool _is_overlap_set;
//auto calculation
CenterMark _center_marks[XCAM_STITCH_MAX_CAMERAS];
bool _is_center_marked;
CopyAreaArray _copy_areas;
};
class BowlModel {
public:
typedef std::vector<PointFloat3> VertexMap;
typedef std::vector<PointFloat2> PointMap;
typedef std::vector<int32_t> IndexVector;
public:
BowlModel (const BowlDataConfig &config, const uint32_t image_width, const uint32_t image_height);
bool get_max_topview_area_mm (float &length_mm, float &width_mm);
bool get_topview_rect_map (
PointMap &texture_points,
uint32_t res_width, uint32_t res_height,
float length_mm = 0.0f, float width_mm = 0.0f);
bool get_stitch_image_vertex_model (
VertexMap &vertices, PointMap &texture_points, IndexVector &indeices,
uint32_t res_width, uint32_t res_height, float vertex_height);
bool get_bowlview_vertex_model (
VertexMap &vertices, PointMap &texture_points, IndexVector &indeices,
uint32_t res_width, uint32_t res_height);
bool get_topview_vertex_model (
VertexMap &vertices, PointMap &texture_points, IndexVector &indeices,
uint32_t res_width, uint32_t res_height);
private:
BowlDataConfig _config;
uint32_t _bowl_img_width, _bowl_img_height;
float _max_topview_width_mm;
float _max_topview_length_mm;
};
}
#endif //XCAM_INTERFACE_STITCHER_H