Próbuję połączyć w poziomie niektóre obrazy JPEG w Pythonie.
Problem
Mam 3 zdjęcia - każdy ma wymiary 148 x 95 - patrz załączony. Właśnie wykonałem 3 kopie tego samego obrazu - dlatego są takie same.
Moja próba
Próbuję dołączyć do nich poziomo za pomocą następującego kodu:
import sys
from PIL import Image
list_im = ['Test1.jpg','Test2.jpg','Test3.jpg']
new_im = Image.new('RGB', (444,95)) #creates a new empty image, RGB mode, and size 444 by 95
for elem in list_im:
for i in xrange(0,444,95):
im=Image.open(elem)
new_im.paste(im, (i,0))
new_im.save('test.jpg')
Jednak jest to generowanie danych wyjściowych dołączonych jako test.jpg
.
Pytanie
Czy istnieje sposób na poziome połączenie tych obrazów w taki sposób, aby obrazy podrzędne w pliku test.jpg nie miały dodatkowego częściowego obrazu?
Dodatkowe informacje
Szukam sposobu na poziome połączenie n obrazów. Chciałbym ogólnie używać tego kodu, więc wolałbym:
- jeśli to możliwe, nie zakodować na stałe wymiarów obrazu
- określ wymiary w jednej linii, aby można je było łatwo zmienić
for i in xrange(...)
w Twoim kodzie jest znak ? Nie powinieneśpaste
zająć się trzema określonymi plikami graficznymi?Odpowiedzi:
Możesz zrobić coś takiego:
Test1.jpg
Test2.jpg
Test3.jpg
test.jpg
Zagnieżdżenie dla
for i in xrange(0,444,95):
polega na wklejaniu każdego obrazu 5 razy w odstępie 95 pikseli. Każda iteracja pętli zewnętrznej wklejana na poprzednią.źródło
x_offset = 0
- czy to jest rozchodzenie się między centrami obrazu? 2. W przypadku konkatenacji pionowej, jak zmienia się twoje podejście?x_offset
asleft
. W przypadku łączenia pionowego śledźy-offset
lubtop
. Zamiastsum(widths)
andmax(height)
, zróbsum(heights)
imax(widths)
i użyj drugiego argumentu z 2 krotki. zwiększyćy_offset
oim.size[1]
.map
wSpróbowałbym tego:
Powinien działać, o ile wszystkie obrazy są tej samej odmiany (wszystkie RGB, wszystkie RGBA lub wszystkie skale szarości). Nie powinno być trudno upewnić się, że tak jest w przypadku kilku dodatkowych wierszy kodu. Oto moje przykładowe obrazy i wynik:
Test1.jpg
Test2.jpg
Test3.jpg
Trifecta.jpg:
Trifecta_vertical.jpg
źródło
min_shape =....
iimgs_comb....
zmiana na pionowej konkatenacji? Czy możesz zamieścić to tutaj jako komentarz lub w swojej odpowiedzi?hstack
navstack
.Image.resize
z PIL.min_shape
jest krotką (min_width, min_height), a następnie(np.asarray( i.resize(min_shape) ) for i in imgs )
zmniejszy wszystkie obrazy do tego rozmiaru. W rzeczywistościmin_shape
może to być dowolny(width,height)
, ale pamiętaj, że powiększanie obrazów o niskiej rozdzielczości sprawi, że będą rozmazane!Edycja: odpowiedź DTing jest bardziej odpowiednia dla twojego pytania, ponieważ używa PIL, ale zostawię to na wypadek, gdybyś chciał wiedzieć, jak to zrobić w numpy.
Oto rozwiązanie numpy / matplotlib, które powinno działać dla N obrazów (tylko kolorowych obrazów) o dowolnym rozmiarze / kształcie.
Oto przykład użycia:
źródło
output = concat_images(output, ...
jest tym, czego szukałem, kiedy zacząłem szukać sposobu, aby to zrobić. Dzięki.Na podstawie odpowiedzi DTing stworzyłem funkcję, która jest łatwiejsza w użyciu:
Pozwala na wybór koloru tła i wyrównanie obrazu. Rekurencję można również łatwo wykonać:
źródło
Oto funkcja uogólniająca poprzednie podejścia, tworząca siatkę obrazów w PIL:
Zmniejszy każdy wiersz i kolumny siatki do minimum. Możesz mieć tylko wiersz, używając pil_grid (obrazy), lub tylko kolumnę, używając pil_grid (obrazy, 1).
Jedną z zalet korzystania z PIL w porównaniu z rozwiązaniami opartymi na tablicach numpy jest to, że można radzić sobie z obrazami o różnej strukturze (jak obrazy w skali szarości lub oparte na palecie).
Przykładowe wyjścia
pil_grid(dummy_images)
:pil_grid(dummy_images, 3)
:pil_grid(dummy_images, 1)
:źródło
h_sizes, v_sizes = [0] * n_horiz, [0] * (n_images // n_horiz)
powinien brzmieć:h_sizes, v_sizes = [0] * n_horiz, [0] * ((n_images // n_horiz) + (1 if n_images % n_horiz > 0 else 0))
Powód: Jeśli pozioma szerokość nie dzieli liczby obrazów w liczbach całkowitych, musisz uwzględnić dodatkową, jeśli niekompletną linię.Jeśli wszystkie wysokości obrazu są takie same,
może możesz zmienić rozmiar obrazów przed połączeniem w ten sposób,
źródło
Oto moje rozwiązanie:
W przypadku tych obrazów:
Wyniki będą wyglądać następująco:
źródło
źródło
Wynik
źródło
Po prostu dodając do rozwiązań już sugerowanych. Przyjmuje tę samą wysokość, bez zmiany rozmiaru.
źródło
moim rozwiązaniem byłoby:
źródło