Alguém sabe por que o MatLab Canny (MLC) é tão diferente em comparação com o OpenCV Canny (OCC)? O ML-C oferece arestas precisas e mais conectadas que o OCC, mas como isso é possível? A razão pela qual pergunto é que preciso implementar meu protótipo de código ML no C ++ e que queria usar o OpenCV. Exportar código de ML não é realmente possível, tanto quanto eu tentei.
Atenciosamente,
image-processing
matlab
opencv
edge-detection
mchlfchr
fonte
fonte
edit edge
Matlab e ver o caso relevante. É tudo de código aberto - nenhum built-in até onde eu sei.Respostas:
Como sugerido acima, o detector de borda Matlab Canny calcula o gradiente usando uma "derivada de um filtro Gaussiano" (conforme declarado na documentação). Em outras palavras, o Matlab faz um desfoque gaussiano da imagem e encontra o gradiente dessa imagem suavizada ... tudo usando um único filtro sofisticado. [Se você quiser conhecer os detalhes, basta digitar
edit edge
como Andrey sugeriu e, em seguida, role para baixo até asmoothGradient()
função.]A operação de desfoque reduz significativamente a quantidade de ruído presente na imagem, eliminando muitas bordas falsas e deixando para trás as coisas boas.
Infelizmente, a função OpenCV Canny não permite alterar o kernel de filtro usado pelos parâmetros de função. Contudo. Você pode gerar os mesmos resultados primeiro desfocando a imagem de entrada e passando essa imagem desfocada para a função Canny.
Isso limpa significativamente o mapa de arestas resultante. Para desfocar a imagem de entrada, eu pessoalmente uso a
GaussianBlur()
função do OpenCV comsigmaX=2
. Isso imita o sigma padrão no Matlab. O melhor tamanho de kernel de desfoque pode variar de caso para caso, mas no Matlab é calculado usandofilterLength = 8*ceil(sigma);
, portanto, para um sigma de 2, isso significaria um tamanho de kernel de(16,16)
Como os filtros Gaussian Blur e Sobel são lineares, passar uma imagem de entrada borrada para a
Canny()
função OpenCV é matematicamente equivalente ao que o Matlab faz por causa do princípio de superposição, conforme demonstrado neste pseudocódigo (nota:*
é o operador de convolução):Há um tutorial do OpenCV Canny aqui que demonstra como fazer isso usando C ++. Eu sou um cara python, então aqui está o que eu faço:
fonte