gpt4 book ai didi

python - 在opencv和python中复制图像的一部分

转载 作者:行者123 更新时间:2023-12-02 16:47:32 25 4
gpt4 key购买 nike

我正在尝试通过opencv将图像分为几个子图像,方法是识别原始图像的模板,然后复制与这些模板匹配的区域。我是opencv的新手!我已经使用以下方式标识了子图像:

result = cv2.matchTemplate(img, template, cv2.TM_CCORR_NORMED)

经过一些清理后,我得到了一个称为点的元组列表,我在其中重复显示矩形。 tw和th分别是模板的宽度和高度。
for pt in points:
re = cv2.rectangle(img, pt, (pt[0] + tw, pt[1] + th), 0, 2)
print('%s, %s' % (str(pt[0]), str(pt[1])))
count+=1

我要完成的工作是将八边形( https://dl.dropbox.com/u/239592/region01.png)保存到单独的文件中。

我怎样才能做到这一点?我已经读过一些有关轮廓的信息,但是我不确定如何使用它。理想情况下,我想绘制八边形轮廓。

非常感谢你的帮助!

最佳答案

如果模板匹配对您有用,请坚持下去。例如,我考虑了以下模板:

然后,我们可以对输入进行预处理,以使其成为二进制输入并丢弃小的组件。在此步骤之后,将执行模板匹配。然后是通过丢弃接近的匹配项来过滤匹配项的问题(为此,我使用了虚拟方法,因此,如果匹配项过多,您可能会花一些时间)。在确定了哪些点相距很远(从而确定了不同的六边形)之后,我们可以通过以下方式对其进行较小的调整:

  • 按y坐标排序;
  • 如果两个相邻项目的y坐标太近,则将它们都设置为相同的y坐标。

  • 现在,您可以按照适当的顺序对该点列表进行排序,以便以栅格顺序进行裁剪。使用 numpy提供的 slice 很容易实现裁剪部分。
    import sys
    import cv2
    import numpy

    outbasename = 'hexagon_%02d.png'

    img = cv2.imread(sys.argv[1])
    template = cv2.cvtColor(cv2.imread(sys.argv[2]), cv2.COLOR_BGR2GRAY)
    theight, twidth = template.shape[:2]

    # Binarize the input based on the saturation and value.
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    saturation = hsv[:,:,1]
    value = hsv[:,:,2]
    value[saturation > 35] = 255
    value = cv2.threshold(value, 0, 255, cv2.THRESH_OTSU)[1]
    # Pad the image.
    value = cv2.copyMakeBorder(255 - value, 3, 3, 3, 3, cv2.BORDER_CONSTANT, value=0)

    # Discard small components.
    img_clean = numpy.zeros(value.shape, dtype=numpy.uint8)
    contours, _ = cv2.findContours(value, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    for i, c in enumerate(contours):
    area = cv2.contourArea(c)
    if area > 500:
    cv2.drawContours(img_clean, contours, i, 255, 2)


    def closest_pt(a, pt):
    if not len(a):
    return (float('inf'), float('inf'))
    d = a - pt
    return a[numpy.argmin((d * d).sum(1))]

    match = cv2.matchTemplate(img_clean, template, cv2.TM_CCORR_NORMED)

    # Filter matches.
    threshold = 0.8
    dist_threshold = twidth / 1.5
    loc = numpy.where(match > threshold)
    ptlist = numpy.zeros((len(loc[0]), 2), dtype=int)
    count = 0
    print "%d matches" % len(loc[0])
    for pt in zip(*loc[::-1]):
    cpt = closest_pt(ptlist[:count], pt)
    dist = ((cpt[0] - pt[0]) ** 2 + (cpt[1] - pt[1]) ** 2) ** 0.5
    if dist > dist_threshold:
    ptlist[count] = pt
    count += 1

    # Adjust points (could do for the x coords too).
    ptlist = ptlist[:count]
    view = ptlist.ravel().view([('x', int), ('y', int)])
    view.sort(order=['y', 'x'])
    for i in xrange(1, ptlist.shape[0]):
    prev, curr = ptlist[i - 1], ptlist[i]
    if abs(curr[1] - prev[1]) < 5:
    y = min(curr[1], prev[1])
    curr[1], prev[1] = y, y

    # Crop in raster order.
    view.sort(order=['y', 'x'])
    for i, pt in enumerate(ptlist, start=1):
    cv2.imwrite(outbasename % i,
    img[pt[1]-2:pt[1]+theight-2, pt[0]-2:pt[0]+twidth-2])
    print 'Wrote %s' % (outbasename % i)

    如果只需要六边形的轮廓,则裁剪到 img_clean而不是 img(但是按栅格顺序对六边形进行排序是没有意义的)。

    这是两个示例在不修改上面的代码的情况下将被剪切的不同区域的表示:

    关于python - 在opencv和python中复制图像的一部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14908986/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com