Все остальные оценки: 79, 155, 395, 2449
. Для оценки этой категории различные столбцы исходного изображения смешиваются в тестовом изображении, соответствующем оценке. Например, если оценка составляет 79
, у нас есть 155 % 79 == 76
, то есть каждая новая строка в тестовом изображении смещает исходные столбцы на 3 относительно предыдущей строки. Предполагая, что исходное изображение изменяется по размеру столбца, эти сдвиги будут представлять все более сильное отклонение для появляющихся последовательных строк. Поскольку этот сдвиг столбцов увеличивается от строки к строке, результирующее уменьшение сглаживания строк должно быть значительным, если только число строк не мало. Если исходное изображение столбца-periodi c с номером сдвига оценки, это может привести к идеальному согласию, однако. мы ожидаем, что гладкость уменьшится при неправильной оценке, и уменьшение будет небольшим, если оценка относится к категории (1), и больше, если оно относится к категории (2). Важно: Если изображения имеют период c вдоль измерения строки или столбца, это может привести к неверной оценке.
Реализация должна охватывать следующие шаги:
- Вычислить простое число факторизация длины сглаженного изображения.
- Вычислите все уникальные оценки размера строки из комбинаций простых факторов.
- Для каждой оценки вычислите сглаживание строк полученного тестового изображения. Например, используйте среднеквадратичную ошибку последовательных строк (на самом деле это будет оценка неравномерности).
- Найдите наилучшую оценку по оценкам.
Вот пример кода для реализации:
import itertools as it
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
image = np.array(Image.open('example.jpg'))
original_shape = image.shape[:2]
image = image.reshape(-1, 3)
def compute_prime_factors(n):
i = 2
while i <= n:
if n % i == 0:
n //= i
yield i
else:
i += 1
prime_factors = list(compute_prime_factors(len(image)))
combinations = it.chain.from_iterable(it.combinations(prime_factors, r=i) for i in range(1, len(prime_factors)))
row_dims = sorted({np.prod(x) for x in combinations})
def test_row_dim(r):
c = len(image) // r
test = image.reshape(r, c, 3)
return np.mean((test[1:] - test[:-1])**2)
scores = [test_row_dim(r) for r in row_dims]
best_estimate = row_dims[np.argmin(scores)]
fig, ax = plt.subplots()
ax.set(xlabel='row dimension', ylabel='score')
ax.set_xscale('log')
ax.plot(row_dims, scores, '-o', label='Estimations')
ax.plot([best_estimate], [np.min(scores)], '*', ms=12, label=f'Best Estimate ({best_estimate})')
ax.axvline(original_shape[0], label=f'Actual Dim ({original_shape[0]})', color='#2ca02c', zorder=-100, lw=1.5, ls='--')
ax.legend()
plt.figure()
plt.imshow(image.reshape(205, -1, 3)) # second best score
plt.show()
Давайте проверим это на некотором изображении (H x W: 410 x 640
):
Фото Камерона Венти на Unspla sh
Это дает следующие оценочные баллы:
пики слева от наилучшей оценки - это оценки категории (1), которые имеют наименьший пропуск строки. Первичная факторизация 410
и 640
составляет 2*5*41
и 2**7 * 5
соответственно. Таким образом, оценки категории (1), наиболее близкие к исходному измерению строки, равны 205
, 82
и 41
(боковые пики справа налево). Уменьшение оценки подразумевает увеличение диапазона пропуска строк и, следовательно, увеличение оценки MSE. Пик слева от наилучшей оценки соответствует оценке 205
, то есть каждая вторая строка пропускается и, следовательно, две такие пропущенные строки располагаются рядом друг с другом:
Как вы можете себе представить, пропуская каждую вторую строку, изображение не слишком сильно меняется, и изменение одинаково для двух параллельных версий. Отсюда и небольшая разница с оценкой MSE исходного изображения.