Search code examples
pythonalgorithmimagetiffgdal

how to do Image reprojection by setting some control points on a picture in any language


description:

  • How to correct a picture all points coordination by setting 2 point coordination? or which lib I need to use?
  • I prefer python lib solution but any language solution are accepted.
  • It is better if I can set the coordinate system in parameter.
  • I want to get all points(pixel) new coordination like example show, do/change nothing to image itself.
  • Edit: sry, now I know it is reprojection not correct.

example:

  • origin image:
  • one point means a pixel in origin image coordination(position).
[[(0, 0), (1, 0), (2, 0), (3, 0), (4, 0)],
[(0, 1), (1, 1), (2, 1), (3, 1), (4, 1)],
[(0, 2), (1, 2), (2, 2), (3, 2), (4, 2)],
[(0, 3), (1, 3), (2, 3), (3, 3), (4, 3)],
[(0, 4), (1, 4), (2, 4), (3, 4), (4, 4)]]
  • example picture coordination matrix:
    • (100,150),(200,200)represent the two points I set.
[[(0, 0), (1, 0), (2, 0), (3, 0), (4, 0)],
[(0, 1), (1, 1), (2, 1), (200, 200), (4, 1)],
[(0, 2), (1, 2), (2,2), (3, 2), (4, 2)],
[(0, 3), (100, 150), (2, 3), (3, 3), (4, 3)],
[(0, 4), (1, 4), (2, 4), (3, 4), (4, 4)]]
  • desired result
    • All pixel old coordination should change to new coordination, it means the distance between two adjacent pixel changed.
    • (150,175) is a example correct result after correction.
    • image itself change nothing.
[[(0, 0), (1, 0), (2, 0), (3, 0), (4, 0)],
[(0, 1), (1, 1), (2, 1), (200, 200), (4, 1)],
[(0, 2), (1, 2), (150,175), (3, 2), (4, 2)],
[(0, 3), (100, 150), (2, 3), (3, 3), (4, 3)],
[(0, 4), (1, 4), (2, 4), (3, 4), (4, 4)]]

what I have tried:

  • python hand write code:
def correction(n,m,set_point):
    x_length = abs(set_point[1]["new_x"]-set_point[0]["new_x"])/abs(set_point[1]["old_x"]-set_point[0]["old_x"])
    y_length = abs(set_point[1]["new_y"]-set_point[0]["new_y"])/abs(set_point[1]["old_y"]-set_point[0]["old_y"])
    ans = [[[set_point[0]["new_x"]+(i-set_point[0]["old_x"])*x_length,
             set_point[0]["new_y"]+(j-set_point[0]["old_y"])*y_length] for i in range(n)] for j in range(m)]
    print(ans[::-1])

correction(5,5,[{"old_x":1,"old_y":1,"new_x":100,"new_y":150},{"old_x":3,"old_y":3,"new_x":200,"new_y":200}])
  • result:
[[[50.0, 225.0], [100.0, 225.0], [150.0, 225.0], [200.0, 225.0], [250.0, 225.0]],
[[50.0, 200.0], [100.0, 200.0], [150.0, 200.0], [200.0, 200.0], [250.0, 200.0]],
[[50.0, 175.0], [100.0, 175.0], [150.0, 175.0], [200.0, 175.0], [250.0, 175.0]], 
[[50.0, 150.0], [100.0, 150.0], [150.0, 150.0], [200.0, 150.0], [250.0, 150.0]],
[[50.0, 125.0], [100.0, 125.0], [150.0, 125.0], [200.0, 125.0], [250.0, 125.0]]]

question:

  1. Any lib or wheel to solve this problem?
  2. How to apply this algorithm to a png or jpg file to correction whole picture by setting 2 points coordination?
  3. So far I set coordinate system in default, how can I set coordinate system by passing parameter?
  4. If I want to set 3 or more point to correct whole picture, how to improve this algorithm?

Solution

    • Finally I figure it out by myself, I need use lib gdal to do image reprojection by setting control point.

    • example code:

    from osgeo import gdal
    from osgeo import osr
    dataset = gdal.Open(r'test.tiff', gdal.GA_Update)
    gcps = [gdal.GCP(-111.931075, 41.745836, 0, 1078, 648),
            gdal.GCP(-111.901655, 41.749269, 0, 531, 295),
            gdal.GCP(-111.899180, 41.739882, 0, 722, 334),
            gdal.GCP(-111.930510, 41.728719, 0, 102, 548)]
    sr = osr.SpatialReference()
    sr.SetWellKnownGeogCS('WGS84')
    dataset.SetGCPs(gcps, sr.ExportToWkt())
    dst_ds = gdal.Warp(r'test_dst.tiff', dataset, format='GTiff', tps=True, xRes=0.05, yRes=0.05, 
                       dstNodata=65535, srcNodata=65535, resampleAlg=gdal.GRIORA_NearestNeighbour, outputType=gdal.GDT_Int32)