Search code examples
pythonpandasbounding-boxcoordinate-systemsyolov5

How to convert bounding box with relative coordinates of object resulting from running yolov5 into absolute coordinates


I have run the yolov5 model to predict trees in imagery with a geocoordinate. I got the bounding box objects with relative coordinates after running the model. I would like to have these bounding boxes with the absolute coordinate system as the imagery (NZTM 2000). Please help me to do this. Below are my bounding box information and original imagery for the prediction.

models= torch.hub.load('ultralytics/yolov5', 'custom', 'C:/Users/yolov5-master/runs/train/exp/weights/best.pt')
im=r'C:\imagery1.PNG'
results = models(im)
results.print()  
results.show()
results.xyxy[0]  
a=results.pandas().xyxy[0]
df=pd.DataFrame(a)
print(df)

enter image description here

   # function to convert polygons to bbox
def bbox(long0, lat0, lat1, long1):
    return Polygon([[long0, lat0], #long0=xmin, lat0=ymin, lat1=ymax, long1=xmax
                    [long1,lat0],
                    [long1,lat1],
                    [long0, lat1]])
​
test = bbox(144.2734528,350.0042114,359.900177,152.4013672) 
test1=bbox(366.7437744,215.1108856,226.6479034,376.282196)
​
gpd.GeoDataFrame(pd.DataFrame(['p1','p2'], columns = ['geom']),
         geometry = [test,test1]).to_file(r'C:\delete\poly1.shp')

enter image description here

The coordinate system of imagery: NZGD 2000 New Zealand Transverse Mercator.

 The extent of imagery: top: 5,702,588.730967 m, bottom:
 5,702,581.666007 m, left:1,902,830.371719m, right: 1,902,837.436679m

Solution

  • You can use rasterio's transform function:

    import rasterio as rio
    import pandas as pd
    from PIL import Image
    
    raster = rio.open(r'C:\imagery1.PNG')
    im = Image.open(r'C:\imagery1.PNG')
    results = models(im)
    
    results= results.pandas().xyxy[0]
    results['col'] = ((results['xmax'] + results['xmin']) / 2)
    results['row'] = ((results['ymax'] + results['ymin']) / 2)
    x, y = rio.transform.xy(im, results.row, results.col)
    

    This function transform rows and columns to coordinates (If your image is georeferenced). It works for me, it gives the centroid of each bounding box.