因此,我正在处理这段代码,以从图像中的某些图形中提取数据。这些图像都是从书本中扫描的。由于我们在这里谈论的是100幅以上的图像,因此我想自动执行该过程。我的第一步是确保所有图像对齐。因为书的页面是手工扫描的,所以扫描彼此之间都略有偏移或旋转。幸运的是,图像上有一些虚线,可用作将它们对齐的参考点。然后,通过在这些虚线上将图像切片,我可以将图像划分为较小的子图像。这样,所有子图像对于所有扫描图像将是相等的。
因此,当然第一步是检测这些虚线。我的策略可分为4个步骤:
现在可能会出现几个问题。有时HoughLines会检测到错误的行(例如书中下一页的折页),但是可以通过在右侧略微裁剪图像来解决此问题(始终欢迎使用更好的解决方案)。第二个(也是最大的)问题是HoughLines有时倾向于将单行标识为多行。我认为这与Canny Edge Detection的边缘过于粗糙或含糊不清有关,因此HoughLines实际上会看到多条线。有什么办法可以使Canny的输出“平滑”,以便HoughLines可以一次检测到每一行?
在此特定图像的情况下,中间的垂直虚线未被识别,而书中下一页的折叠被识别。此外,垂直虚线被识别为多条线。 (左源图像,检测到中间边缘,检测到右线)
# load image
img_large = cv2.imread("image.png")
# resize for ease of use
img_ori = cv2.resize(img_large, None, fx=0.2, fy=0.2, interpolation=cv2.INTER_CUBIC)
# create grayscale
img = cv2.cvtColor(img_ori, cv2.COLOR_BGR2GRAY)
# create mask for image size
mask = np.zeros((img.shape[:2]), dtype=np.uint8)
# do a morphologic close to merge dotted line
kernel = np.ones((8, 8))
res = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
# detect edges for houghlines
edges = cv2.Canny(res, 50, 50)
# detect lines
lines = cv2.HoughLines(edges, 1, np.pi/180, 200)
# draw detected lines
for line in lines:
rho, theta = line[0]
a = np.cos(theta)
b = np.sin(theta)
x0 = a*rho
y0 = b*rho
x1 = int(x0 + 1000*(-b))
y1 = int(y0 + 1000*a)
x2 = int(x0 - 1000*(-b))
y2 = int(y0 - 1000*a)
cv2.line(mask, (x1, y1), (x2, y2), 255, 2)
cv2.line(img, (x1, y1), (x2, y2), 127, 2)
答案 0 :(得分:2)
在您的脚本中,像素仓和旋转仓对于设置的阈值来说太精细了:
public class MangasViewModel{
public List<WN> WN{get;set;}
public List<LN> LN {get;set;}
public List<Manga> Manga {get;set;}
}
因此,您可以调整阈值参数(200)仅获得一行,或者调整rho(1)和theta(np.pi / 180)参数,或者调整所有这些参数。您可以从图像中选择一组仅包含一条水平线或垂直线的图像。然后进行网格搜索以找到仅检测一组测试图像中的一行的参数。