基于opencv实现2D图像的拼接及融合

该文提供了一个C++代码示例,利用OpenCV库进行常规图像拼接,并通过泊松融合技术处理拼接后的突兀区域。代码读取像素坐标文件,计算homography矩阵,应用warpPerspective进行透视变换,并执行两次泊松融合以实现平滑过渡。
摘要由CSDN通过智能技术生成

本文实现常规图像的拼接和基于泊松融合来消除突兀区域,(废话不多说)直接上代码,有问题的欢迎指正和沟通交流

#include <iostream>
#include <io.h>
#include <fstream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/photo.hpp>

#include <opencv.hpp>
using namespace cv;
using namespace std;

int main(int argc, char** argv) {

std::vector<cv::Point2f> vec_src_pts, vec_tgt_pts;
        std::ifstream if_src_coord("D:/3Dsecond development/2Dpinjie/image/2_pix_coord.txt");
        std::ifstream if_tgt_coord("D:/3Dsecond development/2Dpinjie/image/1_pix_coord.txt");
        std::string src_path = "D:/3Dsecond development/2Dpinjie/image/2.jpg";
        std::string tgt_path = "D:/3Dsecond development/2Dpinjie/image/1.jpg";
        cv::Mat src = cv::imread(src_path, 0);
        cv::Mat tgt = cv::imread(tgt_path, 0);

        int h = src.rows, w = tgt.cols + src.cols;
        int tgt_h = tgt.rows, tgt_w = tgt.cols;
        int src_h = src.rows, src_w = src.cols;

        cv::Mat test_img = cv::Mat::zeros(cv::Size(2 * w, h), CV_8UC1);
std::string src_tmp, tgt_tmp;
        int delta_x = src.cols;
        int delta_y = 0;
        cv::Mat T = (Mat_<double>(2, 3) << 1, 0, 0, 0, 1, 0);
        cv::Mat tgt_after;
        // cv::warpAffine(tgt, tgt_after, T, tgt.size() + cv::Size(abs(delta_x), abs(delta_y)));
        while (std::getline(if_src_coord, src_tmp)) {
            std::vector<std::string> tokens = split(src_tmp, ',');
            float x = std::atof(tokens[0].c_str());
            float y = std::atof(tokens[1].c_str());
            std::cout << "x, y: " << x << ", " << y << std::endl;
            cv::Point2f pt_tmp(x, y);
            vec_src_pts.push_back(pt_tmp);
        }
        while (std::getline(if_tgt_coord, tgt_tmp)) {
            std::vector<std::string> tokens = split(tgt_tmp, ',');
            float x = std::atof(tokens[0].c_str()); // +src.cols;
            float y = std::atof(tokens[1].c_str());
            std::cout << x << ", ---" << y << std::endl;
            cv::Point2f pt_tmp(x, y);
            vec_tgt_pts.push_back(pt_tmp);
        }
        if_src_coord.close();
        if_tgt_coord.close();
        std::cout << "point num: " << vec_src_pts.size() << ", " << vec_tgt_pts.size() << std::endl;
        cv::Mat H = cv::findHomography(vec_src_pts, vec_tgt_pts);

fs.release();
        // cv::Mat trans_2D = (cv::Mat_<double>(3, 3) << 0.984798, -0.000890, 5896.0874, -0.0213373, 0.9949, 89.6496, 0, 0, 1.0);
        // H = trans_2D;
        cv::Mat warp_img;
        cv::warpPerspective(src, warp_img, H, cv::Size(w, h));     //
        src.release();
        cv::Mat res_img = cv::Mat::zeros(cv::Size(w, h), CV_8UC1);
        cv::Rect roi = cv::Rect(0, 0, tgt_w, tgt_h);
        tgt.copyTo(res_img(roi));        //生成的res_image是第一图的一部分
        cv::Mat image1, image2, image3, image4, image5;
        cv::threshold(res_img, image1, 0, 255, THRESH_BINARY);
        cv::threshold(warp_img, image2, 0, 255, THRESH_BINARY);
        cv::bitwise_and(image1, image2, image3);
        cv::Rect infor = cv::boundingRect(image3);
        cv::Mat imagetwo1 = cv::Mat::zeros(cv::Size(w, h), CV_8UC1);
        cv::Mat imagetwo2 = cv::Mat::zeros(cv::Size(w, h), CV_8UC1);
        cv::Mat imageone = cv::Mat::zeros(cv::Size(w, h), CV_8UC1);
        cv::Mat imagethree = cv::Mat::zeros(cv::Size(w, h), CV_8UC1);
        cv::Rect roifirst = cv::Rect(0, 0, infor.x, tgt_h);
        cv::Rect roilast = cv::Rect(0, 0, infor.x + infor.width, tgt_h);
        image4 = res_img(roifirst);
        image4.copyTo(imageone(roifirst));
        imagetwo1 = res_img - imageone;
        image5 = warp_img(roilast);
        image5.copyTo(imagetwo2(roilast));
        imagethree = warp_img - imagetwo2;

res_img += warp_img;       //直接把两张图进行叠加
        cv::Mat resultimage;
        resultimage = imageone + (imagetwo1 * 0.7 + imagetwo2 * 0.3) + imagethree;
        cv::Mat imgGuided, imgFilter;

//第一次泊松融合
        //目标 
        cv::Rect roifirstronghe = cv::Rect(infor.x - 20, 0, 50, tgt_h);
        cv::Mat srcimg1 = tgt(roifirstronghe);
        //背景 dst
        Mat srcimg_mask1 = 255 * Mat::ones(srcimg1.rows, srcimg1.cols, srcimg1.depth());//目标影像的

        // The location of the center of the src in the dst
        Point center(infor.x + 5, tgt_h / 2);

        // Seamlessly clone src into dst and put the results in output
        Mat normal_clone;
        cvtColor(srcimg1, srcimg1, COLOR_GRAY2BGR);
        cvtColor(resultimage, resultimage, COLOR_GRAY2BGR);
        resultimage.copyTo(imgGuided);
        seamlessClone(srcimg1, resultimage, srcimg_mask1, center, normal_clone, NORMAL_CLONE);

        //第二次泊松融合
        //目标 
        cv::Rect roilastronghe = cv::Rect(infor.x + infor.width - 600, 0, 1200, tgt_h);
        cv::Mat srcimg2 = warp_img(roilastronghe);
        //背景 dst
        Mat srcimg_mask2 = 255 * Mat::ones(srcimg2.rows, srcimg2.cols, srcimg2.depth());//目标影像的

        // The location of the center of the src in the dst
        Point center2(infor.x + infor.width, tgt_h / 2);

        // Seamlessly clone src into dst and put the results in output
        Mat normal_clone2;

        cvtColor(srcimg2, srcimg2, COLOR_GRAY2BGR);
        seamlessClone(srcimg2, normal_clone, srcimg_mask2, center2, normal_clone2, NORMAL_CLONE);
        resultimage = normal_clone2.clone();

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值