Это может быть проще для вас, чтобы понять, что происходит, если вы пытаетесь с помощью flatten=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
С flatten=True
, 8х8 сетка 64х64 пикселов окна будет просто получить выровнялся в 64 длиной вектора 64x64 пикселов окна. В этом случае вы могли бы использовать что-то вроде np.unravel_index
конвертировать из индекса вектора 1D в кортеж индексов сетки, а затем использовать их, чтобы получить координаты пикселей, как выше:
win = sliding_window(img, (64, 64), flatten=True)
grid_pos = np.unravel_index(12, (8, 8))
t, b, l, r = get_win_pixel_coords(grid_pos, (64, 64))
print(np.all(img[t:b, l:r] == win[12]))
# True
OK, I Попробую и рассмотрим некоторые вопросы, которые вы задали в комментариях.
Я хочу, чтобы положение пикселя окна относительно фактического размера пикселей исходного изображения.
Возможно, я не был достаточно ясно, - вы уже можете сделать это, используя что-то вроде моей get_win_pixel_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_pixel_coords()
для рассмотрения случаев, когда shiftSize
не None
(т.е. окна не полностью замостить изображение без перекрытия).
Так что я предполагаю, что в этом случае я должен просто сделать сетку равной размеру исходного изображения, верно? (вместо использования 8x8).
Нет, если плитка окна изображения без перекрытия (т.е. shiftSize=None
, который я предполагал, до сих пор), а затем, если вы сделали сетку размеров равна размерами пикселов изображения, каждое окно будет содержать только один пиксель!
В моем случае, для изображения ширины: 360 и высоты: 240, это означало, что я использую эту строку: grid_pos = np.unravel_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_win_pixel_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
Спасибо! Но я хочу, чтобы положение пикселя окна относительно фактического размера пикселей пикселя. Поэтому я предполагаю, что в этом случае я должен просто сделать сетку равной размеру исходного изображения, верно? (вместо использования 8x8). Поэтому в моем случае для изображения ширины: 360 и height: 240 это означало бы, что я использую эту строку: 'grid_pos = np.unravel_index (* 12 *, (240, 360))'. Кроме того, что означает '12' в этой строке? – user961627
На самом деле, я не хочу * давать * моей программе пиксельные координаты, из которых я надеюсь, что это покажет мне соответствующее окно. Напротив, я хочу, чтобы программа давала мне координаты каждого окна относительно абсолютных размеров оригинального изображения. Например, если я сдвигаю 10 пикселей с каждым окном, а первое скользящее окно начинается с координат 0x0 на изображении, а второе начинается с 10x10 и т. Д., То я хочу, чтобы программа возвращала не только содержимое окна, но и координаты, соответствующие каждому окну, то есть 0,0, а затем 10,10 и т. д. – user961627
Большое спасибо. Я прошел через код lena и попробовал, и он работает. Но есть два вопроса. Первая проблема заключается в том, что, когда я использую flatten = False, кажется, что это нормально, но я получаю намного меньше окон, чем раньше. Мой старый код был следующим: 'windows = sw.sliding_window (image1, window_size, step_size, flatten = True) для w в окнах: #, а затем я схватил каждую w и распечатал ее'. С тем же изображением и старым кодом я получил приблизительно 5400 изображений. Но в этом случае я получаю 126. У меня размер шага 10, а исходное изображение - 360x240. – user961627