Skip to content

Commit

Permalink
Removed CameraParams/Configs, refactoring WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
imisaacwu committed Oct 22, 2024
1 parent 5f7b063 commit 438e62b
Show file tree
Hide file tree
Showing 12 changed files with 81 additions and 813 deletions.
6 changes: 2 additions & 4 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,6 @@ endif()

add_library(camera SHARED
camera/Camera.cpp
camera/CameraParams.cpp
camera/CameraConfig.cpp
)
target_link_libraries(camera PUBLIC ${OpenCV_LIBS})

Expand Down Expand Up @@ -309,8 +307,8 @@ if(WITH_TESTS)
add_executable(tests
Tests.cpp
# AR Detection tests

This comment has been minimized.

Copy link
@imisaacwu

imisaacwu Oct 22, 2024

Author Contributor

Figure out the proper way to disable ar/ or overhaul entirely

ar/DetectorTests.cpp
ar/MarkerSetTests.cpp
# ar/DetectorTests.cpp
# ar/MarkerSetTests.cpp
# Camera tests
../tests/camera/CameraParamsTests.cpp
# GPS tests
Expand Down
45 changes: 7 additions & 38 deletions src/ar/ARTester.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
#include "../camera/Camera.h"
#include "../camera/CameraConfig.h"
#include "../camera/CameraParams.h"
#include "Detector.h"

#include <chrono>
Expand Down Expand Up @@ -36,7 +34,6 @@ const std::string keys =
// TODO: come up with a better solution for examining video files
// cam::Camera cap;
cv::VideoCapture cap;
cam::CameraParams PARAMS;
std::shared_ptr<AR::MarkerSet> MARKER_SET;

std::vector<cv::Point2d> projectCube(float len, cv::Vec3d rvec, cv::Vec3d tvec);
Expand All @@ -56,8 +53,8 @@ int main(int argc, char* argv[]) {
return EXIT_SUCCESS;
}

if (!parser.has("c") || parser.get<std::string>("c").empty()) {
std::cerr << "Error: camera configuration file is required." << std::endl;
if (!parser.has("co")) {
std:cerr << "Error: camera ID required." << std::endl;
parser.printMessage();
return EXIT_FAILURE;
}
Expand All @@ -78,35 +75,6 @@ int main(int argc, char* argv[]) {
}

int cam_id = parser.get<int>("co", -1);
std::string cam_file = parser.get<std::string>("fo");
cv::FileStorage cam_config(parser.get<std::string>("c"), cv::FileStorage::READ);
if (!cam_config.isOpened()) {
std::cerr << "Error: given camera configuration file " << parser.get<std::string>("c")
<< " does not exist!" << std::endl;
cam_config.release();
return EXIT_FAILURE;
}
if (cam_config[cam::KEY_INTRINSIC_PARAMS].empty()) {
std::cerr << "Error: Intrinsic parameters are required for AR tag detection!"
<< std::endl;
cam_config.release();
return EXIT_FAILURE;
}
cam_config[cam::KEY_INTRINSIC_PARAMS] >> PARAMS;
// read filename or camera ID, and open camera.
if (!cam_config[cam::KEY_FILENAME].empty() && !parser.has("fo")) {
cam_file = (std::string)cam_config[cam::KEY_FILENAME];
} else if (!cam_config[cam::KEY_CAMERA_ID].empty() && !parser.has("co")) {
cam_id = (int)cam_config[cam::KEY_CAMERA_ID];
} else if (!parser.has("fo") && !parser.has("co")) {
std::cerr << "Error: no file or camera_id was provided in the configuration file or "
"on the command line!"
<< std::endl;
std::cerr << "Usage:" << std::endl;
parser.printMessage();
return EXIT_FAILURE;
}
cam_config.release();

cv::Mat frame;
[[maybe_unused]] uint32_t fnum = 0;
Expand All @@ -115,17 +83,18 @@ int main(int argc, char* argv[]) {
bool open_success = false;
if (cam_id > -1) {
open_success = cap.open(cam_id);
} else if (!cam_file.empty()) {
open_success = cap.open(cam_file);
} else {
std::cerr << "Error: invalid camera ID" << std::endl;
return EXIT_FAILURE;
}

if (!open_success) {
std::cerr << "ERROR! Unable to open camera" << std::endl;
return EXIT_FAILURE;
}

const int w = PARAMS.getImageSize().width;
const int h = PARAMS.getImageSize().height;
const int w = cap.getWidth();
const int h = cap.getHeight();
cap.set(cv::CAP_PROP_FRAME_WIDTH, w);
cap.set(cv::CAP_PROP_FRAME_HEIGHT, h);
std::cout << "Set image dimensions to " << w << " x " << h << std::endl;
Expand Down
2 changes: 0 additions & 2 deletions src/ar/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ find_package(Threads REQUIRED)

add_executable(ar_tester
ARTester.cpp
../camera/CameraParams.cpp
../camera/Camera.cpp
../camera/CameraConfig.cpp
Detector.cpp
MarkerSet.cpp
MarkerPattern.cpp
Expand Down
5 changes: 2 additions & 3 deletions src/ar/Detector.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include "Detector.h"

#include "../camera/CameraParams.h"
#include "Tag.h"

#include <cassert>
Expand All @@ -17,9 +16,9 @@ namespace AR {
Detector::Detector() {
}

Detector::Detector(std::shared_ptr<MarkerSet> marker_set, cam::CameraParams camera_params,
Detector::Detector(std::shared_ptr<MarkerSet> marker_set,
cv::Ptr<cv::aruco::DetectorParameters> detector_params)
: marker_set_(marker_set), camera_params_(camera_params),
: marker_set_(marker_set),
detector_params_(detector_params) {
if (!this->empty()) {
this->detector_params_->markerBorderBits = marker_set->getBorderSize();
Expand Down
4 changes: 1 addition & 3 deletions src/ar/Detector.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#pragma once

#include "../camera/CameraParams.h"
#include "MarkerSet.h"
#include "Tag.h"

Expand All @@ -19,7 +18,6 @@ namespace AR {
class Detector {
private:
std::shared_ptr<MarkerSet> marker_set_;
cam::CameraParams camera_params_;
cv::Ptr<cv::aruco::DetectorParameters> detector_params_;
cv::Mat map1_, map2_;
std::vector<Tag> _detectTagsImpl(const cv::Mat& input,
Expand All @@ -28,7 +26,7 @@ class Detector {

public:
Detector();
Detector(std::shared_ptr<MarkerSet> marker_set, cam::CameraParams camera_params,
Detector(std::shared_ptr<MarkerSet> marker_set,
cv::Ptr<cv::aruco::DetectorParameters> detector_params =
cv::aruco::DetectorParameters::create());
std::vector<Tag> detectTags(const cv::Mat& input,
Expand Down
137 changes: 46 additions & 91 deletions src/camera/Camera.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#include "Camera.h"
#include "../Constants.h"

#include "CameraConfig.h"

#include <loguru.hpp>

#include <opencv2/aruco.hpp>
Expand All @@ -21,7 +19,23 @@ Camera::Camera()
_frame_lock(std::make_shared<std::mutex>()),
_capture_lock(std::make_shared<std::mutex>()), _running(std::make_shared<bool>(false)) {}

bool Camera::open(int camera_id, CameraParams intrinsic_params, Mat extrinsic_params) {
Camera::Camera(robot::types::CameraID camera_id)
: _frame(std::make_shared<cv::Mat>()), _frame_num(std::make_shared<uint32_t>(0)),
_frame_time(std::make_shared<datatime_t>()),
_capture(std::make_shared<cv::VideoCapture>(camera_id)),
_frame_lock(std::make_shared<std::mutex>()),
_capture_lock(std::make_shared<std::mutex>()),
_running(std::make_shared<bool>(false)) {
open(camera_id);
}

Camera::Camera(const Camera& other)
: _frame(other._frame), _frame_num(other._frame_num), _frame_time(other._frame_time),
_capture(other._capture), _name(other._name), _description(other._description),
_frame_lock(other._frame_lock), _capture_lock(other._capture_lock),
_thread(other._thread), _running(other._running) {}

bool Camera::open(robot::types::CameraID camera_id) {
if (*_running) {
return false;
}
Expand All @@ -31,38 +45,11 @@ bool Camera::open(int camera_id, CameraParams intrinsic_params, Mat extrinsic_pa
bool result = this->_capture->isOpened();
_capture_lock->unlock();
LOG_F(INFO, "Opening camera %d... %s", camera_id, result ? "success" : "failed");
this->_intrinsic_params = intrinsic_params;
init(extrinsic_params);
init();
return result;
}

Camera::Camera(string filename, string name, string description, CameraParams intrinsic_params,
Mat extrinsic_params)
: _frame(std::make_shared<cv::Mat>()), _frame_num(std::make_shared<uint32_t>(0)),
_frame_time(std::make_shared<datatime_t>()),
_capture(std::make_shared<cv::VideoCapture>(filename)), _name(name),
_description(description), _frame_lock(std::make_shared<std::mutex>()),
_capture_lock(std::make_shared<std::mutex>()), _intrinsic_params(intrinsic_params),
_running(std::make_shared<bool>(false)) {
init(extrinsic_params);
}

Camera::Camera(int camera_id, string name, string description, CameraParams intrinsic_params,
Mat extrinsic_params)
: _frame(std::make_shared<cv::Mat>()), _frame_num(std::make_shared<uint32_t>(0)),
_frame_time(std::make_shared<datatime_t>()),
_capture(std::make_shared<cv::VideoCapture>(camera_id)), _name(name),
_description(description), _frame_lock(std::make_shared<std::mutex>()),
_capture_lock(std::make_shared<std::mutex>()), _intrinsic_params(intrinsic_params),
_running(std::make_shared<bool>(false)) {
init(extrinsic_params);
}

void Camera::init(const Mat& extrinsic_params) {
if (!extrinsic_params.empty() && extrinsic_params.size() != Size(4, 4)) {
throw std::invalid_argument("extrinsic_params must be 4x4 if given");
}
extrinsic_params.copyTo(this->_extrinsic_params);
void Camera::init() {
*(this->_running) = true;
this->_thread = std::shared_ptr<std::thread>(
new std::thread(&Camera::captureLoop, this), [this](std::thread* p) {
Expand All @@ -75,37 +62,6 @@ void Camera::init(const Mat& extrinsic_params) {
});
}

Camera::Camera(const Camera& other)
: _frame(other._frame), _frame_num(other._frame_num), _frame_time(other._frame_time),
_capture(other._capture), _name(other._name), _description(other._description),
_frame_lock(other._frame_lock), _capture_lock(other._capture_lock),
_thread(other._thread), _intrinsic_params(other._intrinsic_params),
_extrinsic_params(other._extrinsic_params), _running(other._running) {}

bool Camera::openFromConfigFile(std::string filename) {
CameraConfig cfg = readConfigFromFile(filename);

cv::Mat extrinsics;
if (cfg.extrinsicParams) {
extrinsics = cfg.extrinsicParams.value();
}

CameraParams intrinsics;
if (cfg.intrinsicParams) {
intrinsics = cfg.intrinsicParams.value();
}

if (std::holds_alternative<std::string>(cfg.filenameOrID)) {
// return this->open(std::get<std::string>(cfg.filenameOrID), intrinsics, extrinsics);
} else if (std::holds_alternative<int>(cfg.filenameOrID)) {
return this->open(std::get<int>(cfg.filenameOrID), intrinsics, extrinsics);
} else {
// this should never happen
throw invalid_camera_config("One of " + KEY_FILENAME + " or " + KEY_CAMERA_ID +
" must be present");
}
}

std::stringstream Camera::GStreamerFromFile(robot::types::CameraID camera_id) {
cv::FileStorage fs(Constants::CAMERA_CONFIG_PATHS.at(camera_id), cv::FileStorage::READ);
if (!fs.isOpened()) {
Expand All @@ -123,9 +79,14 @@ std::stringstream Camera::GStreamerFromFile(robot::types::CameraID camera_id) {
const std::string KEY_HEIGHT = "height";
const std::string KEY_FRAMERATE = "framerate";

_name = fs[KEY_NAME].operator std::string();
_description = fs[KEY_DESCRIPTION].operator std::string();
_width = fs[KEY_WIDTH].operator int();
_height = fs[KEY_HEIGHT].operator int();

gstr_ss << "image/" << fs[KEY_FORMAT].operator std::string();
gstr_ss << ",width=" << fs[KEY_WIDTH].operator std::string();
gstr_ss << ",height=" << fs[KEY_HEIGHT].operator std::string();
gstr_ss << ",width=" << _width;
gstr_ss << ",height=" << _height;
gstr_ss << ",framerate=" << fs[KEY_FRAMERATE].operator std::string() << "/1";
gstr_ss << " ! " << fs[KEY_FORMAT].operator std::string() << "dec ! videoconvert";

Expand All @@ -137,23 +98,25 @@ std::stringstream Camera::GStreamerFromFile(robot::types::CameraID camera_id) {

void Camera::captureLoop() {
loguru::set_thread_name(_name.c_str());
cv::Size image_size(640, 480);
if (!_intrinsic_params.empty()) {
image_size = _intrinsic_params.getImageSize();
}
_capture_lock->lock();
_capture->set(cv::CAP_PROP_FOURCC, cv::VideoWriter::fourcc('M', 'J', 'P', 'G'));
_capture->set(cv::CAP_PROP_FRAME_WIDTH, image_size.width);
_capture->set(cv::CAP_PROP_FRAME_HEIGHT, image_size.height);
_capture_lock->unlock();
cv::Mat frame;
while (*_running) {
_capture_lock->lock();
bool success = _capture->read(frame);
_capture_lock->unlock();
if (success && !frame.empty()) {
// Aruco detection here:
cv::Ptr<cv::aruco::Dictionary> dictionary =
cv::aruco::getPredefinedDictionary(cv::aruco::DICT_4X4_100);
std::vector<std::vector<cv::Point2f>> markerCorners;
cv::Mat frameCopy;
std::vector<int> markerIds;
cv::aruco::detectMarkers(frame, dictionary, markerCorners, markerIds);
frame.copyTo(frameCopy);
if (!markerIds.empty()) {
cv::aruco::drawDetectedMarkers(frameCopy, markerCorners, markerIds);
}
_frame_lock->lock();
frame.copyTo(*(this->_frame));
frameCopy.copyTo(*(this->_frame));
(*_frame_num)++;
*_frame_time = dataclock::now();
_frame_lock->unlock();
Expand Down Expand Up @@ -196,22 +159,6 @@ bool Camera::next(cv::Mat& frame, uint32_t& frame_num, datatime_t& frame_time) c
return true;
}

bool Camera::hasIntrinsicParams() const {
return !(_intrinsic_params.empty());
}

bool Camera::hasExtrinsicParams() const {
return !(_extrinsic_params.empty());
}

CameraParams Camera::getIntrinsicParams() const {
return _intrinsic_params;
}

cv::Mat Camera::getExtrinsicParams() const {
return _extrinsic_params.clone();
}

std::string Camera::getName() const {
return _name;
}
Expand All @@ -220,6 +167,14 @@ std::string Camera::getDescription() const {
return _description;
}

int Camera::getWidth() const {
return _width;
}

int Camera::getHeight() const {
return _height;
}

void Camera::setName(std::string new_name) {
this->_name = new_name;
}
Expand Down
Loading

1 comment on commit 438e62b

@imisaacwu
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check aruco detection comment (overhaul ar/ or remove Camera)
Make sure initialization of cameras is consistent with changed configs in world/simulator interface

Please sign in to comment.