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,

mchlfchr
fonte
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);
Brandon Jackson
fonte