Diferenças entre o OpenCV Canny e o MatLab Canny?


8

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,


3
Você verificou os limites e outras configurações de parâmetros? Se você não os fornecer, eles são escolhidos automaticamente e a estratégia pode variar.
— 22612 Andrey Rubshtein

Hey Andrey, eu sei que eles são fornecidos automaticamente se você não os definir. Eu verifiquei os limites e os variei, mas os resultados não são da mesma qualidade que os resultados de ML em nenhuma combinação.
— Mchlfchr 19/10/12

Tanto quanto eu sei que o OpenCV está usando Sobel para os gradientes. Talvez ML esteja usando uma aproximação de Gauss para os gradientes, porque modela as propriedades das arestas de uma maneira melhor? regards,
— mchlfchr

Você pode digitar edit edgeMatlab e ver o caso relevante. É tudo de código aberto - nenhum built-in até onde eu sei.
— 22612 Andrey Rubshtein

Sim, eu sei, mas para algumas rotinas (como o cálculo do gradiente) você não pode ir mais fundo. E a rotina do Canny é muito longa, então pensei que alguém aqui já tivesse feito essa experiência. ;) Então, eu estava errado, porque ninguém me deu uma resposta sobre isso.
— Mchlfchr 23/10/12

Respostas:


11

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 edgecomo Andrey sugeriu e, em seguida, role para baixo até a smoothGradient()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 com sigmaX=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 usando filterLength = 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):

// The Matlab method: the sobel and blur operations are combined into
// a single filter, and that filter is then convolved with the image
matlabFancyFilter = (sobel * blur);
gradient = matlabFancyFilter * image;

// Equivalent method: image is first convolved with the blur filter, and
// then convolved with the sobel filter.
gradient = sobel * (blur * image); // image is filtered twice

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:

smoothedInput = cv2.GaussianBlur(image, (7,7), 2);
edges = cv2.Canny(smoothedInput, 25, 50);
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.