วิธีการบัฟเฟอร์พิกเซลแรสเตอร์ตามค่าของพวกเขา?


28

พิกเซลทางด้านซ้ายแสดงตำแหน่งต้นไม้และรัศมีรูปมงกุฎที่เกี่ยวข้อง (เช่นค่าพิกเซลอยู่ระหว่าง 2 - 5) ฉันต้องการบัฟเฟอร์พิกเซลแรสเตอร์เหล่านี้ด้วยค่ารัศมีมงกุฎของพวกเขา ภาพไปทางขวาเป็นสิ่งที่ผมหวังที่จะประสบความสำเร็จโดยใช้วิธีการประมวลผลเพียงแรสเตอร์

ตอนแรกฉันคิดว่าจะใช้ผลรวมโฟกัสแบบวงกลมใน ArcGIS แม้ว่าการตั้งค่าพื้นที่ใกล้เคียงเป็นค่าคงที่ซึ่งไม่คำนึงถึงรัศมีมงกุฎขนาดตัวแปร

วิธีที่ดีในการ "บัฟเฟอร์" พิกเซลโดยค่าของพวกเขาคืออะไร?

ป้อนคำอธิบายรูปภาพที่นี่


2
คุณพยายามแปลงแรสเตอร์เป็นจุดแล้วบัฟเฟอร์ตามฟิลด์จากนั้นแปลงกลับเป็นแรสเตอร์?

2
มันจะช่วยให้รู้ว่านี่เป็นท้องถิ่นที่ไม่ใช่การดำเนินการเพราะนั่นไม่ใช่ท้องที่แสดงให้เห็นว่ามีข้อ จำกัด โดยธรรมชาติเกี่ยวกับวิธีการคำนวณสามารถดำเนินการได้ ตัวอย่างเช่นเอาต์พุตของคุณจะเปลี่ยนไปอย่างรุนแรงเกือบทุกที่ถ้าเพียงพิกเซลแยกเดี่ยวในอินพุตจะเปลี่ยนเป็นค่ามาก ดังนั้นหากคุณทราบข้อ จำกัด เกี่ยวกับค่าอินพุตโปรดแบ่งปันให้กับพวกเขาเพราะนั่นอาจนำไปสู่การปรับปรุงแก้ไข ตัวอย่างเช่นค่าอินพุตทั้งหมดของคุณจะอยู่ในชุด {2,3,4} เสมอหรือไม่
whuber

@ ด่านแพตเตอร์สันนั่นเป็นวิธีที่ฉันคิดรูปภาพขึ้นมาทางขวา อย่างไรก็ตามฉันพยายามหลีกเลี่ยงการดำเนินการเวกเตอร์ทั้งหมดและหลีกเลี่ยงขั้นตอนเหล่านั้น
แอรอน

2
@whuber ชุดข้อมูลนี้แสดงให้เห็นถึงต้นไม้ที่มีขนาดเส้นผ่าศูนย์กลางมงกุฎตัวแปร ระบุว่าการวัดรัศมีมงกุฎของต้นไม้สามารถเปลี่ยนแปลงได้ตั้งแต่ 1-10 ฉันควรเพิ่มว่าบัฟเฟอร์เอาต์พุตต้องเป็น 0 เท่านั้นสำหรับการขาดมงกุฎและ 1 สำหรับสถานะมงกุฎ
แอรอน

1
โอเคขอบคุณ. ดูเหมือนว่าคุณสร้างผลลัพธ์ตัวอย่างโดยการรวม 3 บัฟเฟอร์ของจุดที่มีค่า 3, 4 บัฟเฟอร์ของจุดที่มีค่า 4 และ 5 บัฟเฟอร์ของคะแนนที่มีค่า 5 (ดูเหมือนว่าคุณจะลืมไปแล้ว ในการประมวลผลคะแนนด้วยค่า 2) กระบวนการนั้นไม่เพียง แต่ตอบคำถามของคุณ แต่ (ฉันเชื่อว่า) เป็นวิธีที่ง่ายที่สุดในการใช้เครื่องมือที่มีอยู่ใน Spatial Analyst
whuber

คำตอบ:


14

นี่คือโซลูชันแรสเตอร์บริสุทธิ์ที่Python 2.7ใช้numpyและ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()

การป้อนข้อมูล: ป้อนคำอธิบายรูปภาพที่นี่

เอาท์พุท: ป้อนคำอธิบายรูปภาพที่นี่


1
+1 สำหรับวิธีการขยาย! มันทำงานกับจุดใกล้เกินไป
Antonio Falciano

นี่เป็นตัวอย่างที่ดีว่าทำไม colourscheme เจ็ทเก่านั้นแย่มาก มันดูชัดเจนยิ่งขึ้นด้วย viridis
naught101

8

วิธีการใช้เวกเตอร์

ภารกิจนี้สามารถทำได้ในสามขั้นตอน:

หมายเหตุ: การใช้ฟิลด์บัฟเฟอร์หลีกเลี่ยงการคำนวณบัฟเฟอร์สำหรับแต่ละค่ารัศมีมงกุฎ


วิธีการเชิง Raster

การหลีกเลี่ยงโซลูชันที่ใช้เวกเตอร์ปัญหานี้แนะนำให้ใช้Cellular Automataชนิดหนึ่งโดยยึดตามเพื่อนบ้านที่ใกล้ที่สุด สมมติว่าพิกเซลสีดำทั้งหมดเป็นศูนย์พิกเซลจะถูกยกกำลังสองและขนาดเท่ากับ 1 (หรือมิฉะนั้นจะถูกปรับขนาดโดยฉวยโอกาส) กฎที่จะนำมาใช้นั้นง่ายมาก:

  1. หากค่าพิกเซล ( VALUE) มากกว่า 1 ค่าจะกลายเป็นVALUE-1และพิจารณาพิกเซลโดยรอบ ถ้าค่าของพวกเขาน้อยกว่าVALUE-1พิกเซลเหล่านี้เกิดหรือเติบโตVALUE-1และความคุ้มค่าของพวกเขาจะกลายเป็น มิฉะนั้นพิกเซลเหล่านี้จะอยู่รอดและไม่มีการเปลี่ยนแปลง
  2. ถ้าVALUE<=1ไม่ทำอะไรเลย (พิกเซลเสียชีวิต!)

ต้องใช้กฎเหล่านี้จนกว่าพิกเซลทั้งหมดจะตายเช่นค่าเหล่านั้นเท่ากับ 0 หรือ 1 ดังนั้นN-1เวลาที่Nค่าสูงสุดที่คุณมีในแรสเตอร์อินพุทคืออะไร วิธีการนี้สามารถนำไปใช้กับ Python และ numpy ได้อย่างง่ายดาย


1
ขอบคุณสำหรับการตอบสนอง afalciano วิธีนี้เป็นวิธีที่ฉันสร้างภาพไปทางขวาและใช้วิธีเวกเตอร์ - ฉันพยายามหลีกเลี่ยง
แอรอน

1
Ok Aaron นี่เป็นวิธีการเชิงภาพในขณะนี้ หวังว่านี่จะช่วยได้
Antonio Falciano

7

อีกทางเลือกหนึ่งคือการสร้างแรสเตอร์แยกต่างหากสำหรับแต่ละค่าพิกเซลในกรณีนี้คือแรสเตอร์ 4 ตัวพร้อมเงื่อนไข จากนั้นขยายภาพแรสเตอร์ด้วยจำนวนพิกเซลที่สอดคล้องกับค่าของแรสเตอร์ (โดยอาจวนซ้ำตามรายการค่า) สุดท้ายเข้าร่วม rasters (พีชคณิตหรือเชิงพื้นที่) เพื่อสร้างหนึ่ง raster ไบนารีสำหรับครอบฟันต้นไม้


1
ความคิดนี้เป็นสิ่งที่ถูกต้อง รายละเอียดสามารถปรับปรุงได้: (1) การเลือกสร้างตัวบ่งชี้ไบนารี (0,1) ของต้นไม้ของรัศมีมงกุฎที่กำหนด (2) ผลรวมโฟกัสของการเลือกนั้น - การใช้ย่านวงกลมของรัศมีที่กำหนด - นั้นรวดเร็วในการคำนวณโดยใช้ FFT (3) การเพิ่มผลรวมของโฟกัส (จุดในแนวนอน) และเปรียบเทียบกับ 0 จะให้บัฟเฟอร์ที่ต้องการ
whuber

7

เป็นคำถามที่ท้าทายในการทำเช่นนี้เพราะคุณไม่มีโอกาสใช้ค่าของพิกเซลเพื่อกำหนดขนาดของบัฟเฟอร์ ดังนั้นคุณจะต้องทำฟิลเตอร์โฟกัสสำหรับแต่ละค่าตามที่คุณพูดไปแล้ว

นี่เป็นคำตอบที่เป็นไปได้ที่จะทำกับตัวกรองเพียง 3 ตัว (ฉันหาได้น้อยลง) แต่ไม่สมบูรณ์แบบตามที่ Whuber กล่าวถึง: บัฟเฟอร์ของคุณจะถูกตัดเมื่อต้นไม้ใกล้กัน

1) แก้ไข: การจัดสรรแบบยุคลิด (สิ่งนี้ไม่สามารถแก้ปัญหาได้อย่างสมบูรณ์เนื่องจากมันจะตัดบัฟเฟอร์ในบริเวณใกล้เคียงของต้นไม้ขนาดเล็ก แต่มันก็ดีกว่าสิ่งประดิษฐ์ของวิธีแก้ปัญหาแรกของฉัน)

2) ระยะ euclidianรอบแต่ละพิกเซล

3) เครื่องคิดเลขแรสเตอร์ (พีชคณิตแผนที่) พร้อมคำสั่งแบบมีเงื่อนไข

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

โปรดทราบว่าคุณสามารถปรับการแสดงผลตามความต้องการของคุณในแง่ของรัศมี (ด้วยหรือไม่รวมพิกเซลกลาง)


+1 นี่คือวิธีการที่สร้างสรรค์ ฉันจะทดสอบเพื่อดูว่าเป็นไปได้ที่จะขยายขนาดโดยใช้วิธีการนี้หรือไม่
แอรอน

2
วิธีระยะทางแบบยุคลิดจะไม่ทำงานเพราะมันคำนวณระยะทางจากต้นไม้ที่ใกล้ที่สุดซึ่งไม่จำเป็นต้องเป็นระยะทางไปยังต้นไม้ที่มีมงกุฎครอบคลุมจุด
whuber

2

สงสัยว่าทำไมคุณไม่ใช้เครื่องมือขยายของ 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)

ในกรณีที่มีการทับซ้อน: expandคำสั่งล่าสุดจะครอบคลุมคำสั่งก่อนหน้า


2

หากคุณมีตำแหน่งพิกเซลอัลกอริทึมรัศมีและวงกลมจุดกึ่งกลาง (ตัวแปรของ Bresenham Alg.) ให้เบาะแสคุณ IMO มันง่ายในการสร้างรูปหลายเหลี่ยมจากวิธีการนี้และฉันคิดว่ามันง่ายที่จะนำไปใช้ใน Python การรวมกันของรูปหลายเหลี่ยมชุดนี้จะให้พื้นที่ครอบคลุม


ฉันรู้ว่ามันไม่ได้เป็นคำถาม แต่คุณต้องการที่จะรู้เพิ่มเติมเกี่ยวกับกราฟิกดั้งเดิมและการสแกนเส้นเติมรูปหลายเหลี่ยม? สำหรับ cirles มันง่ายมาก ชุดค่าผสมนูนเป็น buzzword และอื่น ๆ ....
huckfinn

สิ่งนี้จะถูกนำไปใช้โดยใช้การปฏิบัติการแรสเตอร์ขั้นพื้นฐานได้อย่างไร
whuber

หากคุณพยายามที่จะจัดการสิ่งนี้ในพื้นที่แรสเตอร์กำหนดจุดวงกลมจัดเรียงพวกมันด้วย y หรือ x และเติมช่องว่างด้วยเส้นตรง (เส้นสแกน) เป็นวิธีที่จะเติมวงกลม ในวิธีสามเหลี่ยมถ้าคุณสร้างวงกลมโดยการประมาณของภาค tringular และพยายามเติมสามเหลี่ยมคุณจำเป็นต้องทดสอบว่าจุดนั้นอยู่ข้างในหรือข้างนอก (รวมกันนูน) และเป็นวิธีอื่น และใน "GIS" appoach การสร้างรูปหลายเหลี่ยม (รูปหลายเหลี่ยมเชิงนาฬิกาที่ชาญฉลาด) และทำการรวมกันเป็นครั้งที่สาม (IMO ที่มีราคาแพงที่สุดในการคำนวณ)
huckfinn

เพื่อความชัดเจน: และใน "GIS" appoach ... ทำให้การดำเนินงานเกี่ยวกับพีชคณิตเช่นสหภาพการแยกการสัมผัส .... เป็น IMO ที่สามที่มีราคาแพงที่สุดในการคำนวณ
huckfinn
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.