【问题标题】:silhouette extraction from depth从深度提取轮廓
【发布时间】:2015-03-10 07:57:32
【问题描述】:

您好,我有一张深度图像,我想从中提取人(人)剪影。我像这样使用像素阈值:

for i=1:240 
  for j=1:320 
    if b(i,j)>2400 || b(i,j)<1900 
      c(i,j)=5000; 
    else 
      c(i,j)=b(i,j); 
    end 
  end
end

但还剩下一些。有什么办法可以去掉吗?

原图:

Extracted_silhouette:

【问题讨论】:

  • 这是一个广泛的主题领域。但也许有人可以解释为什么这比你希望的要难,或者给出一个有用的下一步。请显示您的像素阈值代码,因为任何人写答案的工作可能会更少。
  • @NeilSlater:这是我的代码for i=1:240 for j=1:320 if b(i,j)&gt;2400 || b(i,j)&lt;1900 c(i,j)=5000; else c(i,j)=b(i,j); end end end
  • 您可能会发现this thread 很有用。
  • @Shai:提到的线程有正常的信息,但在我的情况下,深度图像大小是 320x240,我没有正常找到边缘。有没有其他方法可以找出人周围的边缘?
  • 您可以从深度粗略估计表面法线。考虑[dzx dzy] = gradient( depth_map );(深度图的水平和垂直导数),那么表面法线的粗略估计可以是n = cat( 3, dzx, dzy, ones(size(dzx)) )。现在您需要标准化为单位长度n = bsxfun( @rdivide, n, sqrt( sum( n.^2, 3 ) ) );

标签: matlab image-processing kinect matlab-cvst


【解决方案1】:

@Shai above 的工作基础上,您可以获取阈值的输出,然后将边界应用于该图像。下面是一个示例,您可以从前面步骤的输出中输入 [YOUR_IMAGE],然后修改 [ADJUST] 的值,直到仅选择人员。

此代码根据大小查找边界,不会选择大于您输入的值的任何内容。很简单,但它对我有用。希望这会有所帮助。

boundaries = bwboundaries([YOUR_IMAGE]);    
 numberOfBoundaries = size(boundaries)
   if (size(boundaries) < [ADJUST])
      for k = 1 : numberOfBoundaries
         thisBoundary = boundaries2{k}
         plot(thisBoundary(:,2), thisBoundary(:,1), 'b', 'LineWidth', 2);   
      end
   end

【讨论】:

  • 从上面的代码中,图像 (e) 用于计算 bwboundaries(e) 。但是(边界)的大小是[16 1] 那么我应该选择什么值?在我输入[ADJUST] = 18 后,它会显示一个框。对吗?
  • 查看您的代码,您的图像是 240x320 分辨率的吗?如果是这样,那么您调整的值需要反映该人占用多少像素。粗略估计,我会说这个人占据了图像的 1/5 左右。这样一来,图像中总共有 320x240 = 15360 个像素,其中 15360 大约是人的像素面积。使用这些数字应该会有所帮助。
  • 实际上我提取了上图的 ROI,现在我只有人和部分苏打水在他身边。图像的分辨率现在是211x111 图像的1/5 将是4684,所以我使用了[ADJUST]= [70 60]。这向我展示了这个 [结果] (dropbox.com/s/pzf3ahwpvl8lerd/Capture.PNG?dl=0)。
  • 这里的边界阴影很有趣,不知道是什么原因造成的。使用正常(强度)图像并使用深度图像作为人的位置的参考可能有用吗?
【解决方案2】:

根据this thread深度图边界可以根据估计的表面法线方向找到。
要估计表面法线的方向,您可以

[dzx dzy] = gradient( depth_map ); %// horizontal and vertical derivatives of depth map
n = cat( 3, dzx, dzy, ones(size(dzx)) );
n = bsxfun( @rdivide, n, sqrt( sum( n.^2, 3 ) ) ); %// normalize to unit length

一个简单的方法是阈值

e = abs( n(:,:,3) ) < 1e-2;

结果为

可以在this answer 中找到从边界导出轮廓的更复杂的方法。

【讨论】:

  • 有没有什么简单的方法可以提取出坐着的人的边缘?
  • @FrqKhan 我认为没有一种简单的方法可以仅使用深度图来区分人与沙发。试着想一想:是什么让人腿之间沙发区域的深度信息与人本身不同?没有明确的边界,没有价值差异,表面法线的方向可能提供信息,但仅限于局部......
  • 有什么方法可以检测ROI吗?
  • @FrqKhan 这可能适合提出新问题;)
【解决方案3】:

这很难通过阈值实现,因为沙发与人的上半身处于同一深度。 你需要分割整个人,还是分割上半身就足够了?在后一种情况下,你可以尝试使用vision.CascadeObjectDetector是计算机视觉系统工具箱来检测RGB图像中人的上半身。

【讨论】:

  • 你好 Dima,是的,我想提取整个人。有没有办法提取人的边界?
  • 试用图像处理工具箱中的图像分割器应用程序:mathworks.com/help/images/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-24
  • 2013-12-17
  • 2012-05-10
  • 2018-02-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多