利用视差图合成新视点

利用视差图合成新视点,视差图一般通过图像匹配获取,以middlebury上的一张图为例,左边为原图(左图像),右边为对应视差图(灰度图)。

利用视差图合成新视点_第1张图片    利用视差图合成新视点_第2张图片

1. 正向映射:

简单的利用左视点原图和视差图进行视点合成,取每一个像素点处的视差值,然后计算新图像中像素点位置,然后赋值。前向映射,单点赋值代码如下。配置完Opencv可以直接跑,如下图:

 

#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;
using namespace cv;

void main()
{
	string imgPath = "data/source_images/teddy/";
	Mat srcImgL = imread("1.png");
	Mat dispL = imread("2.png", 0);
	dispL = dispL / 4;

	int imgHeight = srcImgL.rows;
	int imgWidth = srcImgL.cols;
	int channels = srcImgL.channels();

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

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

	cv::VideoWriter writer;
	writer.open("video.avi", VideoWriter::fourcc('D', 'I', 'V', 'X'), 30, Size(imgWidth, imgHeight));
	int cnt = 0;
	int viewCnt = 50;
	while (cnt != 4)
	{
		for (int k = 0; k < viewCnt; k++)
		{
			dstImgL.setTo(0);
			float interp;
			if (cnt % 2 == 0)    interp = (float)k / viewCnt;
			else  interp = float(viewCnt - k) / viewCnt;
			for (int j = 0; j < imgHeight; j++)
			{
				for (int i = 0; i < imgWidth; i++)
				{
					uchar dispL = pDispDataL[j*imgWidth + i];
					float offsetL = dispL * interp;
					int idL = (int)(offsetL + 0.5);  //计算视差值

					if (idL + i >= imgWidth) continue;
					//插值结果
					int idxResult = (j*imgWidth + i)*channels;
					int idx = (j*imgWidth + i + idL)*channels;
					for (int chan = 0; chan < channels; chan++)
					{
						pDstDataL[idxResult + chan] = pImgDataL[idx + chan];
					}
				}
			}
			namedWindow("show");
			imshow("show", dstImgL);
			waitKey(10);
			writer << dstImgL;
		}
		cnt++;
	}
	writer.release();
}

 边缘有锯齿,随后找时间加上反向映射以及双线性插值的版本。

2. 反向映射

先根据左视点视差图生成虚拟视点的视差图,然后反向映射得到每一个像素点在原图像中的浮点位置,利用线性插值获取最终颜色值。(虚拟视点位置视差图没有填充空洞版本),可见有很多裂纹。

 

#include 
#include 
#include 

using namespace std;
using namespace cv;

int index(int m, int n)
{
    if (m>=0 && 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

 3.反向映射+空洞填充+双线性插值

上面生成虚拟视点位置的视差图时没有填充空洞,生成的虚拟视点会有很多裂纹存在。加上空洞填充能够有效消除裂纹。如下:

 利用视差图合成新视点_第3张图片  利用视差图合成新视点_第4张图片

填充空洞后生的虚拟视点图如下,可见空洞裂纹得到有效消除:

--------------------------------- 业精于勤而荒于嬉 行成于思而毁于随 ---------------------------------

转自:利用视差图合成新视点

你可能感兴趣的:(利用视差图合成新视点)