¿Cómo se almacenan los píxeles de trama por sus valores?

28

Los píxeles a la izquierda representan las ubicaciones de los árboles y sus radios de corona asociados (es decir, los valores de píxeles que van de 2 a 5). Me gustaría almacenar estos píxeles ráster por su valor de radio de corona. La imagen de la derecha es lo que espero lograr utilizando solo métodos de procesamiento de ráster .

Inicialmente, pensaría utilizar una suma focal circular en ArcGIS, aunque la configuración de vecindad es un valor fijo, que no tomaría en cuenta el radio de la corona de tamaño variable.

¿Cuál es un buen método para "amortiguar" los píxeles por sus valores?

    
pregunta Aaron 10.02.2014 - 17:06

6 respuestas

14

Aquí hay una solución raster pura en Python 2.7 usando numpy y scipy :

import numpy as np
from scipy import ndimage
import matplotlib.pyplot as plt

#create tree location matrix with values indicating crown radius
A = np.zeros((120,320))
A[60,40] = 1
A[60,80] = 2
A[60,120] = 3
A[60,160] = 4
A[60,200] = 5
A[60,240] = 6
A[60,280] = 7

#plot tree locations
fig = plt.figure()
plt.imshow(A, interpolation='none')
plt.colorbar()

#find unique values
unique_vals = np.unique(A)
unique_vals = unique_vals[unique_vals > 0]

# create circular kernel
def createKernel(radius):
    kernel = np.zeros((2*radius+1, 2*radius+1))
    y,x = np.ogrid[-radius:radius+1, -radius:radius+1]
    mask = x**2 + y**2 <= radius**2
    kernel[mask] = 1
    return kernel

#apply binary dilation sequentially to each unique crown radius value 
C = np.zeros(A.shape).astype(bool)   
for k, radius in enumerate(unique_vals):  
    B = ndimage.morphology.binary_dilation(A == unique_vals[k], structure=createKernel(radius))
    C = C | B #combine masks

#plot resulting mask   
fig = plt.figure()
plt.imshow(C, interpolation='none')
plt.show()

Entrada:

Salida:

    
respondido por el jatobat 12.02.2014 - 18:06
8

Enfoque basado en vectores

Esta tarea se puede realizar en tres pasos:

Nota: el uso del campo del búfer evita el cálculo de un búfer para cada valor del radio de la corona.

Enfoque basado en ráster

Al evitar la solución basada en vectores, este problema sugiere utilizar un tipo de Autómatas celulares Basado en los vecinos más cercanos. Suponiendo que todos los píxeles negros son ceros, los píxeles son cuadrados y su tamaño es igual a 1 (o, alternativamente, se escalan oportunamente), las reglas a adoptar son muy simples:

  1. Si el valor de píxel ( VALUE ) es mayor que 1, su valor se convierte en VALUE-1 y luego considera los píxeles que lo rodean. Si sus valores son menores que VALUE-1 , estos píxeles born o grow y su valor se convierte en VALUE-1 . De lo contrario, estos píxeles sobreviven y no se modifican.
  2. Si VALUE<=1 , no haga nada (¡el píxel está muerto!).

Estas reglas deben aplicarse hasta que todos los píxeles estén muertos, es decir, sus valores son iguales a 0 o 1. Entonces N-1 veces, donde N es el valor máximo que tiene en el ráster de entrada. Este enfoque se puede implementar fácilmente con un poco de Python y numpy.

    
respondido por el Antonio Falciano 10.02.2014 - 19:32
7

Otra opción sería crear rásteres separados para cada valor de píxel, en este caso 4 rásteres, con una condición. Luego expanda los rásteres en un recuento de píxeles correspondiente al valor del ráster (posiblemente iterando sobre una lista de valores). Por último, une los rásteres (algebraicos o espaciales) para crear un ráster binario para las coronas de los árboles.

    
respondido por el HDunn 10.02.2014 - 20:45
7

Es una pregunta difícil hacer esto en raster porque no tienes la oportunidad de usar el valor del píxel para definir el tamaño del búfer. Por lo tanto, tendría que hacer el filtro focal para cada valor, como ya dijo.

Aquí hay una posible respuesta para hacerlo con solo 3 filtros (no pude encontrar menos), pero no perfectamente como lo mencionó Whuber: sus búferes se truncarán cuando los árboles estén cerca unos de otros.

1) EDITAR: asignación euclidiana (esto no resuelve completamente el problema, ya que corta los búferes cerca de árboles más pequeños, pero es mejor que los artefactos de mi primera solución).

2) distancia de euclidian alrededor de cada píxel

3) calculadora ráster (álgebra de mapas) con una declaración condicional

Con("allocation_result" > ("distance_result" / pixel_size) , 1 , 0)

Tenga en cuenta que puede ajustar la condición según sus necesidades en términos de radio (con o sin el píxel central)

    
respondido por el radouxju 10.02.2014 - 20:00
2

Me pregunto por qué no usa expandir de ArcGIS.

import arcpy
from arcpy.sa import *

raster_in  = r'c:\test.tif'
raster_out = r'c:\test_out.tif'

outExpand1 = Expand(raster_in, 2, 2)
outExpand2 = Expand(outExpand1, 3, 3)
outExpand3 = Expand(outExpand3, 4, 4)
outExpand4 = Expand(outExpand4, 5, 5)

outExpand4.save(raster_out)

En caso de superposición: el último comando expand cubrirá los anteriores.

    
respondido por el Mr. Che 10.03.2015 - 08:33
2

Si tiene la posición de píxel, el radio y el algoritmo de círculo de punto medio (una variante de Bresenham Alg.) te da una pista En mi opinión, es fácil crear un polígono desde este enfoque y creo que es fácil implementarlo en Python. Una unión de este conjunto de polígonos te da el área de cobertura.

    
respondido por el huckfinn 10.02.2014 - 21:54

Lea otras preguntas en las etiquetas