图像处理之图像拼接三

图像处理之图像拼接三

基于最佳缝合线的拼接:

一个图像如何求取最佳缝合线呢。

    //查找接缝
    Ptr<SeamFinder> seam_finder;
    seam_finder = new detail::GraphCutSeamFinder(GraphCutSeamFinderBase::COST_COLOR);
    seam_finder->find(images_warped_f, corners, masks_warped);

这个是opencv的代码 可以看出需要知道conners。目前怎么求conners还没搞清楚

以上是两个图像以及它们分别的最佳缝合线,其实是一个,因为这个两个图像没有拼接。OK

手动把这两个拼接在一起,也就是拼接后的模板。同时把左图和右图也贴上,三个图像大小一致,且都是拼接后的图像

上拉普拉斯融合代码

// SurfTest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <string.h>
#include <atlstr.h>
#include <assert.h>
#include <math.h>
#include <float.h>
#include <limits.h>
#include <time.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include <cstring>
//#include <opencv2/stitching.hpp>
#include <iostream>
#include <fstream>

using namespace cv;
using namespace std;

//int _tmain(int argc, _TCHAR* argv[])
//{
//
//    CString imgpath="E:\\项目文件\\周信达\\显微镜样品测试\\显微镜样品测试\\介质末\\";
//    CString imgname="ml.jpg";
//    CString filepath;
//    filepath=imgpath+imgname;
//    IplImage *testimg=cvLoadImage(filepath,-1);
//    CString savepath="E:\\项目文件\\周信达\\显微镜样品测试\\显微镜样品测试\\介质末\\6\\";
//    for (int i=0;i<8;i++)
//    {
//        for (int j=0;j<7;j++)
//        {
//            CString saveimgpath;
//            CString saveimgname;
//            saveimgname.Format("0-%d-%d.jpg",i,j);
//            saveimgpath=savepath+saveimgname;
//            cvSaveImage(saveimgpath,testimg);
//        }
//    }
//    cvReleaseImage(&testimg);
//    printf("success");
//    system("pause");
//}

/************************************************************************/
/* 说明:
*金字塔从下到上依次为 [0,1,...,level-1] 层
*blendMask 为图像的掩模
*maskGaussianPyramid为金字塔每一层的掩模
*resultLapPyr 存放每层金字塔中直接用左右两图Laplacian变换拼成的图像
*/
/************************************************************************/

class LaplacianBlending {
private:
    Mat_<Vec3f> left;
    Mat_<Vec3f> right;
    Mat_<float> blendMask;

    vector<Mat_<Vec3f> > leftLapPyr,rightLapPyr,resultLapPyr;//Laplacian Pyramids
    Mat leftHighestLevel, rightHighestLevel, resultHighestLevel;
    vector<Mat_<Vec3f> > maskGaussianPyramid; //masks are 3-channels for easier multiplication with RGB

    int levels;

    void buildPyramids()
    {
        buildLaplacianPyramid(left,leftLapPyr,leftHighestLevel);
        buildLaplacianPyramid(right,rightLapPyr,rightHighestLevel);
        buildGaussianPyramid();
    }

    void buildGaussianPyramid()
    {//金字塔内容为每一层的掩模
        assert(leftLapPyr.size()>0);

        maskGaussianPyramid.clear();
        Mat currentImg;
        cvtColor(blendMask, currentImg, CV_GRAY2BGR);//store color img of blend mask into maskGaussianPyramid
        maskGaussianPyramid.push_back(currentImg); //0-level

        currentImg = blendMask;
        for (int l=1; l<levels+1; l++) {
            Mat _down;
            if (leftLapPyr.size() > l)
                pyrDown(currentImg, _down, leftLapPyr[l].size());
            else
                pyrDown(currentImg, _down, leftHighestLevel.size()); //lowest level

            Mat down;
            cvtColor(_down, down, CV_GRAY2BGR);
            maskGaussianPyramid.push_back(down);//add color blend mask into mask Pyramid
            currentImg = _down;
        }
    }

    void buildLaplacianPyramid(const Mat& img, vector<Mat_<Vec3f> >& lapPyr, Mat& HighestLevel)
    {
        lapPyr.clear();
        Mat currentImg = img;
        for (int l=0; l<levels; l++)
        {
            Mat down,up;
            pyrDown(currentImg, down);
            pyrUp(down, up,currentImg.size());
            Mat lap = currentImg - up;
            lapPyr.push_back(lap);
            currentImg = down;
        }
        currentImg.copyTo(HighestLevel);
    }

    Mat_<Vec3f> reconstructImgFromLapPyramid()
    {
        //将左右laplacian图像拼成的resultLapPyr金字塔中每一层
        //从上到下插值放大并相加,即得blend图像结果
        Mat currentImg = resultHighestLevel;
        for (int l=levels-1; l>=0; l--)
        {
            Mat up;

            pyrUp(currentImg, up, resultLapPyr[l].size());
            currentImg = up + resultLapPyr[l];
        }
        return currentImg;
    }

    void blendLapPyrs()
    {
        //获得每层金字塔中直接用左右两图Laplacian变换拼成的图像resultLapPyr
        resultHighestLevel = leftHighestLevel.mul(maskGaussianPyramid.back()) +
            rightHighestLevel.mul(Scalar(1.0,1.0,1.0) - maskGaussianPyramid.back());
        for (int l=0; l<levels; l++)
        {
            Mat A = leftLapPyr[l].mul(maskGaussianPyramid[l]);
            Mat antiMask = Scalar(1.0,1.0,1.0) - maskGaussianPyramid[l];
            Mat B = rightLapPyr[l].mul(antiMask);
            Mat_<Vec3f> blendedLevel = A + B;

            resultLapPyr.push_back(blendedLevel);
        }
    }

public:
    LaplacianBlending(const Mat_<Vec3f>& _left, const Mat_<Vec3f>& _right, const Mat_<float>& _blendMask, int _levels)://construct function, used in LaplacianBlending lb(l,r,m,4);
      left(_left),right(_right),blendMask(_blendMask),levels(_levels)
      {
          assert(_left.size() == _right.size());
          assert(_left.size() == _blendMask.size());
          buildPyramids();    //construct Laplacian Pyramid and Gaussian Pyramid
          blendLapPyrs();    //blend left & right Pyramids into one Pyramid
      };

      Mat_<Vec3f> blend() {
          return reconstructImgFromLapPyramid();//reconstruct Image from Laplacian Pyramid
      }
};

Mat_<Vec3f> LaplacianBlend(const Mat_<Vec3f>& l, const Mat_<Vec3f>& r, const Mat_<float>& m) {
    LaplacianBlending lb(l,r,m,4);
    return lb.blend();
}

int main()
{

    Mat l8u = imread("11.jpg");//左图
    Mat r8u = imread("22.jpg");//右图

    namedWindow("left",0);
    imshow("left",l8u); 

    namedWindow("right",0);
    imshow("right",r8u);

    Mat_<Vec3f> l; l8u.convertTo(l,CV_32F,1.0/255.0);//Vec3f表示有三个通道,即 l[row][column][depth]
    Mat_<Vec3f> r; r8u.convertTo(r,CV_32F,1.0/255.0);

    ////create blend mask matrix m
    //Mat_<float> m(l.rows,l.cols,0.0);                    //将m全部赋值为0
    //m(Range::all(),Range(0,m.cols/2)) = 1.0;    //取m全部行&[0,m.cols/2]列,赋值为1.0

    Mat_<float> m(l.rows,l.cols,0.0);
    Mat C=imread("newmark.jpg"); //模板
    for(int i=0;i<l.rows;i++)
    {
        for(int j=0;j<l.cols;j++)
        {
            if(C.at<Vec3b>(i,j)[0]!=0&&C.at<Vec3b>(i,j)[1]!=0&&C.at<Vec3b>(i,j)[2]!=0)  // 因为我要的只是位置
                m(i,j)=1.0;
        }
    }

    Mat_<Vec3f> blend = LaplacianBlend(l, r, m);

    Mat re;
    blend.convertTo(re,CV_8UC3,255);
    imwrite("blended.jpg",re); 

    namedWindow("blended",0);
    imshow("blended",blend);

    waitKey(0);
}

融合后的结果如下:

可以看到图像中间有一段拼接的非常好,其他地方是因为最佳缝合线是我手动生成的,存在误差。也就是说这个方法能走通,首先求解最佳缝合线,然后

上拉普拉斯融合即可。

时间: 2024-10-19 17:28:34

图像处理之图像拼接三的相关文章

iOS 图像处理 - 图像拼接

解决问题:将两个图像拼接在一起 前提:需要添加Framework:CoreGraphics.framework 源码: - (UIImage *) combine:(UIImage*)leftImage :(UIImage*)rightImage { CGFloat width = leftImage.size.width * 2; CGFloat height = leftImage.size.height; CGSize offScreenSize = CGSizeMake(width, h

图像处理之图像拼接

图像处理之图像拼接 图像拼接是图像处理中最为常见的一个功能,在不考虑旋转的情况下,也就是需要求取拼接亮就行了,然而当光源是点光源时,往往成像都是高斯性质, 这样会导致中间亮,两边暗或者四周暗,在这种情况下拼接,图像会存在很明显的拼接痕迹. 因此,本文针对上述拼接痕迹,设计了一种线性平滑的方法. 上代码: 1 CString leftimagepath; 2 CString rightimagepath; 3 leftimagepath.Format("0-%d-%d.jpg",i,j)

【数字图像处理之(三)】用图像增强谈灰度变换

前面已经说了,数字图像处理是指通过计算机对数字图像进行去除噪声.增强.复原.分割.提取特征等处理的方法和技术. 其主要目的有三个方面: 提高图像的视感质量,如进行图像的亮度.彩色变换,增强.抑制某些成分,对图像进行几何变换等,以改善图像的质量. 图像数据的变换.编码和压缩,以便于图像的存储和传输. 提取图像中所包含的某些特征或特殊信息,这些被提取的特征或信息往往为计算机分析图像提供便利.提取特征或信息的过程是模式识别或计算机视觉的预处理.提取的特征可以包括很多方面,如频域特征.灰度或颜色特征.边

图像处理之图像拼接---全景视频拼接

一.原理介绍 图像拼接(Image Stitching)是一种利用实景图像组成全景空间的技术,它将多幅图像拼接成一幅大尺度图像或360度全景图,图像拼接技术涉及到计算机视觉.计算机图形学.数字图像处理以及一些数学工具等技术.图像拼接其基本步骤主要包括以下几个方面:摄相机的标定.传感器图像畸变校正.图像的投影变换.匹配点选取.全景图像拼接(融合),以及亮度与颜色的均衡处理等,以下对各个步骤进行分析. 摄相机标定 由于安装设计,以及摄相机之间的差异,会造成视频图像之间有缩放(镜头焦距不一致造成).倾

图像处理之图像拼接二

上次的图像拼接效果还是不够好,有鬼影.所有一直在想怎么解决. 才发现基于拉普拉斯金字塔的图像融合是可以的.然后就找到原来还有最佳拼接缝一说.然后发现opencv高版本是带这个的,但是怎么解决呢? http://blog.csdn.net/wd1603926823/article/details/49536691 http://blog.csdn.net/hanshuning/article/details/41960401 http://blog.csdn.net/manji_lee/artic

图像处理URL

随笔分类 - 图像处理/图像增强等 图像增强: 图像复原: 图像重建: 图像分割: 图像特效: 图像匹配: 图像形态学处理: 图像几何处理: 图像正交变换: 人工智能: 跟踪: 图像处理之增强---图像模糊检测 摘要: 这种检测可以做宽动态的检测,也可应用稳像算法我们实现了拉普拉斯方差算法,该算法提供给我们一个浮点数来代表具体图像的"模糊度".该算法快速,简单且易于使用--用拉普拉斯算子与输入图像做卷积然后计算方差即可.如果方差低于预定义阈值,图像就被标记为"模糊"

图像处理资料分享

资料汇总:链接: http://pan.baidu.com/s/1c1bcDdY 密码: kn4w 资料精选: 1.冈萨雷斯,图像处理(Matlab版) 链接: http://pan.baidu.com/s/1hrzWXRA 密码: t3xw 2.数字图像处理与机器视觉Visual C++与Matlab实现[张铮] 链接: http://pan.baidu.com/s/1jHnbIa6 密码: 6ave 3.[MATLAB数字图像处理].张德丰.扫描版 链接: http://pan.baidu.

Atitit 图像处理的摩西五经attilax总结

1. 数字图像处理(第三版)1 2. 图像处理基础(第2版)(世界著名计算机教材精选)1 3. 计算机视觉特征提取与图像处理(第三版)2 4. OpenCV图像处理 2 4.1. 模式识别(英文版)(第4版) 西奥多里德斯著2 4.2. 图像处理,分析与机器视觉 第三版Sonka等著 艾海舟等译2 4.3. 计算机视觉:理论与算法 RichardSzeliski著2 1. 数字图像处理(第三版) 作者:(美)冈萨雷斯,(美)伍兹 著 Line 1: 第1章 绪论 Line 10: 第2章 数字图

数字图像处理之直方图均衡

直方图均衡化的原理在这里就不赘述了,网上有多此类的博文,也可以参考冈萨雷斯的<数字图像处理>(第三版)一书中的第三章中的相关介绍; 这里演示一下直方图均衡化的效果: 原图像如下: 经过直方图均衡化处理后: 可以看到图像的对比度整体有的很大的提升,原本模糊不清的细节也变得清晰起来 直方图均衡化的算法实现可以分为三个步骤: 第一步:获得原图像的概率密度函数(PDF). 1 for(i=0;i<rows;i++) 2 { 3 for(j=0;j<cols;j++) 4 { 5 n[Ima