2017-02-14 71 views
8

W aplikacji znajduje się około 1 miliarda obrazów PNG (rozmiar 1024 * 1024 i około 1 MB każdy), wymaga połączenia 1 miliarda obrazów z ogromnym obrazem, a następnie tworzy rozmiar 1024 * 1024 jednolitą miniaturę. . A może nie musimy naprawdę łączyć obrazów z ogromnymi, ale po prostu zrobić jakiś magiczny algorytm, aby stworzyć jednolitą miniaturę w pamięci komputera? Tymczasem proces ten należy wykonać tak szybko, jak to możliwe, lepiej w ciągu kilku sekund lub co najmniej w ciągu kilku minut. Czy ktoś ma pomysł?Jak stworzyć jednolitą miniaturę dla miliarda obrazów PNG?

enter image description here

+2

Amerykański miliard ('10 ** 9') lub unijny miliard (" 10 ** 12 ")? – alk

+0

Średni miliard, ogromna ilość. – Suge

+0

Co masz na myśli przez * jednolitą miniaturę * iw jakim celu? – user694733

Odpowiedz

3

ImageMagick może to zrobić:

montage -tile *.png tiled.png

Jeśli nie chcesz korzystać z zewnętrznego pomocnika z jakiegokolwiek powodu, można nadal korzystać z tych źródeł.

+0

Jest bardzo powolny dla dużej ilości obrazów w moich testach, jakiejkolwiek sugestii? – Suge

+0

Tak więc na klastrze maszyn użycie montażu (z opcją -rasa) umożliwiłoby grupowanie obrazów. Aby osiągnąć swoje cele, najpierw należy utworzyć zestaw zadań nxn i uruchomić je, a następnie na wygenerowanych montażach, powtarzać, aż do momentu, w którym zostaniesz z jednym montażem. – mksteve

9

Pomysł załadowania miliarda obrazów w pojedynczy proces montage jest śmieszny. Twoje pytanie jest niejasne, ale twoim podejściem powinno być ustalenie, ile pikseli każdego oryginalnego obrazu będzie w końcowym obrazie, a następnie wyodrębnienie wymaganej liczby pikseli z każdego obrazu równolegle. Następnie zmontuj te piksele do ostatecznego obrazu.

Tak więc, jeśli każdy obraz będzie reprezentowany przez jednego piksela w końcowym obrazie, trzeba uzyskać średnią z każdego obrazu, które można zrobić tak:

convert image1.png image2.png ... -format "%[fx:mean.r],%[fx:mean.g],%[fx:mean.b]:%f\n" info: 

Wyjście Próbka

0.423529,0.996078,0:image1.png 
0.0262457,0,0:image2.png 

można to zrobić bardzo szybko, a następnie równolegle z GNU Parallel, używając coś jak

find . -name \*.png -print0 | parallel -0 convert {} -format "%[fx:mean.r],%[fx:mean.g],%[fx:mean.b]:%f\n" info: 

Następnie można wykonać ostateczny obraz i umieścić poszczególne piksele.

Skanowanie nawet 1.000.000 plików PNG może trwać wiele godzin ...

Nie mów jak duże obrazy są, ale jeśli są one rzędu 1 MB każdy, a ty masz 1 000 000 000 to musisz zrobić petabajt wejścia/wyjścia, aby je odczytać, więc nawet przy superszybkim SSD 500MB/s będziesz tam 23 dni .

+0

Jeśli obrazy kafelków będą przesyłane od różnych klientów, czy dobrze jest utworzyć reprezentatywny piksel na kliencie przed przesłaniem, a następnie złożyć piksele do obrazu na serwerze? Czy ta droga będzie bardzo szybka? – Suge

+1

Odpowiedź zależy od twojego środowiska, czego niestety nie mogę zrozumieć w obecnym opisie. Jeśli jest 1 000 000 000 klientów, którzy przesyłają Ci obraz, rozsądnie byłoby, gdyby każdy wysłał ci niezbędne minimum. Jeśli jest tylko 1024 klientów, z których każdy dostarcza 1 000 000 obrazów, każdy klient powinien opracować dla ciebie cały blok, ale nie można tego zrobić, jeśli każdy klient wysyła tylko jedno zdjęcie. Ogólnie rzecz biorąc, im więcej maszyn można pracować nad poszczególnymi częściami, tym lepiej. –

+2

Obym z pełnym szacunkiem sugerował, że edytujesz swoje pytanie i poprawisz je, aby ludzie nie musieli zgadywać i tracić czasu na omawianie przypadków, które mogą nie być istotne lub opracowywanie odpowiedzi na podstawie fałszywych założeń wynikających ze złego opisu ... –

3

Losowy algorytm, taki jak losowe pobieranie próbek, może być wykonalny.

Biorąc pod uwagę, że połączony obraz jest tak duży, każdy algorytm liniowy może zawieść, nie mówiąc o wyższej złożoności.

Według obliczeń możemy wnioskować, że każdy piksel zależy od 1000 obrazów. Tak więc pojedynczy próbka resztkowa nie ma wpływu na wynik.

Opis algorytm może się następująco:

dla każdego piksela miniatur współrzędnych losowo wybrać N obrazy, które odpowiadają na miejscu i każdego próbkowania obrazu M pikseli, a następnie obliczyć ich średnią wartość. Zrób to samo dla innych pikseli miniatur.

Jeśli jednak twoje obrazy są losowo łączone, wynikiem jest zazwyczaj 0,5-wartościowy obraz w odcieniach szarości.Ponieważ dzięki środkowemu twierdzeniu granicznemu wariancja piksela obrazu miniaturowego ma zwykle wartość zero. Dzięki temu masz pewność, że połączona miniatura ma samą strukturę.

PS: używanie OpenCV byłoby dobrym wyborem: