Skip to content

Instantly share code, notes, and snippets.

@aragaer
Created October 15, 2019 17:29
Show Gist options
  • Save aragaer/2d651a1584e2c2fc5d7e6cb6c9858257 to your computer and use it in GitHub Desktop.
Save aragaer/2d651a1584e2c2fc5d7e6cb6c9858257 to your computer and use it in GitHub Desktop.
literate python - kinda

Подготовительные вещи

РЕСЕТ СЕССИИ

(setq kill-buffer-query-functions
      (remq 'process-kill-buffer-query-function
            kill-buffer-query-functions))
(kill-buffer "wall")

Сначала надо выставить правильный virtualenv

(pyvenv-deactivate)
(pyvenv-activate (concat (file-name-directory (or load-file-name buffer-file-name)) ".venv"))

Поставить нужные пакеты

echo $VIRTUAL_ENV
which python
pip install --upgrade Pillow
pip install nose

Всякие очень нужные импорты

import os
import sys

import numpy as np

from PIL import Image

Константы

SIZE_X = 100
SIZE_Y = 100
OFFT_X = 50
OFFT_Y = 50

USE_CHANNELS = True

Функции для загрузки изображений

get_new_size

  • Возвращает новый размер для картинки.
  • Пропорции сохраняются.
  • x должен стать не менее SIZE_X
  • y должен стать не менее SIZE_Y
def get_new_size(x, y):
    ratio = max(SIZE_X / x, SIZE_Y / y)
    return int(x * ratio), int(y * ratio)

Тесты

from nose.tools import eq_
print("Running get_new_size tests")
eq_(get_new_size(SIZE_X, SIZE_Y), (SIZE_X, SIZE_Y))
eq_(get_new_size(SIZE_X, SIZE_Y*2), (SIZE_X, SIZE_Y*2))
eq_(get_new_size(SIZE_X*2, SIZE_Y), (SIZE_X*2, SIZE_Y))
eq_(get_new_size(SIZE_X*2, SIZE_Y*2), (SIZE_X, SIZE_Y))
eq_(get_new_size(SIZE_X*3, SIZE_Y*2), (SIZE_X*1.5, SIZE_Y))
print("get_new_size tests passed")

get_offsets

  • Принимает размер size_x, size_y
  • Возвращает список пар (x, y)
  • Первая пара должна быть 0, 0
  • Каждая последующая смещена либо по x, либо по y не более чем на OFFT_X/OFFT_Y
  • Для последней пары x+SIZE_X, y+SIZE_Y = size_x, size_y
# Беда - ob-python не работает с уменьшением индентации
# Приходится раскидывать по разным функциям
def _slide_x(x):
    last = [(x-SIZE_X, 0)] if x % OFFT_X else []
    return [(i*OFFT_X, 0) for i in range(x//OFFT_X-1)] + last

def _slide_y(y):
    last = [(0, y-SIZE_Y)] if y % OFFT_Y else []
    return [(0, i*OFFT_Y) for i in range(y//OFFT_Y-1)] + last

def get_offsets(x, y):
    return _slide_x(x) if x > y else _slide_y(y)

Тесты

from nose.tools import eq_
print("Running get_offsets tests")
eq_(get_offsets(SIZE_X, SIZE_Y), [(0, 0)])
eq_(get_offsets(SIZE_X+OFFT_X, SIZE_Y), [(0, 0), (OFFT_X, 0)])
eq_(get_offsets(SIZE_X+OFFT_X*2, SIZE_Y), [(0, 0), (OFFT_X, 0), (OFFT_X*2, 0)])
eq_(get_offsets(SIZE_X+1, SIZE_Y), [(0, 0), (1, 0)])
eq_(get_offsets(SIZE_X, SIZE_Y+OFFT_Y), [(0, 0), (0, OFFT_Y)])
eq_(get_offsets(SIZE_X, SIZE_Y+OFFT_Y*2), [(0, 0), (0, OFFT_Y), (0, OFFT_Y*2)])
eq_(get_offsets(SIZE_X, SIZE_Y+1), [(0, 0), (0, 1)])
print("get_offsets tests passed")

load_image

  • Принимает имя файла
  • Возвращает 4-мерный массив ?x100x100x3
def load_image(filename):
    mode, channels = ("RGB", 3) if USE_CHANNELS else ("L", 1)
    image = Image.open(filename)
    image = image.resize(get_new_size(*image.size), Image.ANTIALIAS).convert(mode)
    images = [image.crop((x, y, x+SIZE_X, y+SIZE_Y)) for x, y in get_offsets(*image.size)]
    result = np.empty((len(images), *images[0].size, channels))
    result[:] = [np.array(i) / 128.0 - 1 for i in images]
    return result

Фичи

Есть набор фичей. У каждого изображения либо фичи присутствуют, либо не присутствуют, либо не определено. Информация об изображении хранится в файле <hash>.txt, где hash это sha1 хэш всего изображения. Предполагается, что фичи присутствуют в каждом из блоков изображения. (Это может быть на самом деле не так. Как с этим бороться?)

Пробуем!

load_image(os.path.expanduser("~/Pictures/wallpapers/0002.jpg"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment