Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

question about Lesson 5 #1

Open
kheinzz opened this issue Jun 6, 2024 · 8 comments
Open

question about Lesson 5 #1

kheinzz opened this issue Jun 6, 2024 · 8 comments

Comments

@kheinzz
Copy link

kheinzz commented Jun 6, 2024

Hi,
First of all, thanks a lot for your hard work to make geospatial insights available for all, your tutorials are great.
I took the lesson 5: Semantic segmentation with geospatial data, the notebook works fine and now that I have satisfying results I'd like to export the predicted mask as a tif file. This is my code but it seems I didn't understand something as the exported .tif is never well geolocated (using your example data, the mask end up in Columbia).. Could you provide me some more light please?

width = predicted_masks.shape[2]
height = predicted_masks.shape[1]
transform = Affine(0.60, 0.00, 440055.00, 0.00, -0.60, 4303429.20)
crs = 'EPSG:26918'  # Coordinate reference system (modify as needed)

# Function to save the predicted mask as a .tif file
def save_mask_as_tif(mask, filename, transform, crs):
    with rasterio.open(
        filename,
        'w',
        driver='GTiff',
        height=mask.shape[0],
        width=mask.shape[1],
        count=1,
        dtype=mask.dtype,
        crs=crs,
        transform=transform
    ) as dst:
        dst.write(mask, 1)

# Convert predicted_masks to numpy and save as .tif
predicted_mask_numpy = predicted_masks.cpu().numpy().astype('uint8')  # Assuming masks are in binary format

# Save the first predicted mask as a sample
save_mask_as_tif(predicted_mask_numpy[0], 'predicted_mask.tif', transform, crs)

By advance, thanks
Thomas

@enomis-dev
Copy link
Owner

Hi @Lecaethomas thanks for your support, looking to your code it looks good. It could be that your mask has different affine or crs with respect to your input raster, I was wondering if you can share with me the input raster as well as the predicted mask, thank you.

@kheinzz
Copy link
Author

kheinzz commented Jun 7, 2024

Hi, sorry for the lack of context, I used your code and your input for a first try (NAIP imagery and Chesapeake landcover layer). The transform I use is the one returned by rasterio based on the input, and the crs too. These are the reasons why I was wondering if I didn't lose the georeference somehow during the process. I never tried deep learning before, so I don't know what can happen to the georeferencing during the process
image

@enomis-dev
Copy link
Owner

Hi! No worries the 2 snippets of code you shared with me, look correct. I'll try to replicate locally.
In case the files are not too big, could you share here please?

@kheinzz
Copy link
Author

kheinzz commented Jun 7, 2024

Thanks a lot for your help! I pushed my code here, it would be easier for you to reproduce. (be careful, I left the number of samples as if I was on kaggle)

@enomis-dev
Copy link
Owner

I'll check better during the weekend but at first sight you're copying the affine of the original naip big tile to the predicted mask.
The fact is that the mask is calculated on a crop of the original image and the affine therefore changes. The whole concept of the training was to have a testing and validation sets from some original big tiles by subcropping it in order to do data augumentation.

If you would like to check the model and have a well geolocated tiff file you could:

  • read a crop of one naip tile (here we use a crop because the model cannot run on a huge .tif)
  • get the numpy array, affine and crs of that crop
  • feed the numpy array to the DL model
  • the output will have exactly the same shape of the input
  • your method to save the mask should now work with the correct input

I'll try to elaborate more in the next days, thanks for your question

@enomis-dev
Copy link
Owner

enomis-dev commented Jun 9, 2024

Hi! Here a code you could use to do the prediction on a input .tif
In case the input .tif is too big as in this case you can read a crop.

# define path to one of the naip tile
path_tile = "/tmp/naip_val/m_3807512_sw_18_060_20180815.tif"

# print original raster shape
with rasterio.open(path_tile) as src:
    print("Original shape:", src.shape)

# input window in pixels
window = rasterio.windows.Window(500, 500, 1000, 1000)

# let's open a crop of the .Tif file
with rasterio.open(path_tile) as src:
    # Read the data within the window
    data = src.read(window=window)
    print("Original affine:", src.transform)
    
    
    # Optionally, get the transform for the window
    transform = src.window_transform(window)
    print("Windows affine:", transform)
    
    # Get the metadata of the input file
    metadata = src.meta.copy()
    
    print("Crop shape:", data.shape)

Prediction:

# Convert the NumPy array to a PyTorch tensor and reshape, we ignore band 4 that is the transperency
tensor_data = torch.tensor(data[0:3]).unsqueeze(0).float()  # tensor_data.shape will be (1, 3, 500, 500)
print("Tensor shape for prediction:",tensor_data.shape)


# Convert logits to predicted class labels
pred = model(tensor_data)
mask = torch.argmax(pred, dim=1)
print("Mask shape:", data.shape)

Save cropped tif

# Write the cropped data to a new .Tif file
output_tif_path = "crop.tif"

metadata.update({
    'height': window.height,
    'width': window.width,
    'transform': transform
})
        
with rasterio.open(output_tif_path, 'w', **metadata) as dst:
    dst.write(data)

Save cropped mask

# Write the mask data a new .Tif file
output_tif_path = "mask.tif"

metadata.update({
    'count': 1,           # Update the number of bands
    'height': window.height,
    'width': window.width,
    'transform': transform
})
    
with rasterio.open(output_tif_path, 'w', **metadata) as dst_mask:
        
    dst_mask.write(mask.cpu().numpy().astype(np.uint8))

Yo will be able to open them in QGIS for instance with the good geolocation:

image

@kheinzz
Copy link
Author

kheinzz commented Jun 10, 2024

Thanks a lot to have taken the time to test it! I'll try that during the week :)

@enomis-dev
Copy link
Owner

Hi @Lecaethomas I was wondering if the issue can be closed.
Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants