SDFIdk / skraafoto_stac_public

Other
6 stars 1 forks source link

Finding pixel position in an image based on coordinates #61

Closed samlama111 closed 1 year ago

samlama111 commented 1 year ago

I am able to search for an image of a polygon, but I would like to specifically locate it. Is there a way of achieving this, based on its coordinates?

I have tried the georeferencing mentioned in the documentation, but without success. I try calculate the (xa, ya) position, but as a result I get a ya position of 27998.858461163214, well outside of the bounds of the image (its height is 8578 pixels). Only difference to documenation is our assumption that Z=Zc. We expect ~(5750, 3350), but receive (5147, 27998).

Following is the geojson and georeferencing calculation. Any help is greatly appreciated!

  1. I query data using the /search/ endpoint, with the following example response:

    "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [
                            711020.0,
                            6166399.999999999
                        ],
                        [
                            710825.0,
                            6167520.0
                        ],
                        [
                            712076.0,
                            6167500.0
                        ],
                        [
                            711888.0,
                            6166390.000000001
                        ],
                        [
                            711020.0,
                            6166399.999999999
                        ]
                    ]
                ]
            },
            "bbox": [
                710825.0,
                6166390.000000001,
                712076.0,
                6167520.0
            ],
            "properties": {
                "datetime": "2019-05-05T08:55:38Z",
                "gsd": 0.1,
                "license": "various",
                "platform": "Fixed-wing aircraft",
                "instruments": [
                    "PhaseOne-IXU-RS-1000_RS011009"
                ],
                "providers": [
                    {
                        "name": "MGGP_Aero",
                        "roles": [
                            "producer"
                        ]
                    },
                    {
                        "url": "https://sdfi.dk/",
                        "name": "SDFI",
                        "roles": [
                            "licensor",
                            "host"
                        ]
                    }
                ],
                "proj:epsg": null,
                "proj:shape": [
                    8578.0,
                    11478.0
                ],
                "direction": "north",
                "estimated_accuracy": 0.01,
                "pers:omega": 44.7639,
                "pers:phi": 0.709278,
                "pers:kappa": -0.560045,
                "pers:perspective_center": [
                    711481.37,
                    6165370.14,
                    1492.23
                ],
                "pers:crs": 25832,
                "pers:vertical_crs": 5799,
                "pers:rotation_matrix": [
                    0.9998756105860587,
                    0.00177663759250761,
                    -0.015671851008138338,
                    0.009773724690373558,
                    0.7100659311567243,
                    0.7040673602122247,
                    0.012378920018853833,
                    -0.7041329540430549,
                    0.7099602421049842
                ],
                "pers:interior_orientation": {
                    "camera_id": "PhaseOne-IXU-RS-1000_RS011009",
                    "focal_length": 108.2201,
                    "pixel_spacing": [
                        0.0046,
                        0.0046
                    ],
                    "calibration_date": "2019-02-21",
                    "principal_point_offset": [
                        0.0,
                        0.0
                    ],
                    "sensor_array_dimensions": [
                        11478.0,
                        8578.0
                    ]
                },
                "asset:data": "https://cdn.dataforsyningen.dk/skraafoto_server/COG_oblique_2019/10km_616_71/1km_6166_711/2019_85_47_2_0044_00001106.tif",
                "asset:thumbnail": "..."
            },
  2. Pixel calculation:

    
    props = item["properties"]
    m11, m12, m13, m21, m22, m23, m31, m32, m33 = props["pers:rotation_matrix"]
    Xc, Yc, Zc = props["pers:perspective_center"]
    f_mm = props["pers:interior_orientation"]["focal_length"]
    ppo_x, ppo_y = props["pers:interior_orientation"]["principal_point_offset"]
    pixel_size = props["pers:interior_orientation"]["pixel_spacing"][0]
    sensor_cols, sensor_rows = props["pers:interior_orientation"]["sensor_array_dimensions"]

Calculated values. In pixels. Origo in image lower left.

f = f_mm / pixel_size x0 = sensor_cols 0.5 + ppo_x / pixel_size y0 = sensor_rows 0.5 + ppo_y / pixel_size

X = (item['bbox'][0] + item['bbox'][2]) / 2 Y = (item['bbox'][1] + item['bbox'][3]) / 2 Z = Zc # We assume the Z coordinate of the polygon is the same

dX = (X-Xc) dY = (Y-Yc) dZ = (Z-Zc)

n = (m31 dX + m32 dY + m33 * dZ)

xa = x0 - f (m11 dX + m12 dY + m13 dZ) / n ya = y0 - f (m21 dX + m22 dY + m23 dZ) / n

NicolaiLolansen commented 1 year ago

The assumption of Z = Zc is where it goes wrong. You actually want the Z coordinate for the corresponding pixel on the ground. There are various ways to find this, but a quick way to see that the other calculations you made are correct, is to assign Z a value closer to the ground, could be between 10-30.

For the real value of Z you need a terrain model. See https://datafordeler.dk/dataoversigt/danmarks-hoejdemodel-dhm/dhm-wms/