// // lenz_stitcher.hpp // LenzCameraNativeModuleForRN // // Created by lr on 2023/2/8. // #ifndef lenz_stitcher_hpp #define lenz_stitcher_hpp #if __cplusplus && __has_include() #import #import #include #include #include #include #include #include #include #include #include #include using namespace cv; using namespace cv::detail; using namespace cv::ocl; using namespace std; #define STITCH_STATUS_INIT 0 #define STITCH_STATUS_CHECKING 1 #define STITCH_STATUS_STITCHING 2 #define STITCH_STATUS_FREE 3 #define STITCH_STATUS_FAILED 4 #define FEATURE_HEIGHT 300 #define STITCH_HEIGHT 300 #define BIG_STITCH_HEIGHT 1000 #define BIG_FEATURE_HEIGHT 800 #define MAX_SIZE 4000 // 缩略图的最大尺寸,长或宽都不能超过MAX_SIZE*MAX_SIZE,否则直接报错 #define BIG_MAX_SIZE 10000 // 拼接大图的最大尺寸, 长或宽都不能超过BIG_MAX_SIZE struct stitch_data { Mat scaled_gray_frame; float work_scale; vector good_keypoints; Mat descriptors; Mat homo = (Mat_(3, 3) << 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0); // store homography matrix to base image Mat base_homo = (Mat_(3, 3) << 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0); // store homography matrix to last base image }; struct LinePara { float k; float b; }; string test_image_path = ""; class LenzStitcher { public: string task_id = ""; string local_path = ""; int stitcher_status = STITCH_STATUS_INIT; // 0: initialized, 1: checking, 2: stitching, 3: free int failed_count = 0; // 当前连续失败的帧数 int failed_thresh = 10; // 连续5帧失败才返回失败 vector last_move_distances; // 记录存下来的最近10帧的移动距离,算均值,大于阈值的时候提示速度过快 float iou_thresh = 0.7; // iou低于该阈值的时候把这张图片存下来 float area_thresh = 0.5; // area threshold for green box float angle_thresh = 10; // angle threshold for green box float inline_thresh = 0.1; // 光流法匹配的点的比例至少要大于这个值,才认为是正确的映射矩阵 int matches_thresh = 10; // 前后两帧基于光流的匹配点的个数的阈值,低于该值则无法进行拼接 float check_match_conf = 0.2f; int frame_index = 0; vector last_warp_points; // 上一张存下来的图的四个点在拼接图上的坐标 int big_frame_index = 0; // 存下来的帧的信息 float total_shift_x = 0; float total_shift_y = 0; Mat last_frame; Mat last_stitch_image = Mat(); // 最后一张拼接缩略图 int last_direction = 0; // 上一帧的手机移动方向 vector last_angles = vector{90, 90, 90, 90}; vector last_scales = vector{1, 1, 1, 1}; string last_stitch_image_path = ""; // 拼接缩略图的本地路径 stitch_data last_check_data; // 上一帧的数据 string big_stitch_image_path = ""; // 拼接大图的本地路径 string test_image_path = ""; // test LenzStitcher(string input_id); int *ofcheck_stitch(Mat &frame, int const direction, int const is_last_one); // 输入每一帧实时产生拼接缩略图 bool get_big_image(int get_big_image); // 在收到当前帧是最后一帧的时候运行,会用之前存下来的帧数据产生最后的拼接大图 void remove_local_path(); }; bool is_good_homo(const vector &corners, const Mat &frame, float area_thresh, float angle_thresh); bool is_convex(const vector &corners); float calc_area(const vector &corners, const Mat &frame); float min_axis(vector input_list); float max_axis(vector input_list); float calc_angle(const vector &conners); float calc_vangle(const vector &conners); float calc_hangle(const vector &conners); void double_match(const Mat &query_des, const Mat &train_des, vector &good_matches, float check_match_conf); void single_match(const Mat &query_des, const Mat &train_des, vector &good_matches, float check_match_conf); void getFilePath(const char *path, const char *filename, char *filepath); void deleteFile(const char *path); bool isFloderexit(const char *path); void randomSelectKeyPoints(vector kpts, vector &pts, int max_num); void optimizeSeam(Mat &last_img, Mat &stitched_image, vector &corners); void getLinePara(float x1, float y1, float x2, float y2, LinePara &LP); float point_2_line(float k, float b, float k2, float x, float y); int get_direction(vector &frame_corners, vector &transpose_corners); float get_move_distance(vector &frame_center, vector &transpose_center); int dcmp(float x); float cross(Point2f a, Point2f b, Point2f c); float CPIA(vector a, vector b, int na, int nb); float SPIA(vector a, vector b, int na, int nb); Point2f get_intersection_point(Point2f a, Point2f b, Point2f c, Point2f d); float PolygonArea(vector p, int n); float single_quadrangle_iou(vector pts1, vector pts2); float single_box_iou(vector pts1, vector pts2); void stitch_big_image(Mat frame, vector angles, vector scales, int direction, int big_frame_index); void cylindrical_projection(Mat &img, Mat &output, float angle); void SphericalProjection(Mat& imgMat, Mat& output, float angle); void fill_contours(vector> contours, Mat &source_image, Mat &target_image); float angle_of_two_vector(Point2f &pt1, Point2f &pt2, Point2f &c); void calc_angles(vector &conners); #endif #endif