【问题标题】:How to find a shape inside a Numpy 2D array having an contour?如何在具有轮廓的 Numpy 2D 数组中找到形状?
【发布时间】:2020-02-08 23:24:18
【问题描述】:

我有一个形状轮廓cnt,我需要在二维数组中找到它,我有一个target_index变量,它用于查找所需区域,但我需要在其中查找cnt轮廓.

import numpy as np

x = np.linspace(0,1000, int(1000/50))
y = np.linspace(0,1000, int(1000/50))
X,Y = np.meshgrid(x,y)

source =  np.column_stack([X.ravel(), Y.ravel()]).astype(int)
destination = source.copy()

cnt = [[550,  42],     
       [600,  42],
       [690, 273],
       [640, 273]]

# Need to use cnt here
target_index = np.where(np.logical_and(destination[:,1]==789,destination[:,0]>=421))

destination[target_index]
scope = destination[target_index] 
scope[:,0] = scope[:,0] + 10
destination[target_index] = scope
destination[target_index]


# Remap
grid_x, grid_y = np.mgrid[0:800, 0:800]
grid_z = griddata(source, destination, (grid_x, grid_y), method='cubic')
map_x = np.append([], [ar[:,1] for ar in grid_z]).reshape(800,800).astype('float32')
map_y = np.append([], [ar[:,0] for ar in grid_z]).reshape(800,800).astype('float32')
warped_image = cv2.remap(img, map_x, map_y, cv2.INTER_CUBIC)

cv2.drawContours(warped_image,[cnt],0,(0,0,0),2)

可以使用其他方法,但首选np.where

【问题讨论】:

标签: python arrays numpy


【解决方案1】:

从你的问题来看,你正在申请身体变形,对我来说这个选项是最方便的,因为你可以为你创建任何轮廓。

    # Left hand contour
    pt1 = (int_12, int_13)
    pt2 = (int_17, int_16)
    pt3 = (int_18, int_19)
    pt4 = (int_14, int_15)
    lh_cnt = np.array([pt1, pt2, pt3, pt4])

    offset = int(hand_lenght / 28)

    for x in destination:
        inside_lh = cv2.pointPolygonTest(lh_cnt, (x[0], x[1]), False)
        elif inside_lh > 0:
            x[0] = x[0] - offset

    # Warping
    grid_x, grid_y = np.mgrid[0:self.width, 0:self.height]
    grid_z = griddata(source, destination, (grid_x, grid_y), method='cubic')
    map_x = np.append([], [ar[:,0] for ar in grid_z]).reshape(self.width, self.height).astype('float32')
    map_y = np.append([], [ar[:,1] for ar in grid_z]).reshape(self.width, self.height).astype('float32')
    warped_image = cv2.transpose(cv2.remap(img, map_x, map_y, cv2.INTER_LANCZOS4))

【讨论】:

    【解决方案2】:

    除非您将自己限制在某些多边形上,否则我认为使用np.where 来做到这一点将非常困难。

    下面是使用matplotlibPath对象解决问题的方法(适配this solution):

    import numpy as np
    from matplotlib.path import Path
    
    x = np.linspace(0,1000, int(1000/50))
    y = np.linspace(0,1000, int(1000/50))
    X,Y = np.meshgrid(x,y)
    source =  np.column_stack([X.ravel(), Y.ravel()]).astype(int)
    
    cnt = [[550,  42],     
           [600,  42],
           [690, 273],
           [640, 273]]
    
    p = Path(cnt)
    grid = p.contains_points(source)
    mask = grid.reshape(20, 20)
    

    然后看结果:

    import matplotlib.pyplot as plt
    plt.imshow(mask)
    

    这给出了:

    linspace 中使用更多点以获得更高分辨率的结果。

    【讨论】:

    • 您好,不幸的是,这个解决方案对我不起作用,因为有索引,我无法更改二维数组中的值
    • @question_mark_77 我不明白。这正在处理您的数据。你希望整个操作的输出是什么?
    猜你喜欢
    • 2014-11-22
    • 2021-05-10
    • 2016-08-11
    • 2022-01-20
    • 1970-01-01
    • 2017-03-12
    • 1970-01-01
    • 2014-10-16
    相关资源
    最近更新 更多