benhuff / random_geospatial

0 stars 0 forks source link

stuff #3

Open benhuff opened 1 year ago

benhuff commented 1 year ago
import os
from PIL import Image
import rasterio
from rasterio.windows import Window
import cv2

def split_image(image_path, square_size, overlap):
    # Open the image using Rasterio
    with rasterio.open(image_path) as src:
        # Get the size of the image
        height, width = src.height, src.width
        # Iterate over the rows and columns of the image
        for row in range(0, height, square_size - overlap):
            for col in range(0, width, square_size - overlap):
                # Define the window corresponding to the current square
                if row + square_size > height or col + square_size > width:
                    pass
                else:
                    window = Window(col, row, square_size, square_size)
                    # Read the data for the current square
                    data = src.read(1, window=window)

                    clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
                    eq_data = clahe.apply(data.astype('uint8'))

                    # Define the metadata for the output file
                    meta = src.meta.copy()
                    meta.update({
                        'width': window.width,
                        'height': window.height,
                        'transform': rasterio.windows.transform(window, src.transform)
                    })
                    # Define the output file name
                    out_file = f'square_{row}_{col}.tif'
                    # Write the current square to the output file
                    Image.fromarray(eq_data).save(out_file.replace('.tif', '.png'))
                    with rasterio.open(out_file, 'w', **meta) as out:
                        out.write(eq_data, 1)
import json
import os
import shutil

def get_img(filename):
    for img in coco_anno['images']:
        if img['file_name'] == filename:
            return img

def get_img_ann(image_id):
    img_ann = []
    isFound = False
    for ann in coco_anno['annotations']:
        if ann['image_id'] == image_id:
            img_ann.append(ann)
            isFound = True
    if isFound:
        return img_ann
    else: 
        return None

def coco_to_yolo(x1, y1, w, h, image_w, image_h):
    return [
        ((2*x1 + w)/(2*image_w)), 
        ((2*y1 + h)/(2*image_h)), 
        w/image_w, 
        h/image_h
    ]

coco = 'test_chips/via_project_30Mar2023_18h55m_coco-2.json'
coco_json = open(coco)
coco_anno = json.load(coco_json)
coco_json.close()

file_names = [] 

for file in os.listdir('test_chips/'):
    if file.endswith('.png'):
        file_names.append(file)

file_names

for filename in file_names:
    img = get_img(filename)

    img_id = img['id']
    img_w = img['width']
    img_h = img['height']

    img_ann = get_img_ann(img_id)

    if img_ann:
        # shutil to move image to a new images folder
        # shutil.copy(source, destination)

        lbl_fn = filename.replace('.png', '.txt')
        txt = open(f'test_chips/labels/{lbl_fn}', 'a')

        for ann in img_ann:
            category = ann['category_id'] - 1
            current_bbox = ann['bbox']
            x = current_bbox[0]
            y = current_bbox[1]
            w = current_bbox[2]
            h = current_bbox[3]

            xc, yc, w, h = coco_to_yolo(x, y, w, h, img_w, img_h)
            txt.write(f"{category} {xc} {yc} {w} {h}\n")

        txt.close()
import rasterio
from shapely.geometry import box
import geopandas as gpd

def bbox_to_geospatial(src, xmin, ymin, xmax, ymax):
    # Convert the pixel bounds to geospatial bounds
    xmin, ymin = rasterio.transform.xy(src.transform, xmin, ymin, offset='ul')
    xmax, ymax = rasterio.transform.xy(src.transform, xmax, ymax, offset='ul')

    # Create the polygon
    polygon = box(xmin, ymin, xmax, ymax)
    return polygon

def yolo_to_bbox(yolo_coords, image_w, image_h):
    x_center, y_center, w, h = yolo_coords
    w = w * image_w
    h = h * image_h
    x1 = ((2 * x_center * image_w) - w)/2
    y1 = ((2 * y_center * image_h) - h)/2
    x2 = x1 + w
    y2 = y1 + h
    return [x1, y1, x2, y2]

# Load the geospatial metadata
with rasterio.open('square_0_0.tif') as src:
    crs = src.crs

    # Load the text file
    with open('coords.txt', 'r') as f:
        coords = [tuple(map(float, line.strip().split())) for line in f]

    # Convert the pixel coordinates to geographic coordinates
    geoms = [bbox_to_geospatial(src, *yolo_to_bbox(yolo_coords, src.width, src.height)) for yolo_coords in coords]

# Create a GeoDataFrame with the converted geometries
gdf = gpd.GeoDataFrame(geometry=geoms, crs=crs)
benhuff commented 1 year ago
import rasterio
from rasterio.warp import Resampling

xres, yres = float, float
with rasterio.open('') as dataset:
    scale_factor_x = dataset.res[0]/xres
    scale_factor_y = dataset.res[1]/yres

    profile = dataset.profile.copy()
    # resample data to target shape
    data = dataset.read(
        out_shape=(
            dataset.count,
            int(dataset.height * scale_factor_y),
            int(dataset.width * scale_factor_x)
        ),
        resampling=Resampling.bilinear
    )

    # scale image transform
    transform = dataset.transform * dataset.transform.scale(
        (1 / scale_factor_x),
        (1 / scale_factor_y)
    )
    profile.update({'height': data.shape[-2],
                    'width': data.shape[-1],
                   'transform': transform})

with rasterio.open('', 'w', **profile) as dataset:
    dataset.write(data)