测量图像中痕迹的平均厚度

Alc*_*sta 19 language-agnostic algorithm image image-processing computer-vision

这是问题所在:我有许多由不同厚度的痕迹组成的二进制图像.下面有两张图片来说明问题:

第一张图片 - 大小:711 x 643 px

711 x 643示例图像

第二张图片 - 尺寸:930 x 951像素

替代文字

我需要的是测量图像中痕迹的平均厚度(以像素为单位).实际上,图像中痕迹的平均厚度是一种有点主观的度量.所以,我需要的是一个与轨迹半径有一定关系的度量,如下图所示:

替代文字

笔记

  • 由于该措施不需要非常精确,我愿意以精确度换取速度.换句话说,速度是解决这个问题的重要因素.

  • 痕迹中可能存在交叉点.

  • 迹线厚度可能不是恒定的,但平均测量值是可以的(即使最大迹线厚度是可接受的).

  • 跟踪总是比它宽得多.

Nik*_*iki 19

我建议这个算法:

  1. 对图像应用距离变换,以便将所有背景像素设置为0,将所有前景像素设置为距背景的距离
  2. 在距离变换图像中找到局部最大值.这些是线条中间的点.将它们的像素值(即距背景的距离)放入列表中
  3. 计算该列表的中位数或平均值

  • 喜欢你的答案.:) (2认同)

Dr.*_*ius 8

@ nikie的答案给我留下了深刻的印象,并尝试了一下......

我简化了算法以获得最大值,而不是平均值,因此避免了局部最大值检测算法.我认为如果中风表现良好就足够了(尽管对于自相交线,它可能不准确).

Mathematica中的程序是:

m = Import["http://imgur.com/3Zs7m.png"]   (* Get image from web*)
s = Abs[ImageData[m] - 1];                 (* Invert colors to detect background *)
k = DistanceTransform[Image[s]]            (* White Pxs converted to distance to black*)
k // ImageAdjust                           (* Show the image *)
Max[ImageData[k]]                          (* Get the max stroke width *)
Run Code Online (Sandbox Code Playgroud)

生成的结果是

替代文字

数值(28.46 px X 2)非常适合我的56 px测量值(尽管你的值是100px:*)

编辑 - 实现完整算法

嗯......有点......而不是搜索局部最大值,找到距离变换的固定点.几乎,但不完全不同于同一件事:)

m = Import["http://imgur.com/3Zs7m.png"];   (*Get image from web*)
s = Abs[ImageData[m] - 1];         (*Invert colors to detect background*)
k = DistanceTransform[Image[s]];   (*White Pxs converted to distance to black*)
Print["Distance to Background*"]
k // ImageAdjust                   (*Show the image*)
Print["Local Maxima"]
weights = 
    Binarize[FixedPoint[ImageAdjust@DistanceTransform[Image[#], .4] &,s]]  
Print["Stroke Width =", 
     2 Mean[Select[Flatten[ImageData[k]] Flatten[ImageData[weights]], # != 0 &]]]
Run Code Online (Sandbox Code Playgroud)

替代文字

正如您所看到的,结果与前一个结果非常相似,使用简化算法获得.