2014-12-20 2 views
0

Ссылаясь на эту отличную реализацию разворачивающего окна в python: https://github.com/keepitsimple/ocrtest/blob/master/sliding_window.py#blob_contributors_box, мой вопрос: где в коде я могу увидеть местоположение текущего окна на изображении? Или как я могу захватить его местоположение?Скользящее окно - как получить окно на изображении?

В строках 72 и после строки 85, я пробовал распечатать shape и newstrides, но я явно ничего не получаю здесь. В функции norm_shape я распечатал tuple, но на выходе были только размеры окна (если я тоже это понял).

Но мне нужно не только размеры, такие как ширина и высота, мне также нужно знать , где точно из изображения извлекается окно с точки зрения координат пикселя или какие строки/столбцы в образ.

ответ

2

Это может быть проще для вас, чтобы понять, что происходит, если вы пытаетесь с помощью 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 
+0

Спасибо! Но я хочу, чтобы положение пикселя окна относительно фактического размера пикселей пикселя. Поэтому я предполагаю, что в этом случае я должен просто сделать сетку равной размеру исходного изображения, верно? (вместо использования 8x8). Поэтому в моем случае для изображения ширины: 360 и height: 240 это означало бы, что я использую эту строку: 'grid_pos = np.unravel_index (* 12 *, (240, 360))'. Кроме того, что означает '12' в этой строке? – user961627

+0

На самом деле, я не хочу * давать * моей программе пиксельные координаты, из которых я надеюсь, что это покажет мне соответствующее окно. Напротив, я хочу, чтобы программа давала мне координаты каждого окна относительно абсолютных размеров оригинального изображения. Например, если я сдвигаю 10 пикселей с каждым окном, а первое скользящее окно начинается с координат 0x0 на изображении, а второе начинается с 10x10 и т. Д., То я хочу, чтобы программа возвращала не только содержимое окна, но и координаты, соответствующие каждому окну, то есть 0,0, а затем 10,10 и т. д. – user961627

+0

Большое спасибо. Я прошел через код lena и попробовал, и он работает. Но есть два вопроса. Первая проблема заключается в том, что, когда я использую flatten = False, кажется, что это нормально, но я получаю намного меньше окон, чем раньше. Мой старый код был следующим: 'windows = sw.sliding_window (image1, window_size, step_size, flatten = True) для w в окнах: #, а затем я схватил каждую w и распечатал ее'. С тем же изображением и старым кодом я получил приблизительно 5400 изображений. Но в этом случае я получаю 126. У меня размер шага 10, а исходное изображение - 360x240. – user961627

Смежные вопросы