8. Operações avançadas de processamento de imagem Opencv-python (5) - detecção de bordas

  • A detecção de bordas é frequentemente considerada um tópico de mestrado ou uma pergunta de entrevista de empresa, por isso é muito importante.Neste capítulo, serão apresentados vários operadores comuns de detecção de bordas.

meta de aprendizagem

Compreenda o operador Sobel, o operador Scharr e o operador Laplaciano

Domine os princípios e aplicações da detecção inteligente de bordas

1. Princípio da detecção de bordas

A detecção de bordas é um problema fundamental no processamento de imagens e na visão computacional, e seu objetivo é representar pontos em imagens digitais com mudanças óbvias de brilho. Mudanças significativas nos atributos da imagem geralmente refletem eventos e mudanças importantes nos atributos. A expressão da detecção de bordas é mostrada na figura abaixo:
Insira a descrição da imagem aqui
A detecção de bordas da imagem reduz bastante a quantidade de dados, remove informações que podem ser consideradas irrelevantes e retém atributos estruturais importantes da imagem. Existem muitos métodos para detecção de bordas, a maioria dos quais pode ser dividida em duas categorias: baseada em pesquisa e baseada em cruzamento zero.

1. Com base na pesquisa

O limite é detectado encontrando o valor máximo na primeira derivada da imagem e, em seguida, usando os resultados do cálculo para estimar a direção local da borda. Normalmente, a direção do gradiente é usada, e esta direção é usada para encontrar o máximo valor do módulo de gradiente local.Algoritmos representativos incluem o operador Sobel e o operador Scharr.

(1) O valor máximo da primeira derivada da imagem -->
.
(2) A direção local da borda (direção geral do gradiente) -->
.
(3) O valor máximo do módulo de gradiente local

Insira a descrição da imagem aqui

2. Com base no cruzamento zero

O limite é encontrado procurando o cruzamento zero da segunda derivada da imagem, e o operador representativo é o operador laplaciano.
O ponto zero é a intersecção da função e do eixo y.
Insira a descrição da imagem aqui

2. Operador de detecção Sobel

O algoritmo de detecção de bordas Sobel é relativamente simples e mais eficiente do que a detecção inteligente de bordas em aplicações práticas . No entanto, a borda não é tão precisa quanto a detecção inteligente, mas em muitas aplicações práticas, o operador Sobel é a primeira escolha.
O operador Sobel é uma combinação de suavização gaussiana e operações diferenciais, portanto possui forte resistência ao ruído e muitos usos . Especialmente quando os requisitos de eficiência são altos e você não se importa muito com texturas detalhadas.

1. Discussão de princípios e métodos

Para funções descontínuas, a primeira derivada pode ser escrita como:
Insira a descrição da imagem aqui
ou
Insira a descrição da imagem aqui
Então existe:
Insira a descrição da imagem aqui
Suponha que a imagem a ser processada seja I, e a derivada seja obtida em duas direções

  • Mudança horizontal: Convolve a imagem I com um modelo de tamanho de período e o resultado é Gx. Por exemplo, quando o tamanho do modelo é 3, Gx é:
    Insira a descrição da imagem aqui
  • Variação vertical: Convolve a imagem I com um gabarito de tamanho técnico, o resultado é Gy. Por exemplo, quando o tamanho do modelo é 3, Gy é:
    Insira a descrição da imagem aqui
    Em cada ponto da imagem, combinado com os dois resultados acima,
    Insira a descrição da imagem aqui
    a posição do valor máximo estatístico é a borda da imagem.
    **Nota:** Quando o tamanho do kernel é 3, o kernel Sobel acima pode produzir erros óbvios. Para resolver este problema, usamos a função Scharr, mas esta função só funciona em kernels com tamanho 3. Esta função opera tão rápido quanto a função de Sobel, mas os resultados são mais precisos. É calculada como:
    Insira a descrição da imagem aqui

2. Aplicação

A API para detecção de bordas Sobel usando OpenCV é:

Sobel_x_or_y = 
cv2.Sobel(src, ddepth, dx, dy, dst, ksize, scale, delta, borderType)

parâmetro:

  • src: a imagem recebida
  • dprofundidade: a profundidade da imagem
  • dx e dy: referem-se à ordem de derivação, 0 significa que não há derivação nesta direção e os valores são 0 e 1.
  • ksize: é o tamanho do operador Sobel, ou seja, o tamanho do kernel de convolução. Deve ser um número ímpar de 1, 3, 5 ou 7, e o padrão é 3.
  • Nota: Se ksize=-1, ele evolui para um operador Scharr 3x3.
  • escala: A constante proporcional da derivada de escala, o padrão é nenhum coeficiente de escala.
  • borderType: O modo da borda da imagem, o valor padrão é cv2.BORDER_DEFAULT.

Após a função Sobel calcular a derivada, haverá valores negativos e valores maiores que 255. A imagem original é uint8, ou seja, 8 é um número sem sinal, portanto a imagem criada por Sobel não possui dígitos suficientes e ficará truncada. Portanto, use o tipo de dados assinados de 16 bits, cv2.CV_16s. Após processar a imagem, use a função cv2.convertScaleAbs() para convertê-la de volta ao tipo uint8 original, caso contrário a imagem não poderá ser exibida.

O operador Sobel é calculado em duas direções e finalmente precisa ser combinado usando a função cv2.addWeighted()

Scale_abs = cv2.convertScaleAbs(x)  # 格式转换函数
result = cv2.addWeighted(src1, alpha, src2, beta) # 图像混合

Exemplo de código:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
# 1 读取图像
img = cv.imread('./image/horse.jpg',0)
# 2 计算Sobel卷积结果
x = cv.Sobel(img, cv.CV_16S, 1, 0)
y = cv.Sobel(img, cv.CV_16S, 0, 1)
# 3 将数据进行转换
Scale_absX = cv.convertScaleAbs(x)  # convert 转换  scale 缩放
Scale_absY = cv.convertScaleAbs(y)
# 4 结果合成
result = cv.addWeighted(Scale_absX, 0.5, Scale_absY, 0.5, 0)
# 5 图像显示
plt.figure(figsize=(10,8),dpi=100)
plt.subplot(121),plt.imshow(img,cmap=plt.cm.gray),plt.title('原图')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(result,cmap = plt.cm.gray),plt.title('Sobel滤波后结果')
plt.xticks([]), plt.yticks([])
plt.show()

Insira a descrição da imagem aqui
Defina o ksize da parte de cálculo do operador Sobel no código acima como -1, que usa Scharr para detecção de borda.

x = cv2.Sobel(img, cv2.CV_16S, 1, 0, ksize=-1)
y = cv2.Sobel(img, cv2.CV_16S, 0, 1, ksize=-1)

Insira a descrição da imagem aqui

Pode-se observar que usando o operador Scharr, o efeito de detecção é ligeiramente melhor que o operador Sobel.

3. Operador Laplaciano

O método de detecção Laplaciano usa derivadas de segunda ordem para detectar arestas. Como a imagem é "bidimensional", precisamos derivar a derivada em duas direções, conforme mostrado na seguinte fórmula:
Insira a descrição da imagem aqui
Então a derivada descontínua de segunda ordem é:
Insira a descrição da imagem aqui
Então o núcleo de convolução usado é:
Insira a descrição da imagem aqui
API:

laplacian = cv2.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])

parâmetro:

  • Fonte: imagem
  • Dprofundidade: Profundidade da imagem, -1 significa que a mesma profundidade da imagem original é usada e a profundidade da imagem alvo deve ser maior ou igual à profundidade da imagem original;
  • ksize: O tamanho do operador, ou seja, o tamanho do kernel de convolução, deve ser 1, 3, 5, 7

Exemplo de código:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
# 1 读取图像
img = cv.imread('./image/horse.jpg',0)
# 2 laplacian转换
result = cv.Laplacian(img,cv.CV_16S)
Scale_abs = cv.convertScaleAbs(result)
# 3 图像展示
plt.figure(figsize=(10,8),dpi=100)
plt.subplot(121),plt.imshow(img,cmap=plt.cm.gray),plt.title('原图')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(Scale_abs,cmap = plt.cm.gray),plt.title('Laplacian检测后结果')
plt.xticks([]), plt.yticks([])
plt.show()

Insira a descrição da imagem aqui

4. Detecção de borda astuta

O algoritmo de detecção de bordas astuto é um algoritmo de detecção de bordas muito popular. Foi proposto por John F. Canny em 1986 e é considerado o melhor algoritmo de detecção de bordas.

1. Princípio do algoritmo Canny

O algoritmo de detecção de bordas Canny consiste em 4 etapas, que são apresentadas a seguir:

  • remoção de ruído

Como a detecção de bordas sofre facilmente interferência do ruído, um filtro gaussiano é usado primeiro para remover o ruído. (A filtragem gaussiana é mencionada em Suavização de imagem, você pode ler adiante)

  • Calcular gradiente de imagem

Use o operador Sobel para calcular as primeiras derivadas (Gx e Gy) nas direções horizontal e vertical da imagem suavizada . Encontre o gradiente e a direção do limite com base nos dois mapas de gradiente obtidos (Gx e Gy) A fórmula é a seguinte:
Insira a descrição da imagem aqui
Se um pixel é uma aresta, sua direção de gradiente é sempre perpendicular à direção da aresta. As direções do gradiente são classificadas em quatro categorias: vertical, horizontal e duas direções diagonais.

  • supressão não máxima

Depois de obter a direção e a magnitude do gradiente, escaneie toda a imagem para remover pontos que não estão no limite. Verifique cada pixel para ver se o gradiente deste ponto é o maior entre os pontos circundantes com a mesma direção do gradiente. Como mostrado na figura abaixo:
Insira a descrição da imagem aqui
O ponto A está localizado na borda da imagem. Na direção de sua mudança de gradiente, selecione os pontos de pixel B e C para verificar se o gradiente do ponto A é um valor máximo. Se for um valor máximo valor, mantenha-o, caso contrário, os pontos A serão suprimidos e o resultado final será uma imagem binária com "bordas finas".

  • limite de histerese

Agora vem a determinação dos verdadeiros limites. Definimos dois limites: minVal e maxVal. Quando o gradiente de cinza da imagem é maior que maxVal, ele é considerado um limite verdadeiro e o limite abaixo de minVal será descartado. Se estiver entre os dois, depende se o ponto está conectado a um determinado ponto limite determinado como um ponto limite real. Nesse caso, é considerado um ponto limite. Caso contrário, é descartado. Como mostrado na figura abaixo:
Insira a descrição da imagem aqui
Como mostrado na figura acima, A é maior que o limite maxVal, então é um ponto limite real. Embora C seja menor que maxVal, ele é maior que minVal e está conectado a A, então é também é considerado um ponto limite real. E B será descartado porque é inferior a maxVal e não está conectado ao ponto limite real. Portanto, escolher maxVal e minVal apropriados é muito importante para obter bons resultados.

2. Aplicação

API usada para implementar detecção inteligente na medicina chinesa opencv:

canny = cv2.Canny(image, threshold1, threshold2)

parâmetro:

  • imagem: imagem em tons de cinza,
  • limite1: minval, um limite menor conecta bordas descontínuas
  • limite2: maxval, um limite maior para detectar bordas óbvias na imagem
    . Exemplo de código:
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
# 1 图像读取
img = cv.imread('./image/horse.jpg',0)
# 2 Canny边缘检测
lowThreshold = 0
max_lowThreshold = 100
canny = cv.Canny(img, lowThreshold, max_lowThreshold) 
# 3 图像展示
plt.figure(figsize=(10,8),dpi=100)
plt.subplot(121),plt.imshow(img,cmap=plt.cm.gray),plt.title('原图')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(canny,cmap = plt.cm.gray),plt.title('Canny检测后结果')
plt.xticks([]), plt.yticks([])
plt.show()

Insira a descrição da imagem aqui

Resumir:

1. Princípio da detecção de bordas

(1) Com base na pesquisa

(2) Com base no cruzamento zero

2. Operador Sobel [aplicação prática]

(1) Obtenha o limite com base no método de pesquisa

(2)cv2.Sobel()

(3)cv2.convertScaleAbs()

(4)cv2.addWeighted()

3. Operador Laplaciano

(1) Obtenha o limite com base no cruzamento zero

(2)cv2.Laplaciano()

4. Algoritmo astuto

(1) Remoção de ruído (filtragem gaussiana)

(2) Calcular gradiente de imagem (operador Sobel)

(3) Supressão não máxima: Determine se o pixel é um ponto limite

(4) Limite de histerese: Defina dois limites para determinar o limite final

5. Comparação entre vários operadores tradicionais

Insira a descrição da imagem aqui

  • O caminho para se tornar mais forte é longo e árduo, então vamos lá! ! !

Acho que você gosta

Origin blog.csdn.net/weixin_44463519/article/details/126095174
Recomendado
Clasificación