2016-12-14 3 views
1

Я работаю над обнаружением объектов в изображениях и использую векторный массив срезов изображения из скользящего окна на основном изображении. Я хотел бы изменить размер всех окон до небольшого размера для перехода к детектору объекта. К сожалению, я нахожу, что когда я использую функцию изменения размера opencv, она может изменять размер маленького фрагмента изображений, которые я передаю ему сразу, прежде чем он перестанет работать.Существует ограничение максимального размера массива для функции изменения размера opencv?

В заключительных строках приведенного ниже кода есть две строки, указывающие количество окон, чтобы попытаться изменить размер сразу. Для данного размера окна он работает с 512 и не работает с 513 окнами. Если в функции изменения размера существует ограничение максимального размера массива, то это будет разница между значениями массива 3481600 и 3488400.

Я не смог найти что-либо в документации opencv, ссылающейся на ограничение размера для функции изменения размера, но кто-нибудь столкнулся с этой проблемой?

Существуют ли другие функции изменения размера в разных модулях, которые, как известно, имеют большую емкость для сокращения вектора фрагментированного изображения?

Моя текущая работа заключалась в том, чтобы перебирать массив изображений, изменяя их размеры в кусках, меньших, чем мой экспериментально определенный максимальный размер массива.

Любые советы/мудрость оцениваются!

import cv2 
import numpy as np 

img = cv2.imread('best_of_hope_kolosser_water_snow.jpg') 
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 


## ---- these would normally be function arguments for this module ------- 
window_size = np.resize(np.array([int(100/1.45),100]),(1,2)) 
w = 0 
strX_wPerc = 1/6 
strY_wPerc = 1/6 
data_patch_size = (30,46) 
## ---- end of; locally defining function arguments for module -------- 

## ---- sliding window params ----- 
win_w = window_size[w,0] 
win_h = window_size[w,1] 
strideX = int(window_size[w,0]*strX_wPerc) 
strideY = int(window_size[w,1]*strY_wPerc) 
## ---------------------------------- 

print('img shape: ', img.shape) 
# ^^ prints: img shape: (1200, 1920) 

## -------- sliding window vectorization steps -------------------------- 
num_vert_windows = len(np.arange(0,img.shape[0]-window_size[w,1],strideY)) # number of vertical windows that will be created 
indx = np.arange(0,img.shape[0]-window_size[w,1],strideY)[:,None]+np.arange(window_size[w,1]) # index that will be broadcasted across image 
vertical_windows = img[indx] # array of windows win_h tall and the full width of the image 

vertical_windows = np.transpose(vertical_windows,(0,2,1)) # transpose to prep for broadcasting 
num_horz_windows = len(np.arange(0,vertical_windows.shape[1]-window_size[w,0],strideX)) # number of horizontal windows that will be created 
indx = np.arange(0,vertical_windows.shape[1]-window_size[w,0],strideX)[:,None]+np.arange(window_size[w,0]) # index for broadcasting across vertical windows 
all_windows = vertical_windows[0:vertical_windows.shape[0],indx] # array of all the windows 
## -------- end of, sliding window vectorization ------------------------ 

total_windows = num_vert_windows*num_horz_windows 
all_windows = np.transpose(all_windows,(3,2,1,0)) # rearrange for resizing and intuitive indexing 
all_windows = np.resize(all_windows,(window_size[w,1],window_size[w,0],total_windows)) # resize to stack all windows 

print('sliding windows height:',all_windows.shape[0],', width:',all_windows.shape[1],', number of windows:',all_windows.shape[2]) 
# ^^ prints: sliding windows height: 100 , width: 68 , number of windows: 11661 

##num_windows_to_resize = all_windows.shape[2] # ideally this would resize them all at once 
num_windows_to_resize = 512 # 513 fails 
small_windows = cv2.resize(all_windows[:,:,0:num_windows_to_resize],data_patch_size,0,0,cv2.INTER_AREA) 

print('final windows (height, width, # windows):',small_windows.shape) 
# ^^ if resizing less than 513 windows, prints: final windows (height, width, # windows): (46, 30, 512) 
# ^^ if resizing more than 512 windows, prints: final windows (height, width, # windows): (46, 30) 

ответ

1

Просто чтобы прояснить, что вы спрашиваете можно суммировать в следующем

>>> cv2.resize(np.zeros([1200,1920,512]), (30,46)).shape 
(46,30,512) 
>>> cv2.resize(np.zeros([1200,1920,513]), (30,46)).shape 
(46,30) 

Так почему же первая линия изменяет все каналы, в то время как вторая линия, кажется, приводит только 1 канал?

Я обнаружил, что по умолчанию OpenCV не поддерживает более 512 каналов в одном изображении. Как определено в cvdef.h

#define CV_CN_MAX  512 

Так что же происходит, что ввод cv2.resize сводится только к первому каналу. Не рекомендуется также изменять максимальные каналы, как описано здесь: http://answers.opencv.org/question/46296/increase-the-maximum-amount-of-channels-in-cvmat/ Так, к сожалению, это означает, что вам придется изменять размер в партиях.

+0

Спасибо iamai, что объясняет проблему. Я, вероятно, буду искать еще один маршрут для сокращения этих фрагментов в пакете, отличном от изображения, поскольку я не понимал, что opencv интерпретировал мой индексный ввод как цветные каналы. Также спасибо за то, что кипятил мой вопрос так ясно. Должен ли я редактировать свой вопрос, чтобы он содержал только важную часть, о которой вы говорили, или просто оставить ее как есть? – Scout2013