利用视差图合成新视点

来自这篇博客,利用视差图和普通图像合成新视点:

视差图
图像
#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int index(int m, int n){
    if (m>=0 && m<n)
        return m;
    else if (m<0)
        return 0;
    else if (m>=n)
        return n-1;
}

void obtainNewDispMap(const Mat &refDisp, Mat &dstDisp, float value){
    int height=refDisp.rows;
    int width=refDisp.cols;
    uchar* pSrcDispData=(uchar*) refDisp.data;
    float* pDstDispData=(float*) dstDisp.data;
    for (int j=0; j<height; j++){
        for (int i=0; i<width; i++){
            int disp=(int)pSrcDispData[j*width+i];
            float newDisp=disp*(value);
            int inew=(int)(i-newDisp);
            inew=index(inew, width);
            pDstDispData[j*width+inew]=newDisp;
        } 
    }
}

int main(){
    Mat srcImgL=imread("imgL.png");
    Mat dispL=imread("dispL.png",0);
    dispL=dispL/4;//每个像素值缩小4倍

    int imgHeight=srcImgL.rows;
    int imgWidth=srcImgL.cols;

    Mat dstImgL=Mat::zeros(imgHeight,imgWidth, CV_8UC3);
    Mat dstImg=Mat::zeros(imgHeight,imgWidth, CV_8UC3);
    Mat dstNewDispImg=Mat::zeros(imgHeight,imgWidth, CV_32FC1);

    uchar* pImgDataL=(uchar*)srcImgL.data;
    uchar* pDispDataL=(uchar*)dispL.data;
    uchar* pDstDataL=(uchar*)dstImgL.data;

    VideoWriter writer("video.avi", CV_FOURCC('D','I','V','X'), 30, Size(imgWidth, imgHeight), 1); 
    int cnt=0;
    int viewCnt=50;
    while (true/*cnt!=4*/){
        float interp;
        for(int k=0; k<viewCnt; k++){
            dstNewDispImg.setTo(255);
            dstImgL.setTo(0);
            if (cnt%2==0)
                interp=(float)k/viewCnt;
            else
                interp=(float)(viewCnt-k)/viewCnt;

            obtainNewDispMap(dispL, dstNewDispImg, interp);

            float* pNewDispData=(float*)dstNewDispImg.data;
            for (int j=0; j<imgHeight; j++){
                for (int i=0; i<imgWidth; i++){
                    float disp=pNewDispData[j*imgWidth+i];
                    float id=i+disp;

                    int id0=floor(id);
                    int id1=floor(id+1);
                
                    float weight1=1-(id-id0);
                    float weight2=id-id0;

                    id0=index(id0, imgWidth);
                    id1=index(id1, imgWidth);

                    //插值结果
                    pDstDataL[j*imgWidth*3+i*3+0]=weight1*pImgDataL[j*imgWidth*3+id0*3+0]+weight2*pImgDataL[j*imgWidth*3+id1*3+0];
                    pDstDataL[j*imgWidth*3+i*3+1]=weight1*pImgDataL[j*imgWidth*3+id0*3+1]+weight2*pImgDataL[j*imgWidth*3+id1*3+1];
                    pDstDataL[j*imgWidth*3+i*3+2]=weight1*pImgDataL[j*imgWidth*3+id0*3+2]+weight2*pImgDataL[j*imgWidth*3+id1*3+2];
                }
            }
            namedWindow("virImg");
            imshow("virImg", dstImgL);
            waitKey(10);
            writer<<dstImgL;
        }
        cnt++;
    }
   writer.release();
   return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_26697045/article/details/84892640