Este repositório inclui o código (e outros arquivos) para criar versões artísticas em mosaico de uma determinada imagem. Dada uma imagem (referida como imagem original), a ideia principal é substituir fragmentos (em formato quadrado) da imagem original pela imagem mais semelhante de um determinado conjunto de imagens (referidas como imagens lado a lado ou simplesmente blocos) .
A implementação usa o modelo Stable Diffusion disponível no submódulo KerasCV de Keras para criar os blocos. Ele permite criatividade ilimitada ao criar arte em mosaico da mesma imagem usando diferentes blocos criados alterando os parâmetros do modelo e usando diferentes prompts de texto.
Nos exemplos abaixo, cada linha mostra uma imagem (original) e duas imagens de arte em mosaico criadas a partir dela. A imagem mais à esquerda é a imagem original, e a imagem do meio é a arte em mosaico criada com 2.500 peças, e a imagem mais à direita é a arte em mosaico criada com 90.000 peças.
Os principais arquivos e pastas incluídos neste repositório são:
images/tiles
.images/canvases
e também o código para criar as imagens dos blocos. As principais dependências são TensorFlow/Keras
(pelo menos versão 2.9), Pillow
e Scipy
. Se você usa Pip, pode instalá-los executando o seguinte comando:
pip install -r requirements.txt
Além disso, o código é escrito em Python 3.9 e testado em um computador rodando Ubuntu 22.04 LTS com Keras 2.9 (e KerasCV 0.3.4) em uma GPU NVIDIA RTX 3090 com CUDA 11.6.
Abra Making Mosaic Art usando o bloco de notas KerasCV + StableDiffusion para ver o código.
Além disso, você pode modificar as variáveis e parâmetros na função principal (mostrada abaixo) para criar suas próprias versões de arte em mosaico das imagens fornecidas. Você pode colocar suas imagens na pasta images/canvases
se quiser criar versões artísticas em mosaico delas.
def main ( remake_tiles : bool ) -> None :
"""Main function to pack everything together and run it"""
# Extension to use for saving and loading the tile images
tile_file_extension = "jpeg"
# (Re)-make the tile images if the user wants to do so
if remake_tiles :
# Create a MosaicMaker object to make the tile images
image_maker = MosaicMaker ( img_width = 400 , img_height = 400 , jit_compile = False , seed = 33 )
# The text prompts to be used to make the tile images
prompt_seq = (( "A laughing woman" , ( "realistic" , "white background" )),
( "A sad girl" , ( "realistic" , "white background" )),
( "An old man" , ( "realistic" , "white background" )),
( "Face of a sad man" , ( "realistic" , "white background" )),
( "Drawing of rings of Saturn" , ( "abstract" , "white background" )),
( "A watercolor painting of a puppy" , ( "detailed" ,)),
( "Drawing of a red rose" , ( "elegant" , "detailed" , "white background" )),
( "View of a green forest with mountains in the background" , ( "elegant" , "lush" , "nature" )),
( "A painting of four oranges in a bowl" , ( "elegant" , "detailed" , "white background" )),
( "A ninja shuriken" , ( "realistic" , "metal" , "white background" )),)
# Make the tile images and save them
for index , prompt_data in enumerate ( prompt_seq ):
image_seq = image_maker . make_images ( prompt_data [ 0 ], prompt_data [ 1 ], num_images = 40 )
image_maker . save_images ( img_seq = image_seq , path = 'images/tiles' , prefix = f'p { index } ' ,
extension = tile_file_extension )
# Use the images in the images/canvases and images/tiles directories to make mosaic arts
for canvas_image_path in pathlib . Path ( "images/canvases" ). glob ( "*.png" ):
# Create a MosaicArtMaker object with about sqrt_num_tiles*sqrt_num_tiles tiles!
art_maker = MosaicArtMaker ( original_image_path = canvas_image_path , sqrt_num_tiles = 300 ,
tile_file_extension = tile_file_extension )
# Make the mosaic art and save it in the images/outputs directory
output_image = art_maker . make_mosaic_art ( k = 40 )
print ( f"Created a mosaic art version of ' { art_maker . original_image_path } ' using "
f" { art_maker . sqrt_num_tiles * art_maker . sqrt_num_tiles } smaller images created by a Stable Diffusion model" )
art_maker . save_images (( output_image ,), path = 'images/outputs' ,
prefix = f' { art_maker . original_image_name } _mosaic_art' )
# Display each original image and its mosaic art version
art_maker . display_images (( art_maker . original_image , output_image ),
( art_maker . original_image_name , art_maker . original_image_name + "_mosaic_art" ))
Execute a função principal para executar o código. Se você quiser refazer as imagens dos blocos, defina o parâmetro remake_tiles
como True
. Observe que a criação de um novo conjunto de imagens de blocos pode demorar um pouco, por isso é recomendável usar as imagens de blocos atuais no início, definindo remake_tiles
como False
.
main ( remake_tiles = False )
O notebook já está disponível no Kaggle. Você pode abri-lo usando este link.
- [ ] Usando formas diferentes em vez de quadrados (do mesmo tamanho) para as peças. Por exemplo, trapézios ou triângulos.
- [ ] Usando diferentes imagens lado a lado para diferentes partes da imagem original. Por exemplo, usando um conjunto de imagens contendo rostos como rostos na imagem original e usando um conjunto de imagens contendo paisagens como plano de fundo na imagem original.
- [] Usando melhores métricas de similaridade para comparar os blocos com um patch da imagem original. Por exemplo, usando a métrica SSIM em vez da distância euclidiana.
Este projeto está licenciado sob os termos da licença Apache 2.0. Consulte LICENÇA para obter mais detalhes. Observe que os arquivos de imagem em imagens/telas foram baixados da Web e não são de propriedade do criador deste repositório. Conseqüentemente, eles não podem ser licenciados sob a licença Apache 2.0.