Python 滑动窗口-如何在图像上获得窗口位置?

Python 滑动窗口-如何在图像上获得窗口位置?,python,numpy,computer-vision,sliding-window,Python,Numpy,Computer Vision,Sliding Window,提到python中这个很棒的滑动窗口实现,我的问题是——在代码中,我在图像上的什么位置可以看到当前窗口? 或者我怎样才能找到它的位置 在第72行和第85行之后,我试着打印出shape和newstrides,但我显然没有取得任何进展。在norm\u shape函数中,我打印出了tuple,但输出的只是窗口维度(如果我也理解正确的话) 但我不仅需要尺寸,比如宽度和高度,我还需要知道从图像中提取窗口的确切位置,像素坐标,或者图像中的哪些行/列。如果您尝试使用 flatte=False要在图像上创建窗口

提到python中这个很棒的滑动窗口实现,我的问题是——在代码中,我在图像上的什么位置可以看到当前窗口? 或者我怎样才能找到它的位置

在第72行和第85行之后,我试着打印出
shape
newstrides
,但我显然没有取得任何进展。在
norm\u shape
函数中,我打印出了
tuple
,但输出的只是窗口维度(如果我也理解正确的话)


但我不仅需要尺寸,比如宽度和高度,我还需要知道从图像中提取窗口的确切位置,像素坐标,或者图像中的哪些行/列。

如果您尝试使用
flatte=False
要在图像上创建窗口的“网格”:

import numpy as np
from scipy.misc import lena
from matplotlib import pyplot as plt

img = lena()
print(img.shape)
# (512, 512)

# make a 64x64 pixel sliding window on img. 
win = sliding_window(img, (64, 64), shiftSize=None, flatten=False)

print(win.shape)
# (8, 8, 64, 64)
# i.e. (img_height / win_height, img_width / win_width, win_height, win_width)

plt.imshow(win[4, 4, ...])
plt.draw()
# grid position [4, 4] contains Lena's eye and nose
要获得相应的像素坐标,可以执行以下操作:

def get_win_pixel_coords(grid_pos, win_shape, shift_size=None):
    if shift_size is None:
        shift_size = win_shape
    gr, gc = grid_pos
    sr, sc = shift_size
    wr, wc = win_shape
    top, bottom = gr * sr, (gr * sr) + wr
    left, right = gc * sc, (gc * sc) + wc

    return top, bottom, left, right

# check for grid position [3, 4]
t, b, l, r = get_win_pixel_coords((3, 4), (64, 64))

print(np.all(img[t:b, l:r] == win[3, 4, :, :]))
# True
使用
flatte=True
,64x64像素窗口的8x8网格将被展平为64x64像素窗口的64长矢量。那样的话,你 可以使用类似于
np.unlavel_index
的方法从一维向量索引转换 转换为网格索引的元组,然后使用这些索引获取像素坐标,如下所示: 以上:


好的,我将尝试解决您在评论中提出的一些问题

我想要窗口相对于原始图像的实际像素尺寸的像素位置

也许我不够清楚-您已经可以使用类似我的
get\u win\u pixel\u coords()
函数这样的函数来完成此操作,该函数为您提供窗口相对于图像的顶部、底部、左侧和右侧坐标。例如:

win = sliding_window(img, (64, 64), shiftSize=None, flatten=False)

fig, (ax1, ax2) = plt.subplots(1, 2)
ax1.hold(True)
ax1.imshow(win[4, 4])
ax1.plot(8, 9, 'oy')         # position of Lena's eye, relative to this window

t, b, l, r = get_win_pixel_coords((4, 4), (64, 64))

ax2.hold(True)
ax2.imshow(img)
ax2.plot(t + 8, l + 9, 'oy') # position of Lena's eye, relative to whole image

plt.show()
还请注意,我已经更新了
get_win\u pixel\u coords()
,以处理
shiftSize
不是
None
(即窗口没有完全平铺图像,没有重叠)的情况

所以我猜在这种情况下,我应该使网格等于原始图像的尺寸,对吗?(而不是使用8x8)

不,如果窗口平铺图像而不重叠(即,我目前假设的是
shiftSize=None
),那么如果使网格尺寸等于图像的像素尺寸,则每个窗口将只包含一个像素

所以在我的例子中,对于宽度为360,高度为240的图像,这是否意味着我使用这一行:
grid\u pos=np.unravel\u index(*12*,(240,360))
。另外,12在这一行中指的是什么

正如我所说,使“网格大小”等于图像尺寸将是毫无意义的,因为每个窗口将只包含一个像素(至少,假设窗口不重叠)。12指的是平格窗口的索引,例如:

x = np.arange(25).reshape(5, 5)    # 5x5 grid containing numbers from 0 ... 24
x_flat = x.ravel()                 # flatten it into a 25-long vector
print(x_flat[12])                  # the 12th element in the flattened vector
# 12
row, col = np.unravel_index(12, (5, 5))  # corresponding row/col index in x
print(x[row, col])
# 12
我在每个窗口中移动10个像素,第一个滑动窗口从图像上的坐标0x0开始,第二个从10x10开始,等等,然后我希望程序不仅返回窗口内容,还返回每个窗口对应的坐标,即0,0,然后是10,10,等等

正如我所说,您已经可以使用
get\u win\u pixel\u coords()
返回的上、下、左、右坐标获得窗口相对于图像的位置。如果您真的需要,可以将其封装为单个函数:

def get_pixels_and_coords(win_grid, grid_pos):
    pix = win_grid[grid_pos]
    tblr = get_win_pixel_coords(grid_pos, pix.shape)
    return pix, tblr

# e.g.:
pix, tblr = get_pixels_and_coords(win, (3, 4))
如果需要窗口中每个像素相对于图像的坐标,可以使用的另一个技巧是构造包含图像中每个像素的行和列索引的数组,然后将滑动窗口应用于这些:

ridx, cidx = np.indices(img.shape)
r_win = sliding_window(ridx, (64, 64), shiftSize=None, flatten=False)
c_win = sliding_window(cidx, (64, 64), shiftSize=None, flatten=False)

pix = win[3, 4]    # pixel values
r = r_win[3, 4]    # row index of every pixel in the window
c = c_win[3, 4]    # column index of every pixel in the window

如果您尝试使用
flatte=False
要在图像上创建窗口的“网格”:

import numpy as np
from scipy.misc import lena
from matplotlib import pyplot as plt

img = lena()
print(img.shape)
# (512, 512)

# make a 64x64 pixel sliding window on img. 
win = sliding_window(img, (64, 64), shiftSize=None, flatten=False)

print(win.shape)
# (8, 8, 64, 64)
# i.e. (img_height / win_height, img_width / win_width, win_height, win_width)

plt.imshow(win[4, 4, ...])
plt.draw()
# grid position [4, 4] contains Lena's eye and nose
要获得相应的像素坐标,可以执行以下操作:

def get_win_pixel_coords(grid_pos, win_shape, shift_size=None):
    if shift_size is None:
        shift_size = win_shape
    gr, gc = grid_pos
    sr, sc = shift_size
    wr, wc = win_shape
    top, bottom = gr * sr, (gr * sr) + wr
    left, right = gc * sc, (gc * sc) + wc

    return top, bottom, left, right

# check for grid position [3, 4]
t, b, l, r = get_win_pixel_coords((3, 4), (64, 64))

print(np.all(img[t:b, l:r] == win[3, 4, :, :]))
# True
使用
flatte=True
,64x64像素窗口的8x8网格将被展平为64x64像素窗口的64长矢量。那样的话,你 可以使用类似于
np.unlavel_index
的方法从一维向量索引转换 转换为网格索引的元组,然后使用这些索引获取像素坐标,如下所示: 以上:


好的,我将尝试解决您在评论中提出的一些问题

我想要窗口相对于原始图像的实际像素尺寸的像素位置

也许我不够清楚-您已经可以使用类似我的
get\u win\u pixel\u coords()
函数这样的函数来完成此操作,该函数为您提供窗口相对于图像的顶部、底部、左侧和右侧坐标。例如:

win = sliding_window(img, (64, 64), shiftSize=None, flatten=False)

fig, (ax1, ax2) = plt.subplots(1, 2)
ax1.hold(True)
ax1.imshow(win[4, 4])
ax1.plot(8, 9, 'oy')         # position of Lena's eye, relative to this window

t, b, l, r = get_win_pixel_coords((4, 4), (64, 64))

ax2.hold(True)
ax2.imshow(img)
ax2.plot(t + 8, l + 9, 'oy') # position of Lena's eye, relative to whole image

plt.show()
还请注意,我已经更新了
get_win\u pixel\u coords()
,以处理
shiftSize
不是
None
(即窗口没有完全平铺图像,没有重叠)的情况

所以我猜在这种情况下,我应该使网格等于原始图像的尺寸,对吗?(而不是使用8x8)

不,如果窗口平铺图像而不重叠(即,我目前假设的是
shiftSize=None
),那么如果使网格尺寸等于图像的像素尺寸,则每个窗口将只包含一个像素

所以在我的例子中,对于宽度为360,高度为240的图像,这是否意味着我使用这一行:
grid\u pos=np.unravel\u index(*12*,(240,360))
。另外,12在这一行中指的是什么

正如我所说,使“网格大小”等于图像尺寸将是毫无意义的,因为每个窗口将只包含一个像素(至少,假设窗口不重叠)。12指的是平格窗口的索引,例如:

x = np.arange(25).reshape(5, 5)    # 5x5 grid containing numbers from 0 ... 24
x_flat = x.ravel()                 # flatten it into a 25-long vector
print(x_flat[12])                  # the 12th element in the flattened vector
# 12
row, col = np.unravel_index(12, (5, 5))  # corresponding row/col index in x
print(x[row, col])
# 12
我用每个窗口移动10个像素,第一个滑动窗口从图像上的坐标0x0开始,第二个从10x10开始,以此类推,然后我想让程序
t, b, l, r = get_win_pixel_coords(grid_pos, (96, 96), (48,48))
print(np.all(pad_img[t:b, l:r] == win[239]))
#True