Pergunta

Calculei o histograma (uma matriz 1D simples) para uma imagem em escala de cinza 3D. Agora eu gostaria de calcular o gradiente para este histograma em cada ponto. Portanto, isso significaria que eu tenho que calcular o gradiente para uma função 1D em determinados pontos. No entanto, eu não tenho uma função. Então, como posso calculá -lo com valores de concreto x e y?

Por uma questão de simplicidade, você provavelmente poderia me explicar isso em um exemplo de histograma - por exemplo, com os seguintes valores (x é a intensidade e a frequência dessa intensidade):

x1 = 1; y1 = 3

x2 = 2; y2 = 6

x3 = 3; y3 = 8

x4 = 4; y4 = 5

x5 = 5; y5 = 9

x6 = 6; y6 = 12

x7 = 7; y7 = 5

x8 = 8; y8 = 3

x9 = 9; y9 = 5

x10 = 10; y10 = 2

Sei que isso também é um problema de matemática, mas como preciso resolvê -lo em C ++ I, você pode me ajudar aqui.

Obrigado pelo seu conselho Marc

Foi útil?

Solução

Eu acho que você pode calcular seu gradiente usando a mesma abordagem usada na detecção de borda de imagem (que é um cálculo de gradiente). Se o seu histograma estiver em um vetor, você poderá calcular uma aproximação do gradiente como*:

for each point in the histogram compute 
     gradient[x] = (hist[x+1] - hist[x])

Essa é uma maneira muito simples de fazê -lo, mas não tenho certeza se é a mais precisa.

  • aproximação porque você está trabalhando com dados discretos em vez de contínuo

Editado:

Outros operadores podem enfatizar pequenas diferenças (pequenos gradientes se tornarão mais enfatizados). O algoritmo Roberts deriva do cálculo derivado:

lim delta -> 0 = f(x + delta) - f(x) / delta

O Delta tende infinitamente a 0 (para evitar a divisão 0), mas nunca é zero. Como na memória do computador, isso é impossível, o menor que podemos obter do delta é 1 (porque 1 é a menor distância de pontos em uma imagem (ou histograma)).

Substituindo

lim delta -> 0 to lim delta -> 1

Nós temos

f(x + 1) - f(x) / 1 = f(x + 1) - f(x) => vet[x+1] - vet[x]

Outras dicas

Dois geralmente se aproximam aqui:

  1. uma aproximação discreta à derivada
  2. Pegue a verdadeira derivada de uma função ajustada

No Primeiro caso tentar:

g = (y_(i+1) - y_(i-1))/2*dx

em todos os pontos, exceto os fins, ou um dos

g_left-end  = (y_(i+1) - y_i)/dx
g_right-end = (y_i - y_(i-1))/dx

Onde dx é o espaçamento entre x pontos. (Ao contrário da definição igualmente correta Andres sugeriu, este é simétrico. Se isso importa ou não, depende de você usar o caso.)

No Segundo caso, ajuste a spline para seus dados [*] e pergunte à biblioteca spline a derivada no ponto que você deseja.

*] Use uma biblioteca! Não implemente isso você mesmo, a menos que este seja um projeto de aprendizado. Eu usaria RAIZ Porque eu já tenho na minha máquina, mas é um pacote bastante pesado apenas para obter uma spline ...


Finalmente, se você estiver barulhento, você deseja suavizá -los antes de fazer a detecção de inclinação. Isso foi evitar perseguir o barulho e só olha para encostas em larga escala.

  1. Pegue um pouco de papel quadrado e desenhe seu histograma. Desenhe também eixos verticais e horizontais através do ponto 0,0 do seu histograma.

  2. Pegue uma borda reta e, a cada ponto em que você está interessado, gire a borda reta até que ela concorra à sua idéia do que é o gradiente nesse ponto. É mais importante que você faça isso, sua definição de gradiente é a que você deseja.

  3. Uma vez que a borda reta estiver no ângulo que você deseja desenhar uma linha nesse ângulo.

  4. Drop perpendiculares de 2 pontos na linha que você acabou de desenhar. Será mais fácil dar a seguinte etapa se a distância horizontal entre os 2 pontos escolhidos for de cerca de 25% ou mais da largura do seu histograma. A partir dos mesmos 2 pontos, desenham linhas horizontais para cruzar o eixo vertical do seu histograma.

  5. Suas linhas agora definem uma distância x e uma distância y, ou seja, o comprimento dos eixos horizontais/ verticais (respectivamente) marcados por suas interseções com as linhas perpendiculares/ horizontais. O gradiente que você deseja é a distância Y dividida pela distância x.

Agora, para traduzir isso em código é muito direto, além da etapa 2. Você deve definir quais são os critérios para determinar o que é o gradiente em qualquer ponto do histograma. As opções simples incluem:

a) Em cada ponto, defina sua borda reta para passar pelo ponto e a próxima à sua direita;

b) Em cada ponto, defina sua borda reta para passar pelo ponto e a próxima à esquerda;

c) Em cada ponto, defina sua borda reta para passar pelo ponto à esquerda e o ponto para a direita.

Você pode investigar opções mais complexas, como ajustar uma curva (como um polinômio quadrático ou de ordem superior) através de vários pontos no seu histograma e usando o derivado disso para representar o gradiente.

Até você entender a pergunta no papel, evite codificar em C ++ ou qualquer outra coisa. Depois de entender, a codificação deve ser trivial.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top