来自这篇博客,利用视差图和普通图像合成新视点:
#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;
}