2014-09-22 134 views
0

我试图使用here描述的方法修复深度图的缺失深度值。总结方法:修补深度图,仍是黑色图像边框

  1. DOWNSIZE深度图以20中的原始大小
  2. 补绘的小型化的图像中的全黑(未知的)像素
  3. 升迁到原来的大小
  4. 在替换所有的黑色像素%具有相应值的原始图像

超级简单,一切正常。显示结果的视频可以在here找到。

但是,我想知道为什么左边和上边的图像边框仍然是黑色,尽管它们应该被修补(可以在视频中看到)。我的第一个想法是,这可能需要做一些边界插值(图像边界外的黑色像素),但是我希望这也会发生在其他图像边界上。我的第二个想法是,这是使用的修复方法(Alexandru Telea方法)特有的,但将其改为基于Navier-Stokes的方法并未改变结果。

有人可以向我解释为什么会发生这种情况,如果可能的话如何告诉OpenCV也修复这些区域?

在此先感谢。

+0

可能是左边的值是不是255?你可以添加另一个窗口,显示深度值等于255的所有深度值?例如'cv :: imshow(“newWindowName”,depthf == 255);'如果这就是您可以在链接代码的第13行和第16行将使用过的掩码更改为'> 250'或其他内容而不是'== 255'的原因。 – Micka 2014-09-22 14:58:51

+0

因为我得到的深度值未知为0,对我来说,它会是depthf == 0或depthf> 5,但无论如何,这里有一些图片:[This](https://drive.google.com/file/d/ 0B-qt8lafqDaeQy03QndSMkUxUkU/edit?usp = sharing)显示了一个示例深度图。 [This](https://drive.google.com/file/d/0B-qt8lafqDaeZUNOdVBNMlNLcXc/edit?usp=sharing)是用于修补的蒙版。并且[this](https://drive.google.com/file/d/0B-qt8lafqDaeSi01cmJDc3Byc1U/edit?usp=sharing)就是结果。任何想法@Micka?左边框有点奇怪,但让我们坚持顶部边框。它明显包含在面具中。 – thomas 2014-09-22 18:55:26

+0

你看过_tmp1和_tmp吗? – Micka 2014-09-22 19:02:53

回答

2

在@theodore询问http://answers.opencv.org/question/86569/inpainting-depth-map-still-black-image-borders/?comment=86587#comment-86587后,我用示例图像测试了inpaint的行为。它看起来不能正确处理边框,因此可以使用创建边框cv::copyMakeBorder

这里的扩展版本,以某种单元测试:

int main(int argc, char* argv[]) 
{ 
    cv::Mat input = cv::imread("C:/StackOverflow/Input/depthInpaint.png"); 
    cv::Mat img; 
    cv::cvtColor(input, img, CV_BGR2GRAY); 

    cv::Mat inpainted; 
    const unsigned char noDepth = 0; // change to 255, if values no depth uses max value or use the mask image 
    //cv::inpaint(img, (img == noDepth), depth, 5.0, cv::INPAINT_TELEA); // img is the 8-bit input image (depth map with blank spots) 


    double inpaintRadius = 5; 
    int makeBorder = 1; 
    cv::Mat borderimg; 
    cv::copyMakeBorder(img, borderimg, makeBorder, makeBorder, makeBorder, makeBorder, cv::BORDER_REPLICATE); 
    cv::imshow("border", borderimg); 
    cv::inpaint(borderimg, (borderimg == noDepth), inpainted, inpaintRadius, cv::INPAINT_TELEA); // img is the 8-bit input image (depth map with blank spots) 

    cv::Mat originalEmbedded = borderimg(cv::Rect(makeBorder, makeBorder, img.cols, img.rows)); 
    cv::Mat inpaintedEmbedded = inpainted(cv::Rect(makeBorder, makeBorder, img.cols, img.rows)); 


    cv::Mat diffImage; 
    cv::absdiff(img, originalEmbedded, diffImage); 
    cv::imshow("embedding correct?", diffImage > 0); 

    cv::Mat mask = img == noDepth; 
    cv::imshow("mask", mask); 


    cv::imshow("input", input); 
    cv::imshow("inpainted", inpainted); 
    cv::imshow("inpainted from border", inpaintedEmbedded); 
    cv::waitKey(0); 
    return 0; 
} 

这里的简化版本,如果你认为它是正确的:

int main(int argc, char* argv[]) 
{ 
    cv::Mat input = cv::imread("C:/StackOverflow/Input/depthInpaint.png"); 
    cv::Mat img; 
    cv::cvtColor(input, img, CV_BGR2GRAY); 

    cv::Mat inpainted; 
    const unsigned char noDepth = 0; // change to 255, if values no depth uses max value or use the mask image 
    //cv::inpaint(img, (img == noDepth), depth, 5.0, cv::INPAINT_TELEA); // img is the 8-bit input image (depth map with blank spots) 

    double inpaintRadius = 5; 
    int makeBorderSize = 1; 
    cv::Mat borderimg; 
    //cv::copyMakeBorder(img, borderimg, borderSize, borderSize, borderSize, borderSize, cv::BORDER_REPLICATE); 
    cv::copyMakeBorder(img, borderimg, makeBorderSize, makeBorderSize, makeBorderSize, makeBorderSize, cv::BORDER_REPLICATE); 
    //cv::imshow("border", borderimg); 
    cv::inpaint(borderimg, (borderimg == noDepth), inpainted, inpaintRadius, cv::INPAINT_TELEA); // img is the 8-bit input image (depth map with blank spots) 

    // extract the original area without border: 
    cv::Mat inpaintedEmbedded = inpainted(cv::Rect(makeBorderSize, makeBorderSize, img.cols, img.rows)); 



    cv::imshow("input", input); 
    cv::imshow("inpainted from border", inpaintedEmbedded); 
    cv::waitKey(0); 
    return 0; 
} 

这里的输入:

enter image description here

这是带边框的输入(bordersiz E(5)可视化效果越好):

enter image description here

下面是输出:

enter image description here

+0

非常感谢您的答复;-)。不幸的是,我不能将它标记为一个解决方案,因为只有线程启动器可以,但你得到了我的赞赏。非常感谢。 – ThT 2016-02-04 16:15:44

+0

是的,我知道,thx。这不是线程启动器问题的直接解决方案,因为他没有发布他的代码,但可能相同的机制也会帮助他。玩得开心,请使用解决方案在OpenCV网站上回答或更新您的问题。 – Micka 2016-02-04 16:17:54

+0

是的我会,我想我也会在github上打开一个问题;-) – ThT 2016-02-04 16:25:39