Как получить только возможные неперекрывающиеся блоки из изображений любого заданного размера и показать их в Python

#python #opencv #scikit-learn #scikit-image

#python #opencv #scikit-learn #scikit-image

Вопрос:

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

Однако, поскольку изображения не имеют фиксированного размера, а размер моего блока большой (64×64), я хотел бы получить только неперекрывающиеся блоки, которые можно было бы найти на изображении. Если блок превышает границы изображения, я не хочу их получать.

Я попробовал функцию view_as_blocks из scikit-image, как показано ниже:

 from skimage.util import view_as_blocks
for elem in listOfFiles:
    # Reading image
    print("Reading image " elem)

    img = cv2.imread(elem)
    print(img.shape) #for example, one image is (2059, 2059, 3)

    Blocks = view_as_blocks(img, block_shape=(64, 64, 3))
  

Код возвращает следующую ошибку:

 ValueError: 'block_shape' is not compatible with 'arr_in'
  

Я также попробовал извлечь патч из scikit-learn следующим образом:

 from sklearn.feature_extraction import image
import cv2
import numpy 

for elem in listOfFiles:
    # Reading image
    print("Reading image " elem)

    img = cv2.imread(elem)
    print(img.shape)

    pe = image.PatchExtractor(patch_size=(64,64))
    pe_fit = pe.fit(img)
    pe_trans = pe.transform(img)
    print('Patches shape: {}'.format(pe_trans.shape))
  

Ошибка, которая возвращается ко мне, заключается в следующем:

 ValueError: negative dimensions are not allowed
  

функция image.extract_patches_2d из sklearns работает отлично, но, к сожалению, она работает только для перекрывающихся блоков, как вы можете видеть здесь.

Эти функции также не помогают мне, потому что я также хочу показать изображение с выделенными этими блоками, поэтому мне также нужна другая матрица с координатами таких блоков и показать выбранные блоки.

Возможно ли это в Python?

Комментарии:

1. Блоки по умолчанию не перекрываются, вам просто нужно исправить форму блока сейчас

Ответ №1:

Поскольку вас не волнуют неполные блоки по краям, вы можете вручную проверить количество блоков по каждому измерению и обрезать изображение до этой формы:

 from skimage.util import view_as_blocks


for elem in listOfFiles:
    # Reading image
    print("Reading image " elem)

    img = cv2.imread(elem)
    print(img.shape) #for example, one image is (2059, 2059, 3)
    block_shape = np.array((64, 64, 3))
    nblocks = np.array(img.shape) // block_shape  # integer division
    crop_r, crop_c, crop_ch = nblocks * block_shape
    cropped_img = img[:crop_r, :crop_c, :crop_ch]
    Blocks = view_as_blocks(cropped_img, block_shape=(64, 64, 3))