视差前向合成虚拟视点的原理很简单,就是根据视差计算的原理来计算得到虚拟视点位置在左图像或有图像中的位置,然后对应取值得到对应虚拟视点的像素。
假如左图中一点的像素位置为6,对应该点像素的视差值为3,那么这一点像素在右图中的位置3。因为视差的计算公式为,Xl - Xr = d;特别注意的是,这里合成算法使用的都是极线矫正处理过的图像,所以不用考虑y轴的影响。
下面的代码使用了opencv的库。计算的是左视图和左视差图合成右视图的程序。
#include <iostream>
#include <vector>
#include <deque>
#include <unordered_map>
#include <math.h>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
/*
*@func: 根据视差图正向合成右视图
*@param: img_left, disp_left 原图片左图
*@return: img_syn 合成的图像
*/
cv::Mat ImgAndDispForewardSyn(cv::Mat img, cv::Mat disp)
{
int col = img.cols;
int row = img.rows;
Mat img_syn = Mat::zeros(row, col, CV_8UC3);
disp /= 4; // 因为输入的图像是1/4分辨率 对应不同输入的分辨率进行修改
for(int i=0; i<row; i++)
{
for(int j=0; j<col; j++)
{
auto disp_vlaue = int(disp.at<uchar>(i, j) + 0.5);
if(disp_vlaue + j >= col || disp_vlaue == 0)
continue;
img_syn.at<Vec3b>(i, j) = img.at<Vec3b>(i, disp_vlaue+j);
}
}
return img_syn;
}
int main()
{
auto image = imread("im2.png");
auto disp2 = imread("disp2.png");
auto img_syn = ImgAndDispForewardSyn(image, disp2);
imwrite("syn_img.png", img_syn);
return 0;
}
输入分别是如下所示的左视图和对应的左视差图
合成得到如下所示的右视图:
这里面的数据集用的是middlebury。可以到对应的如下官网地址进行下载。