Комментарии 16
Здесь n — количество признаков, в нашем случае 3 x n x m
Я так понимаю, здесь ошибка, и вместр первой n следует использовать другой символ, например, N?
Без нейронок не модно же такие задачи решать.
Еще немного про функцию потерь. У вас формулы расстояния между цветами:
- лучше не использовать. По производительности нет выигрыша, и сильно ошибается
- корень можно не считать, так как он не влияет на результат сравнения. Получится просто d = (R1-R2)² + (G1-G2)² + (B1-B2)²
- добавились коэффициенты, но эти коэффициенты показывают лишь вклад в яркость — их нельзя здесь применять. Так например синяя компонента даёт самый малый вклад в яркость, но самый большой — в насыщенность
- возведение коэффициентов в квадрат, это просто плохо
Виденные мною мозаики из изображений, казалось, учитывали и содержимое изображений, а не только среднее значение цвета.
Рандомная картинка из интернета
Кажется, что прядь волос создана фотографиями, у которых есть темная область в нужной части, что позволяет добиться большей детализации общего изображения при том же размере
элемента мозаики. Хотя, не могу утверждать, что это действительно так.
Подход очень похож на ваш был. С одним небольшим улучшением.
Допустим, мы уже нашли маленькую картинку, наилучшим образом подходящую на роль «пиксела». Но ведь почти наверняка её RGB не на 100% соответствует желаемому. Что делать? Тогда мы берём и чуть-чуть «докрашиваем» её на недостающую разницу по R, G, и B, чтобы она совпала точно. Итоговая мозаика получается куда глаже и достовернее.
Ух, исходники даже нашел :) Тольно на 10ке хрен знает как его включить
Спасибо за статью!
Пошел немного по другому: датасет пообрезал и пережал в картинки 16х16, потом для каждой рассчитано среднее по hue-каналу, запомнено напротив имени файла и сортировано по средним. Целевое изображение разбивается на плитку соответственно 16х16 и для каждого фрагмента также считается среднее, находится по базе номер, который этот фрагмент бы в ней занял, и поднимаем в окрестности этого номера кучку картинок, которые уже можно сравнивать суммами квадратов разностей. Ну и наиболе подходящие пазлы идут в конечную картинку
using Images
using Statistics: mean
pth = s"D:\inter3\Cat Annotation Dataset"
folderz = readdir(pth)
@time for foldr in folderz
filez = readdir("$pth/$foldr")
for fl in filez
imgi = load("$pth/$foldr/$fl")
if min( size(imgi)... ) < 256 continue end
if typeof(tmp[1]) == Gray{Normed{UInt8,8}} continue end
if min( size(imgi)... ) < 512
imgc = imgi[1:256, 1:256]
else
imgc = imgi[1:512, 1:512]
end
imgr = imresize(imgc, sz, sz)
save("ketz16/$fl", imgr)
end
end
filez = readdir("ketz16")
meanz = zeros(length(filez))
for (i,fl) in enumerate(filez)
tmp = load("ketz16/$fl")
meanz[i,:] = mean( hue.( float.( HSV.(tmp) ) ) )
end
indcs = sortslices( [meanz filez], dims = 1 );
using DelimitedFiles
# indcs = readdlm("meanzandnamez.txt", ',', Float64)
open("meanzandnamezcat.txt", "w") do io
writedlm(io, indcs)
end
imgo = load("test3.jpg")
n, m = size(imgo)
n ÷= sz
m ÷= sz
Mx = [ imgo[(i-1)*sz:i*sz-1, (j-1)*sz:j*sz-1] for i in 2:n, j in 2:m ];
function simil(part, w)
u = mean( hue.( float.( HSV.(part) ) ) )
ii = searchsorted(indcs[:,1], u)
ii.start+w >= size(indcs,1) ? (ww = size(indcs,1)-ii.start-1) : (ww = w)
dists = []
for i in ii.stop-w:ii.start+ww
tmp = load("ketz16/$(indcs[i,2])")
if typeof(tmp[1]) == Gray{Normed{UInt8,8}} continue end
s = sum(x-> x^2, Float64.(channelview(part)) - Float64.(channelview(tmp)) )
push!( dists, s)
end
num = ii.stop-w + argmin(dists) - 1
load("ketz16/$(indcs[num,2])")
end
@time Mxx = [ simil(prt, 80) for prt in Mx ];
function combiner(arr)
N, M = size(arr)
n, m = size(arr[1])
brr = zeros(RGBA{Normed{UInt8,8}}, N*n, M*m)
for i in 1:N, j in 1:M
x = 1+n*(i-1)
y = 1+m*(j-1)
brr[x:x+n-1,y:y+m-1] = arr[i,j]
end
brr
end
save( "testt3.jpg", combiner(Mxx) )
Теперь нужен датасет поприличней
Создание мозаичной картинки