Xử lý ảnh bằng Python, GDAL và Scikit-Image


11

Tôi đang vật lộn với một quá trình xử lý và hy vọng tôi sẽ có thể giải quyết ở đây.

Tôi làm việc với Viễn thám áp dụng cho Lâm nghiệp, đặc biệt là làm việc với dữ liệu LiDAR. Ý tưởng là sử dụng Scikit-image để phát hiện ngọn cây. Vì tôi là người mới trong Python, tôi đã xem xét một chiến thắng cá nhân tuyệt vời để làm như sau:

  1. Nhập một CHM (với matplotlib);
  2. Chạy bộ lọc gaussian (với gói hình ảnh scikit);
  3. Chạy bộ lọc cực đại (với gói hình ảnh scikit);
  4. Chạy pic_local_max (với gói hình ảnh scikit);
  5. Hiển thị CHM với cực đại cục bộ (với matplotlib);

Bây giờ vấn đề của tôi. Khi tôi nhập bằng matplot, hình ảnh sẽ mất tọa độ địa lý. Vì vậy, tọa độ tôi có chỉ là tọa độ hình ảnh cơ bản (tức là 250.312). Điều tôi cần là lấy giá trị của pixel dưới dấu chấm cực đại cục bộ trong ảnh (chấm đỏ trong ảnh). Ở đây trong diễn đàn tôi thấy một anh chàng hỏi điều tương tự ( Lấy giá trị pixel của raster GDAL dưới điểm OGR mà không có NumPy? ), Nhưng anh ta đã có điểm trong một shapefile. Trong trường hợp của tôi, các điểm được tính toán với hình ảnh scikit (Đó là một mảng với tọa độ của mỗi đỉnh cây). Vì vậy, tôi không có shapefile.

Tóm lại, thứ tôi muốn cuối cùng là một tệp txt với tọa độ của từng cực đại cục bộ trong tọa độ địa lý, ví dụ:

525412 62980123 1150 ...

Cực đại cục bộ (chấm đỏ) trong CHM

Câu trả lời:


11

Đầu tiên, chào mừng đến với trang web!

Mảng Numpy không có khái niệm về hệ tọa độ được tích hợp vào mảng. Đối với raster 2D, chúng được lập chỉ mục theo cột và hàng.

Lưu ý Tôi đang đưa ra giả định rằng bạn đang đọc định dạng raster được GDAL hỗ trợ .

Trong Python cách tốt nhất để nhập dữ liệu raster không gian là với rasteriogói. Dữ liệu thô được rasterio nhập vào vẫn là một mảng gọn gàng không có quyền truy cập vào các hệ tọa độ, nhưng rasterio cũng cho phép bạn truy cập vào một phương thức affine trên mảng nguồn mà bạn có thể sử dụng để chuyển đổi các cột và hàng raster thành tọa độ được chiếu. Ví dụ:

import rasterio

# The best way to open a raster with rasterio is through the context manager
# so that it closes automatically

with rasterio.open(path_to_raster) as source:

    data = source.read(1) # Read raster band 1 as a numpy array
    affine = source.affine

# ... do some work with scikit-image and get an array of local maxima locations
# e.g.
# maxima = numpy.array([[0, 0], [1, 1], [2, 2]])
# Also note that convention in a numy array for a 2d array is rows (y), columns (x)

for point in maxima: #Loop over each pair of coordinates
    column = point[1]
    row = point[0]
    x, y = affine * (column, row)
    print x, y

# Or you can do it all at once:

columns = maxima[:, 1]
rows = maxima[:, 0]

xs, ys = affine * (columns, rows)

Và từ đó bạn có thể viết kết quả của chúng tôi vào một tệp văn bản theo cách bạn muốn (ví dụ tôi khuyên bạn nên xem mô-đun sẵn cócsv ).


Cảm ơn rât nhiều. Có vẻ như điều này có thể làm việc. Vì tôi mới làm việc này, tôi vẫn phải làm quen với rất nhiều thứ. Cảm ơn sự kiên nhẫn.
João Paulo Pereira

1
Trong Rasterio 1.x, bạn có thể sử dụng source.xy (hàng, cột) để lấy tọa độ địa lý.
bugmenot123


0

Vui lòng thử với đoạn mã sau. Điều này có thể được sử dụng để đọc dữ liệu hình ảnh từ raster và ghi dữ liệu đã xử lý vào raster (tệp .geotiff).

from PIL import Image,ImageOps
import numpy as np
from osgeo import gdal
#from osgeo import gdal_array
#from osgeo import osr
#from osgeo.gdalconst import *
#import matplotlib.pylab as plt

#from PIL import Image, ImageOps
#import gdal
#from PIL import Image
gdal.AllRegister()

################## Read Raster #################
inRaster='C:\python\Results\Database\Risat1CRS\CRS_LEVEL2_GEOTIFF\scene_HH\imagery_HH.tif'

inDS=gdal.Open(inRaster,1)
geoTransform = inDS.GetGeoTransform()
band=inDS.GetRasterBand(1)
datatype=band.DataType
proj = inDS.GetProjection()
rows = inDS.RasterYSize
cols=inDS.RasterXSize
data=band.ReadAsArray(0,0,cols,rows)#extraction of data to be processed#
############write raster##########
driver=inDS.GetDriver()
outRaster='C:\\python\\Results\\Database\\Temporary data base\\clipped_26July2017\\demo11.tif'
outDS = driver.Create(outRaster, cols,rows, 1,datatype)
geoTransform = inDS.GetGeoTransform()
outDS.SetGeoTransform(geoTransform)
proj = inDS.GetProjection()
outDS.SetProjection(proj)
outBand = outDS.GetRasterBand(1)
outBand.WriteArray(data1,0,0)
#data is the output array to written in tiff file
outDS=None 
im2=Image.open('C:\\python\\Results\\Database\\Temporary data base\\clipped_26July2017\\demo11.tif');
im2.show()
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.