publiclab / mapknitter

Upload your own aerial images, position (rubbersheet) them in a web interface over existing map data, and share via web or composite and export for print.
http://mapknitter.org
GNU General Public License v3.0
267 stars 211 forks source link

use GPS exif data to guess scale of image placement #176

Closed jywarren closed 9 years ago

jywarren commented 9 years ago

it'd be great to use the altitude from GPS to roughly scale images.

But this is tough because GPS offers only altitude over sea level, so we'd have to subtract the ground elevation. We'd also probably want to know the camera's field of view if we want to get a closer fit.

Maybe we could use Google's Elevation Service in their Google Maps JS API.

jywarren commented 9 years ago
// Create an ElevationService
var elevator = new google.maps.ElevationService(), lat = 42, lng = -71;

elevator.getElevationForLocations({'locations':[ {lat: lat, lng: lng} ]
  },function(results, status) { 
    console.log(results[0].elevation); 
  }
)

This works!

jywarren commented 9 years ago

OK, we can guess field of view is ~50 degrees, and we can now get height above ground. Trigonometry!!!!

jywarren commented 9 years ago

image

a = camera height above ground
B = field of view / 2 = 25 degrees
A = (180-2B) / 2 = 65 degrees
a / tan(A) = b
2b = width of image on ground

width = 2 * (a / Math.tan(A))
jywarren commented 9 years ago

I have implemented it this far, but my console says:

Map.js?body=1:165 Photo taken from 62.859 meters above sea level
Map.js?body=1:166 Ground is 488.9666748046875 meters above sea level
Map.js?body=1:167 Photo taken from -426.1076748046875 meters
Map.js?body=1:173 Photo should be -715.0935855408433 meters wide
Fastie commented 9 years ago

If guessing is okay, you can probably get closer to the field of view most of the time. EXIF data includes the focal length for each photo, but does not include the size of the sensor, so the field of view is unknown. You could look up the sensor size of that camera model (given in the EXIF data), but it might be a pain to make that table. Most PowerShots that people fly have the same size sensor, and many other low-end point & shoots have the same size sensor (1/2.3 inch). So you could assume the sensor size and compute field of view from that and the focal length. When it fails, e.g. with a phone camera with a tiny sensor, it will fail miserably.

jywarren commented 9 years ago

I've just implemented this and it's "working" -- but hard to assess how good our estimates are (such as an est. default 50 degree field of view -- what do you think, Chris?) without running some images through it. I agree that field of view can dramatically affect our guesses in a way that just GPS precision wouldn't as much.

jywarren commented 9 years ago

about to push into production... done!

Fastie commented 9 years ago

For a typical PowerShot, the widest focal length is equivalent to 28mm. That converts to a diagonal field of view of 75°. For an S90 to S120, the widest focal length is equivalent to 24 mm, which converts to a diagonal field of view of 85°

jywarren commented 9 years ago

I'm not sure which field of view I should work with -- average? Diagonal is the widest possible. I am currently averaging vertical and horizontal FOV in the code I wrote up, and making the estimation/assumption that their average should be ~50 degrees. Any interest in doing the math to convert from diagonal to average vert/horiz?

On Thu, May 21, 2015 at 10:16 AM, Fastie notifications@github.com wrote:

For a typical PowerShot, the widest focal length is equivalent to 28mm. That converts to a diagonal field of view of 75°. For an S90 to S120, the widest focal length is equivalent to 24 mm, which converts to a diagonal field of view of 85°

— Reply to this email directly or view it on GitHub https://github.com/publiclab/mapknitter/issues/176#issuecomment-104315281 .

Fastie commented 9 years ago

For typical small PowerShot, horizontal FOV is 63.3, vertical FOV is 48.9, mean=56.1 For S90 to S120, horizontal FOV is 72.3, vertical FOV is 57.5, mean = 64.9

jywarren commented 9 years ago

Hmm, so perhaps 60 degrees would be a better default.

On Thu, May 21, 2015 at 10:25 AM, Fastie notifications@github.com wrote:

For typical small PowerShot, horizontal FOV is 63.3, vertical FOV is 48.9, mean=56.1 For S90 to S120, horizontal FOV is 72.3, vertical FOV is 57.5, mean = 64.9

— Reply to this email directly or view it on GitHub https://github.com/publiclab/mapknitter/issues/176#issuecomment-104318505 .

jywarren commented 9 years ago

For reference, Chris, here are all the EXIF tags from a very fully EXIF provided image:

--------------------+----------------------------------------------------------
EXIF data contains a thumbnail (4220 bytes).
EXIF tags in 'RIMG0352.JPG' ('Motorola' byte order):
--------------------+----------------------------------------------------------
Tag                 |Value
--------------------+----------------------------------------------------------
Image Description   |Exif_JPEG_PICTURE                                         
Manufacturer        |RICOH      
Model               |G700 SE        
Orientation         |Bottom-right
X-Resolution        |72
Y-Resolution        |72
Resolution Unit     |Inch
Software            |G700SE Firmware
Date and Time       |2013:06:13 14:34:38
YCbCr Positioning   |Co-sited
Copyright           |[None] (Photographer) - [None] (Editor)
PRINT Image Matching|212 bytes undefined data
Compression         |JPEG compression
X-Resolution        |72
Y-Resolution        |72
Resolution Unit     |Inch
Exposure Time       |1/863 sec.
F-Number            |f/3.5
Exposure Program    |Normal program
ISO Speed Ratings   |64
Exif Version        |Exif Version 2.21
Date and Time (Origi|2013:06:13 14:34:38
Date and Time (Digit|2013:06:13 14:34:38
Components Configura|Y Cb Cr -
Compressed Bits per |3.22
Aperture            |0.35 EV (f/1.1)
Brightness          |9.00 EV (1754.24 cd/m^2)
Exposure Bias       |0.00 EV
Maximum Aperture Val|3.61 EV (f/3.5)
Metering Mode       |Center-weighted average
Light Source        |Unknown
Flash               |Flash did not fire, compulsory flash mode
Focal Length        |5.0 mm
Maker Note          |5276 bytes undefined data
User Comment        |GP1
FlashPixVersion     |FlashPix Version 1.0
Color Space         |sRGB
Pixel X Dimension   |4000
Pixel Y Dimension   |3000
Exposure Mode       |Auto exposure
White Balance       |Auto white balance
Scene Capture Type  |Standard
Sharpness           |Normal
GPS Tag Version     |2.2.0.0
North or South Latit|N
Latitude            |46, 36, 35.718
East or West Longitu|E
Longitude           |13, 52, 58.674
Altitude Reference  |Sea level
Altitude            |616.40
GPS Time (Atomic Clo|12:49:10.00
GPS Satellites      |24,12,25,17,15,14,04,02,,,,,                              
GPS Receiver Status |A
GPS Measurement Mode|3
Measurement Precisio|0.90
Speed Unit          |N
Speed of GPS Receive|3.36
Reference for direct|M
Direction of Movemen|147.07
GPS Image Direction |T
GPS Image Direction |198.78
Geodetic Survey Data|WGS-84                         
Reference For Latitu|
Latitude of Destinat|0/0, 0/0, 0/0
Reference for Longit|
Longitude of Destina|0/0, 0/0, 0/0
Reference for Bearin|T
Bearing of Destinati|0.20
Reference for Distan|K
Distance to Destinat| 0
Name of GPS Processi|1 bytes undefined data
Name of GPS Area    |1 bytes undefined data
GPS Date            |2013:06:13
GPS Differential Cor|0
Interoperability Ind|R98
Interoperability Ver|0100
Fastie commented 9 years ago

The Ricoh G7 SE has the typical point & shoot sensor (1/2.3 inch), but the EXIF data do not include that information. If you had assumed that or found it in a look up table, you could have calculated that a 5 mm focal length (given in the EXIF) produces the equivalent (35mm eq) of a 28 mm lens which has a horizontal FOV of 63.3° and vertical FOV of 48.9°.

jywarren commented 9 years ago

How widely do sensor sizes vary? i.e. how big would the lookup table be?

Fastie commented 9 years ago

There are CHDK versions for 130 PowerShot models. Probably most of those used for mapping have 1/2.3" sensors, and most of the rest that any aerial mappers use have 1/1.7" sensors (or maybe one or two other sizes). That table might exist somewhere or would not be too hard to make if you like boring tasks. If your fov algorithm worked only for PowerShots you might succeed for 70 to 90% of MapKnitter maps. There are a lot of other camera makes and models out there, so a comprehensive table would be a lot of work (unless someone had already done it) and it might not add much to your success rate.

jywarren commented 9 years ago

Are you looking at a reference somewhere about the sensor sizes? How do you know -- maybe we could adapt from the CHDK website if they have one.

On Sun, Jun 7, 2015 at 3:15 PM, Fastie notifications@github.com wrote:

There are CHDK versions for 130 PowerShot models. Probably most of those used for mapping have 1/2.3" sensors, and most of the rest that any aerial mappers use have 1/1.7" sensors (or maybe one or two other sizes). That table might exist somewhere or would not be too hard to make if you like boring tasks. If your fov algorithm worked only for PowerShots you might succeed for 70 to 90% of MapKnitter maps. There are a lot of other camera makes and models out there, so a comprehensive table would be a lot of work (unless someone had already done it) and it might not add much to your success rate.

— Reply to this email directly or view it on GitHub https://github.com/publiclab/mapknitter/issues/176#issuecomment-109789585 .

Fastie commented 9 years ago

I have not found a list of camera model and sensor size. I have to search for each model. Reviews at DPreview.com always include the sensor size.

Fastie commented 9 years ago

Here is a start for your lookup table: http://arch.ced.berkeley.edu/kap/discuss/index.php?p=/discussion/5461/comparison-of-lightweight-cameras-by-weight-and-sensor-size

jywarren commented 9 years ago

New possibility: sourcing from https://github.com/perliedman/elevation-service which sources from lots of different places: http://www.imagico.de/map/demsearch.php -- suggested via @ebarry via @mojodna

Eventually want to use OpenTerrainMap.

This works! :

curl -i http://data.cykelbanor.se/elevation/geojson -X POST -H "Content-Type: application/json" -d '{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [125.6, 10.1]
  },
  "properties": {
    "name": "Dinagat Islands"
  }}'

returns:

{"type":"Feature","geometry":{"type":"Point","coordinates":[125.6,10.1,130.00000000012065]},"properties":{"name":"Dinagat Islands"}}

Haven't been able to figure out posting from jQuery in the right format yet, but I'm just being a bit dumb:

$.post('http://data.cykelbanor.se/elevation/geojson', {
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [125.6, 10.1]
  },
  "properties": {
    "name": "Dinagat Islands"
  }});