在双目SGBM匹配之后,由于遮挡和误匹配等问题,最后出来的深度图会存在很多噪点和空洞,这些问题无法通过某一种滤波方法解决,对于这个问题我尝试自己写了一个脚本,能比较好的去除空洞。代码如下:
头文件hole_filling.h
#pragma once
#include<iostream>
#include <opencv2/opencv.hpp>
#include<typeinfo>
#include<algorithm>
#include<vector>
#include<numeric>
using namespace std;
void insertDepth32f(cv::Mat& depth);
源文件hole_filling.cpp
#include"hole_filling.h"
void insertDepth32f(cv::Mat& depth)
{
for (int i = 0; i < depth.rows; i++)
{
for (int j = 0; j < depth.cols; j++)
{
if (depth.channels() == 1)
{
//图像数组是逐行逐列顺序排列的,也就是第一行,全列,第二行全列的走
int a,b,indexs = i * depth.cols + j;
//cout << typeid(depth.data[indexs]).name() << endl;
a = (int)depth.data[indexs];
//cout << a << endl;
if (a == 0 && j > 50 && j< depth.cols-50 && i>50 && i< depth.rows-50)
{
//vector<int> testarray = { (int)depth.data[indexs - 50], (int)depth.data[indexs + 50], (int)depth.data[indexs - 50 * depth.cols], (int)depth.data[indexs + 50 * depth.cols] };
b = max({ (int)depth.data[indexs - 50], (int)depth.data[indexs + 50], (int)depth.data[indexs - 50* depth.cols], (int)depth.data[indexs + 50 * depth.cols] });//accumulate(testarray.begin(),testarray.end(),0)/4;
//cout << "a的值为:"<<a<<"b的值为:"<<b << endl;
depth.data[indexs] = b;
}
}
else if (depth.channels() == 3)
{
}
}
}
}
我做了两个实验,b = max({ (int)depth.data[indexs - 50], (int)depth.data[indexs + 50], (int)depth.data[indexs - 50* depth.cols], (int)depth.data[indexs + 50 * depth.cols]
- 一个是把距离当前空洞像素前后上下50个像素处的最大像素值替代当前空洞像素;
- 另一个是把距离当前空洞像素前后上下1个像素处的最大像素值替代当前空洞像素;
得出来的效果如下:
可以看到参数设置为50的时候填充缺乏渐变,存在新的噪点,具体选择参数为多少应根据需要处理的图片的分辨率来确定,大分辨率参数可以适当设置的大一些。