2010-11-10 152 views
1

我有一个图像,我在图像中有部分线条。他们都是水平线或垂直线。我不知道线条的颜色,也不知道线条的宽度。如何检测图像中的部分垂直/水平线?

如何使用PHP来检测这样的行?

正如你在上传的图片中看到的那样,我需要切片的是3x3节。我需要3个垂直部分和3个水平部分来切片。请注意,在内容区域周围有一个带有一些标记的矩形,这是图像的一部分。

我们可以使用这些标记来获得坐标。

alt textalt text

+0

背景是否固体?你能否在某处上传示例并给出链接? – 2010-11-10 07:55:37

+0

但是,图像中的部分线是什么?如果连续的行具有与图像相同的颜色,比如仅使用16种颜色的剪贴画呢? – stillstanding 2010-11-10 08:00:19

+0

查看带有示例图片的更新问题。 – Pentium10 2010-11-10 08:08:50

回答

1

如果比较每行的第一个和最后一个N像素(如果它们具有相同的颜色/长度),则最好使用标记。与解析每行上的所有像素相比,这样做效率更高。

0

您必须查看图像行方向和列明智的。你很可能会使用imagecolorat()。遍历所有列和行。如果两个(或任意限制)或更多像素具有相同(或非常接近)的颜色,则它们构成一条线。

0

肯定使用标记,否则这是一个难题。

要使用标记,您只需要找到他们的位置。要做到这一点,从边缘开始,采用连续的单像素宽条并寻找周期性偏差。经典的,相当简单的方法是使用自相关。由于您的标记非常清晰(即,如果有噪声,所以很少),您可能会发现更简单的方法,例如对整个条带的像素值进行平均,并且与此偏离的所有偏差超过一小部分的数字都是标记;或者制作一个像素值的直方图,它应该有两个尖角,背景的一个大凹凸,以及小标记的凹凸等。但是无论使用什么方法,都要找到标记,然后就完成了。

0
  1. 查找一个角落像素的背景颜色($ cBack)(比方说,左上)
  2. 从左上角,动环的foreach(范围(1,imagesx($ img_rsrc)),设置$ cCur.color = imagecolorat($ img_asset,$ x,$ y);
  3. $ iMarkWidth + = 1; $ iMarkPosStart = $ cCur.x;直到您碰到不同颜色的像素($ cCur.color!= $ $ bMarkFound = true; else $ bMarkFound = false;
  4. 如果$ cCur.color == $ cBack.color,$ horizMarkArray [] = array($ iMarkPosStart,$ iMarkPosStart + $ iMarkWidth,$ iMarkWidth );
  5. 继续,直到的宽度
  6. end如果is_empty($ horizMarkArray)与下一水平行
  7. 重复..和通过11.重复为高度/垂直,具有$ vertMarkArray []

在步骤4 & 8您可以进行任何平均,噪声检测等。 在步骤7 & 11您可以重复前面的步骤并对$ iMarkWidth进行平均以避免行顶部出现混叠错误。在这种情况下,你停止之一:

  • 后N行,或者$ iMarkWidth后
  • > {东西,显然比任何线更宽}
+0

第二张图像有两个框架,一个是白色的,另一个是灰色的。 – Pentium10 2010-11-11 06:34:54

+0

因为您知道标记数/线数> 1的范围,所以可以将其用作步骤#6中的条件。 if(is_empty($ horizMarkArray)OR count($ horizMarkArray)== 1)){// repeat ... – 2010-11-22 21:56:20

0

你可以尝试做边缘检测,然后使用Hough transform检测线条。在你的情况下,问题是与线条对应的边缘非常微弱。另一方面,你只需要寻找垂直和水平线,所以你可以限制很多问题。