This repository has been archived by the owner on May 25, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added geolocation code (adapted from Chris's PR #79)
- Loading branch information
Benjamin Winger
committed
Jan 12, 2018
1 parent
320df32
commit 2c99eea
Showing
8 changed files
with
234 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
include_directories(include ../core/include) | ||
ADD_DEFINITIONS("-DBOOST_LOG_DYN_LINK") | ||
add_library(TargetAnalysis src/area_analyzer.cpp src/target_analyzer.cpp src/target_loader.cpp) | ||
add_library(TargetAnalysis src/area_analyzer.cpp src/target_analyzer.cpp src/target_loader.cpp src/gps.cpp) | ||
target_link_libraries(TargetAnalysis ${Boost_LIBRARIES} Core) | ||
target_compile_features(TargetAnalysis PRIVATE) | ||
add_subdirectory("test") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/** | ||
* @file gps.cpp | ||
* @author WARG | ||
* | ||
* @section LICENSE | ||
* | ||
* Copyright (c) 2015-2017, Waterloo Aerial Robotics Group (WARG) | ||
* All rights reserved. | ||
* | ||
* This software is licensed under a modified version of the BSD 3 clause license | ||
* that should have been included with this software in a file called COPYING.txt | ||
* Otherwise it is available at: | ||
* https://raw.githubusercontent.com/UWARG/computer-vision/master/COPYING.txt | ||
*/ | ||
|
||
#ifndef GPS_H | ||
#define GPS_H | ||
|
||
#include "frame.h" | ||
|
||
static const double GPS_TOLERANCE = 0.0000001; | ||
|
||
/** | ||
* @brief Determines GPS location of a point in an image | ||
* @param point Location in the image (pixels) | ||
* @param f Image | ||
* @param returnResult Resulting location in the image (in latitude and longitude) | ||
* | ||
* @return true on success, false on failure | ||
*/ | ||
int get_gps(cv::Point2d point, Frame *f, cv::Point2d *returnResult); | ||
|
||
/** | ||
* @brief Calculates the distance (in metres) between two sets of GPS co-ordinates | ||
* | ||
* Calculates distance in metres between two sets of GPS co-ordinates. | ||
* Inaccurate for long distances since it calculates the direct distance rather than the distance along the surface of the earth. | ||
*/ | ||
double gps_dist(cv::Point2d p1, cv::Point2d p2); | ||
|
||
#endif // GPS_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/** | ||
* @file gps.cpp | ||
* @author WARG | ||
* | ||
* @section LICENSE | ||
* | ||
* Copyright (c) 2015-2017, Waterloo Aerial Robotics Group (WARG) | ||
* All rights reserved. | ||
* | ||
* This software is licensed under a modified version of the BSD 3 clause license | ||
* that should have been included with this software in a file called COPYING.txt | ||
* Otherwise it is available at: | ||
* https://raw.githubusercontent.com/UWARG/computer-vision/master/COPYING.txt | ||
*/ | ||
|
||
#include <iomanip> | ||
#include <boost/log/trivial.hpp> | ||
#include "frame.h" | ||
|
||
#define RAD2DEG(rad) ((rad)*180.0/M_PI) | ||
#define DEG2RAD(deg) ((deg)*M_PI/180.0) | ||
#define EARTH_RADIUS 6371000 | ||
|
||
//Based on the GPS location of the image, calculates the | ||
//GPS location of a certain pixel in the image. | ||
bool get_gps(cv::Point2d point, Frame* f, cv::Point2d* returnResult){ | ||
if (f == NULL) { | ||
BOOST_LOG_TRIVIAL(error) << "Frame is null"; | ||
return false; | ||
} | ||
BOOST_LOG_TRIVIAL(trace) << "get_gps(" << point << ", " << f->get_id() << ")"; | ||
|
||
const Metadata* m = f->get_metadata(); | ||
cv::Mat img = f->get_img(); | ||
int h = img.cols; | ||
int w = img.rows; | ||
|
||
if (w <= 0 || h <= 0){ | ||
BOOST_LOG_TRIVIAL(error) << "Invalid frame size w:" << w << " h:" << h; | ||
return false; | ||
} | ||
|
||
cv::Point2d imgCenter(w/2, h/2); | ||
|
||
//(0,0) is in the center of the image | ||
cv::Point2d biasedPoint = point - imgCenter; | ||
|
||
double altitude = m->altitude; | ||
double heading = m->heading; | ||
double latitude = m->lat; | ||
double longitude = m->lon; | ||
|
||
BOOST_LOG_TRIVIAL(trace) << "Camera FOV: " << f->get_camera().get_fov(); | ||
|
||
BOOST_LOG_TRIVIAL(trace) << "Dist from Center (pixels: " << biasedPoint; | ||
|
||
double cameraXEdge = altitude * tan(DEG2RAD(f->get_camera().get_fov().width/2)); //meters from center of photo to edge | ||
double cameraYEdge = altitude * tan(DEG2RAD(f->get_camera().get_fov().height/2)); //meters from center of photo to edge | ||
|
||
BOOST_LOG_TRIVIAL(trace) << "X Edge: " << cameraXEdge << " Y Edge: " << cameraYEdge; | ||
|
||
//Rotation Matrix - Heading | ||
//Note: The '-heading' compensates for the fact that directional heading is | ||
//a clockwise quantity, but cos(theta) assumes theta is a counterclockwise | ||
//quantity. | ||
double realX = cos(DEG2RAD(-heading)) * biasedPoint.x/(w/2)*cameraXEdge - sin(DEG2RAD(-heading)) * biasedPoint.y/(h/2)*cameraYEdge; | ||
double realY = sin(DEG2RAD(-heading)) * biasedPoint.x/(w/2)*cameraXEdge + cos(DEG2RAD(-heading)) * biasedPoint.y/(h/2)*cameraYEdge; | ||
|
||
BOOST_LOG_TRIVIAL(trace) << "Real X: " << realX << " Real Y: " << realY; | ||
|
||
double lon = RAD2DEG(realX/EARTH_RADIUS)/cos(DEG2RAD(latitude)) + longitude; | ||
double lat = RAD2DEG(realY/EARTH_RADIUS) + latitude; | ||
|
||
BOOST_LOG_TRIVIAL(trace) << "Distance from centre: " << RAD2DEG(realY/EARTH_RADIUS) << " " << RAD2DEG(realX/EARTH_RADIUS)/cos(DEG2RAD(latitude)); | ||
|
||
BOOST_LOG_TRIVIAL(trace) << std::setprecision(10) << "Result: " << lat << " " << lon; | ||
|
||
*returnResult = cv::Point2d(lat,lon); | ||
return true; | ||
} | ||
|
||
double gps_dist(cv::Point2d p1, cv::Point2d p2) { | ||
double dLat = DEG2RAD(p2.x-p1.x); | ||
double dLon = DEG2RAD(p2.y-p1.y); | ||
|
||
double rLat1 = DEG2RAD(p1.x); | ||
double rLat2 = DEG2RAD(p2.x); | ||
|
||
double a = sin(dLat/2) * sin(dLat/2) + | ||
sin(dLon/2) * sin(dLon/2) * cos(rLat1) * cos(rLat2); | ||
double c = 2 * atan2(sqrt(a), sqrt(1-a)); | ||
return EARTH_RADIUS * c; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/** | ||
* @file gps_test.cpp | ||
* @author WARG | ||
* | ||
* @section LICENSE | ||
* | ||
* Copyright (c) 2015-2017, Waterloo Aerial Robotics Group (WARG) | ||
* All rights reserved. | ||
* | ||
* This software is licensed under a modified version of the BSD 3 clause license | ||
* that should have been included with this software in a file called COPYING.txt | ||
* Otherwise it is available at: | ||
* https://raw.githubusercontent.com/UWARG/computer-vision/master/COPYING.txt | ||
*/ | ||
|
||
#define BOOST_TEST_DYN_LINK | ||
#define BOOST_TEST_MODULE TargetAnalysis | ||
|
||
#include <boost/test/unit_test.hpp> | ||
#include <boost/log/core.hpp> | ||
#include <boost/log/trivial.hpp> | ||
#include <boost/log/expressions.hpp> | ||
#include "gps.h" | ||
|
||
using namespace std; | ||
using namespace boost; | ||
|
||
namespace logging = boost::log; | ||
|
||
void gps_check(cv::Point2d point, cv::Point2d expected, Frame *f) { | ||
cv::Point2d result; | ||
if (get_gps(point, f, &result)) { | ||
BOOST_TEST_MESSAGE("Result: " << result); | ||
BOOST_TEST_MESSAGE("Expected: " << expected); | ||
BOOST_TEST_MESSAGE("Error distance: " << gps_dist(result, expected)); | ||
BOOST_CHECK(norm(result - expected) < GPS_TOLERANCE); | ||
} else { | ||
BOOST_TEST_FAIL("get_gps returned failure"); | ||
} | ||
} | ||
|
||
BOOST_AUTO_TEST_CASE(GpsTest){ | ||
Metadata m; | ||
m.lat = 43.47181; | ||
m.lon = -80.54366; | ||
m.altitude = 100; | ||
m.heading = 0; | ||
Camera testcamera = Camera::TestCamera(); | ||
Frame f( | ||
new cv::Mat(6000, 4000, CV_32F), | ||
"test_image", | ||
m, | ||
testcamera | ||
); | ||
|
||
gps_check(cv::Point2d(3000, 2000), cv::Point2d(43.47181, -80.54366), &f); | ||
|
||
gps_check(cv::Point2d(1500, 1000), cv::Point2d(43.47158517, -80.54412471), &f); | ||
|
||
m.heading = 180; | ||
Frame f2( | ||
new cv::Mat(6000, 4000, CV_32F), | ||
"test_image", | ||
m, | ||
testcamera | ||
); | ||
gps_check(cv::Point2d(4500, 3000), cv::Point2d(43.47158517, -80.54412471), &f2); | ||
|
||
m.heading = 90; | ||
Frame f3( | ||
new cv::Mat(6000, 4000, CV_32F), | ||
"test_image", | ||
m, | ||
testcamera | ||
); | ||
gps_check(cv::Point2d(4000, 500), cv::Point2d(43.47158517, -80.54412471), &f3); | ||
} |