2

I have a PNG image which I am trying to georeference using four corners of coordinate information of the defined input image.

When I am trying to convert PNG to TIFF, I am getting 3 bands (R,G,B) raster. Then I have copied the metadata from the original raster and tried to save it as GeoTIFF along with copied metadata using rasterio library.

In the final output, I am getting only one e band as R band. but I want all the bands in my GeoTIFF output.

Below, I have attached, input PNG and output GeoTIFF images. While converting PNG to GeoTIFF, the blue and black features are missing. only yellow is capturing.

Below is my code,

import rasterio as rio
import numpy as np

#Input png image, to convert as geotiff img = rio.open('C:/Users/Documents/Study_Area_2.png') img = img.read([1,2,3]) img = img.astype('uint16')

Input image for coordinate reference

with rio.open('C:/Users/Study_Area_2_RGB.tif') as src: naip_data_ras = src.read() naip_meta = src.profile

#output images with rio.open('C:/Users/Georeferenced.tif', 'w', **naip_meta) as dst: dst.write(img,[1,2,3])

Input Png image

enter image description here

Output GeoTIFF

enter image description here

Vince
  • 20,017
  • 15
  • 45
  • 64
SWAT
  • 131
  • 3
  • 14

1 Answers1

4

edit: even more specific, the problem lies with .astype(uint16). Without this conversion, it loads fine. Also show(limg.read()) also works original: The problem lies with the show(rio.open(georeferenced.tif)). The data is saved properly, and when loaded all operations you would want to perform should work fine. if you're only interested in showing the image, you can show(limg.read([1,2,3])

Further, an (ugly) workaround would be to re-load and save the data. Then you can also resample so your rasters overlap (for calculations). When performed directly on the PNG, this crashed my kernel (sounds like a bug). I also changed the arguments for the rasterio.open('w') to use the shape of your img in stead of the reference image in case they do not exactly match. optionally, you could maybe resample your georeferenced image, so

import rasterio as rio
from rasterio.enums import Resampling
from rasterio.plot import show

#Input png image, to convert as geotiff img = rio.open('/path/to.png') img = img.read([1,2,3]) img = img.astype('uint16') show(img) #shows true color

Input image for coordinate reference

with rio.open('/path/to/reference.tif') as naip: #open georeferenced.tif for writing with rio.open( 'georeferenced.tif', 'w', driver='GTiff', count=img.shape[0], height=img.shape[1], width=img.shape[2], dtype=img.dtype, crs=naip.crs, transform=naip.transform, ) as dst: dst.write(img)

with rio.open('georeferenced.tif') as limg: show(limg) #1 band only shows show(limg.read([1,2,3])) #shows true color #resample so pixels overlap with reference limg = limg.read(out_shape=(3,naip.shape[0],naip.shape[1]), resampling=Resampling.nearest) with rio.open('resampled.tif','w', driver='GTiff', count=limg.shape[0], height=limg.shape[1], width=limg.shape[2], dtype=limg.dtype, crs=naip.crs, transform=naip.transform, ) as dst: dst.write(limg)

The writing is a bit verbose, but a passing of **naip.profile does not work, since the count is different, unless your reference layer has the same number of bands. an alternative would be storing naip.profile, and then changing the count manually.

Fee
  • 1,158
  • 4
  • 14