Um mosaico de imagens é a organização de um conjunto de imagens que resulte em uma nova imagem. Para essa implementação serão utilizados a linguagem Python, as bibliotecas cv2 (OpenCV) e Numpy, um banco de imagens e uma imagem principal.
A ideia principal do algoritmo consiste em:
- Segmentar a imagem original em pequenas partes;
- Comparar cada parte com as imagens contidas no banco de imagens;
- Montar uma imagem final com as imagens mais compatíveis às partes correspondentes na imagem principal.
O banco de imagens utilizado possui 1223 imagens de mesmas dimensões, desse modo, ao serem lidas e redimensionadas pelo programa de maneira padronizada, não perdem suas proporções. A função principal de comparação das imagens foi implementada utilizando análises de histograma.
Para cada parte da imagem principal, as seguintes operações são realizadas:
- É calculado o histograma de cada banda ("b","g" e "r") da parte considerada:
hist1_b = cv2.calcHist([img],[0],None,[256],[0,256])
hist1_g = cv2.calcHist([img],[1],None,[256],[0,256])
hist1_r = cv2.calcHist([img],[2],None,[256],[0,256])
- O banco de imagens é percorrido imagem a imagem realizando as devidas comparações.
Para cada comparação:
- É verificado se a imagem já foi utilizada e quantas vezes (para controle de repetição de imagens).
- São calculados os histogramas das bandas "b", "g" e "r" .
hist2_b = cv2.calcHist([imagens[i]],[0],None,[256],[0,256])
hist2_g = cv2.calcHist([imagens[i]],[1],None,[256],[0,256])
hist2_r = cv2.calcHist([imagens[i]],[2],None,[256],[0,256])
- Os histogramas da parte da imagem principal e de cada imagem do banco são comparados de acordo com a banda. Essa comparação é realizada por meio da operação "compareHist" e o método da comparação pode um dos quatro: CV_COMP_CORREL, CV_COMP_CHISQR, CV_COMP_INTERSECT, CV_COMP_BHATTACHARYYA.
comp_b = cv2.compareHist(hist1_b, hist2_b, metodo)
comp_g = cv2.compareHist(hist1_g, hist2_g, metodo)
comp_r = cv2.compareHist(hist1_r, hist2_r, metodo)
O valor final de comparação foi composto de duas formas diferentes para os testes: soma das três comparações e menor valor entre os três.
comp = comp_b+comp_g+comp_r ou comp = min(comp_b,comp_g,comp_r)
As variáveis avaliadas durantes os testes foram: tamanho das partes da imagem principal a serem comparadas (grande, médio e pequeno), número de repetições de cada imagem do banco (variando entre 1 e 300, dependendo do teste), método de comparação de histograma (CV_COMP_CORREL, CV_COMP_CHISQR, CV_COMP_INTERSECT, CV_COMP_BHATTACHARYYA.) e modelo de análise dos resultados das comparações (soma dos três ou mínimo).
A imagem utilizada para os testes foi a seguinte:
Teste 1 - Tamanho das partes: Grande (sem repetição das imagens do banco)
As imagens a seguir descrevem o resultado do algoritmo testado selecionando partes de tamanho 45px por 30px.
Método BHATTACHARYYA
 |
| Retorno do Valor Mínimo |
 |
| Retorno da Soma |
Método CHISQR
 |
| Retorno do Valor Mínimo |
 |
| Retorno da Soma |
Método CORREL (correlação)
 |
| Retorno do Valor Mínimo |
 |
| Retorno da Soma |
Método INTERSEC
 |
| Retorno do Valor Mínimo |
 |
| Retorno da Soma |
Observou-se que os métodos CV_COMP_CORREL e CV_COMP_INTERSECT oferecem os melhores resultados e os testes seguintes foram realizados através deles.
Teste 2 - Tamanho das partes: Grande (com até 10 e 50 repetições)
Os métodos escolhidos foram testados novamente com a possibilidade de cada imagem do banco repetir 10 vezes. Os resultados obtidos foram os seguintes:
Método CORREL (máximo 10 repetições)
 |
| Retorno do Valor Mínimo |
 |
| Retorno da Soma |
Método INTERSEC (máximo 10 repetições)
 |
| Retorno do Valor Mínimo |
 |
| Retorno da Soma |
Os métodos escolhidos foram testados novamente com a possibilidade de cada imagem do banco repetir 50 vezes. Os resultados obtidos foram os seguintes:
Método CORREL (máximo 50 repetições)
 |
| Retorno do Valor Mínimo |
 |
| Retorno da Soma |
Método INTERSEC (máximo 50 repetições)
 |
| Retorno do Valor Mínimo |
 |
| Retorno da Soma |
Realizaram-se testes com valores maiores de repetição, mas estes não apresentaram diferenças significativas.
Teste 3 - Tamanho das partes: Médio (com possibilidade de 3, 5, 10, 50, 100 e 200 repetições)
As imagens a seguir descrevem o resultado do algoritmo testado selecionando partes de tamanho 23px por 15px. Como o banco de imagens possui apenas 1223 imagens, foi preciso permitir no mínimo 3 repetições para alcançar um número suficiente de imagens para cobrir toda a imagem.
Método CORREL (máximo 3 repetições)
 |
| Retorno do Valor Mínimo |
 |
| Retorno da Soma |
Método INTERSEC (máximo 3 repetições)
 |
| Retorno do Valor Mínimo |
 |
| Retorno da Soma |
Método CORREL (máximo 5 repetições)
 |
| Retorno do Valor Mínimo |
 |
| Retorno da Soma |
Método INTERSEC (máximo 5 repetições)
 |
| Retorno do Valor Mínimo |
 |
| Retorno da Soma |
Método CORREL (máximo 10 repetições)
 |
| Retorno do Valor Mínimo |
 |
| Retorno da Soma |
Método INTERSEC (máximo 10 repetições)
 |
| Retorno do Valor Mínimo |
 |
| Retorno da Soma |
Método CORREL (máximo 50 repetições)
 |
| Retorno do Valor Mínimo |
 |
| Retorno da Soma |
Método INTERSEC (máximo 50 repetições)
 |
| Retorno do Valor Mínimo |
 |
| Retorno da Soma |
Método CORREL (máximo 100 repetições)
 |
| Retorno do Valor Mínimo |
 |
| Retorno da Soma |
Método INTERSEC (máximo 100 repetições)
 |
| Retorno do Valor Mínimo |
 |
| Retorno da Soma |
Método CORREL (máximo 200 repetições)
 |
| Retorno do Valor Mínimo |
 |
| Retorno da Soma |
Método INTERSEC (máximo 200 repetições)
 |
| Retorno do Valor Mínimo |
 |
| Retorno da Soma |
Realizaram-se outros testes com outros valores de repetição, mas os citados foram os que melhor exibem as diferenças entre eles.
Para a continuidade dos testes, foi elegida a estratégia de retorno da soma dos histogramas (das três bandas) como mais adequado.
Teste 4 - Tamanho das partes: Pequeno (com possibilidade de 6, 20, 100, 200 e 300 repetições)
As imagens a seguir descrevem o resultado do algoritmo testado selecionando partes de tamanho 14px por 10px. Como o banco de imagens possui apenas 1223 imagens, foi preciso permitir no mínimo 6 repetições para alcançar um número suficiente de imagens para cobrir toda a imagem.
Métodos CORREL e INTERSEC (máximo 6 repetições)
 |
| Método CORREL |
 |
| Método INTERSEC |
Métodos CORREL e INTERSEC (máximo 20 repetições)
 |
| Método CORREL |
 |
| Método INTERSEC |
Métodos CORREL e INTERSEC (máximo 100 repetições)
 |
| Método CORREL |
 |
| Método INTERSEC |
Métodos CORREL e INTERSEC (máximo 200 repetições)
 |
| Método CORREL |
 |
| Método INTERSEC |
Métodos CORREL e INTERSEC (máximo 300 repetições)
 |
| Método CORREL |
 |
| Método INTERSEC |
Esses foram os resultados obtidos por meio da imagem:
Segue o código completo utilizado:
import cv2
import numpy as np
def maiorCorrelacao(img,imagens,usadas,numero_imagens):
hist1_b = cv2.calcHist([img],[0],None,[256],[0,256])
hist1_g = cv2.calcHist([img],[1],None,[256],[0,256])
hist1_r = cv2.calcHist([img],[2],None,[256],[0,256])
valor_maior = -2
img_comp = []
pos_maior = 0
for i in range(numero_imagens):
metodo = cv2.cv.CV_COMP_INTERSECT
if usadas[i] < 300:
hist2_b = cv2.calcHist([imagens[i]],[0],None,[256],[0,256])
hist2_g = cv2.calcHist([imagens[i]],[1],None,[256],[0,256])
hist2_r = cv2.calcHist([imagens[i]],[2],None,[256],[0,256])
comp_b = cv2.compareHist(hist1_b, hist2_b, metodo)
comp_g = cv2.compareHist(hist1_g, hist2_g, metodo)
comp_r = cv2.compareHist(hist1_r, hist2_r, metodo)
comp = comp_b+comp_g+comp_r
if comp > valor_maior:
valor_maior = comp
img_comp = imagens[i]
pos_maior = i
return (img_comp,pos_maior)
def criarMosaico(imagem_principal_name):
imagem_principal = cv2.imread(imagem_principal_name,-1)
linhas,colunas,cores = np.shape(imagem_principal)
numero_imagens = 1223
imagens = []
ci = 10
li = 15
for i in range(numero_imagens):
nome = "banco_capas\\img ({0}).jpg".format(i)
imagens.append(cv2.imread(nome,-1))
imagens[i] = cv2.resize(imagens[i], (ci,li), interpolation = cv2.INTER_AREA)
usadas = np.zeros(numero_imagens)
mosaico = np.copy(imagem_principal)
c = 0
l = 0
while (l+li) <= linhas:
while (c+ci) <= colunas:
(parte,pos) = maiorCorrelacao(imagem_principal[l:(l+li):1,c:(c+ci):1,::],imagens,usadas,numero_imagens)
mosaico[l:(l+li):1,c:(c+ci):1,::] = parte
usadas[pos] += 1
c += ci
c = 0
l += li
return mosaico
mosaico = criarMosaico("p (6).jpg");
cv2.imshow("saida1",mosaico)
cv2.waitKey(0)
cv2.destroyAllWindows()
0 comentários:
Postar um comentário