Desculpe, eu não conheço o OpenCV, e esta é mais uma etapa de pré-processamento do que uma resposta completa:
Primeiro, você não quer um detector de borda. Um detector de borda converte transições (como esta do escuro para a luz):
em cristas (linhas brilhantes no escuro) assim:
Ele realiza uma diferenciação, em outras palavras.
Mas nas suas imagens, há uma luz brilhando em uma direção, o que nos mostra o relevo da superfície 3D. Percebemos isso como linhas e arestas, porque estamos acostumados a ver coisas em 3D, mas elas não estão realmente, e é por isso que os detectores de bordas não estão funcionando, e a correspondência de modelos não funciona facilmente com imagens rotacionadas (um perfeito a correspondência a 0 graus de rotação cancelaria completamente a 180 graus, porque claro e escuro se alinhavam).
Se a altura de uma dessas linhas confusas se parecer com esta do lado:
então a função de brilho quando iluminada de um lado ficará assim:
É isso que você vê nas suas imagens. A superfície oposta fica mais brilhante e a superfície posterior fica mais escura. Então você não quer se diferenciar. Você precisa integrar a imagem na direção da iluminação, e ela fornecerá o mapa de altura original da superfície (aproximadamente). Então será mais fácil combinar as coisas, seja por meio da transformação de Hough, da correspondência de modelos ou qualquer outra coisa.
Não sei como automatizar a localização da direção da iluminação. Se é o mesmo para todas as suas imagens, ótimo. Caso contrário, você teria que encontrar a maior linha de contraste e assumir que a luz é perpendicular a ela ou algo assim. No meu exemplo, eu girei a imagem manualmente para o que eu achava que era a direção certa, com a luz vindo da esquerda:
Você também precisa remover todas as alterações de baixa frequência na imagem, para destacar apenas os recursos semelhantes a linhas que mudam rapidamente. Para evitar tocar artefatos, usei o desfoque Gaussiano 2D e subtraí o do original:
A integração (soma acumulada) pode sair facilmente, o que produz riscos horizontais. Eu os removi com outro passe alto gaussiano, mas apenas na direção horizontal desta vez:
Agora, os estômatos são elipses brancos a toda a volta, em vez de brancos em alguns lugares e pretos em outros.
Original:
Integrado:
from pylab import *
import Image
from scipy.ndimage import gaussian_filter, gaussian_filter1d
filename = 'rotated_sample.jpg'
I = Image.open(filename).convert('L')
I = asarray(I)
# Remove DC offset
I = I - average(I)
close('all')
figure()
imshow(I)
gray()
show()
title('Original')
# Remove slowly-varying features
sigma_2d = 2
I = I - gaussian_filter(I, sigma_2d)
figure()
imshow(I)
title('2D filtered with %s' % sigma_2d)
# Integrate
summed = cumsum(I, 1)
# Remove slowly-changing streaks in horizontal direction
sigma_1d = 5
output = summed - gaussian_filter1d(summed, sigma_1d, axis=1)
figure()
imshow(output)
title('1D filtered with %s' % sigma_1d)
A transformação Hough pode ser usada para detectar elipses de cume como este, feitos de "pixels de borda", embora seja muito caro em computação e memória, e não sejam elipses perfeitas, portanto seria um detector "desleixado". Eu nunca fiz isso, mas existem muitos resultados do Google para " detecção de elipse de hough ". Eu diria que se você detectar uma elipse dentro da outra, dentro de um determinado tamanho de espaço de pesquisa, ela deve ser contada como um estoma.
Veja também: