Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plane 260: Fix flipping #51

Merged
merged 9 commits into from
Dec 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,4 @@ Flask App: ![Alt](/res/flaskapp.png "Flask App Screenshot")

Information for how data is sent to and from the Orin on NetworkTables is stored on the following Google Doc <a> https://docs.google.com/document/d/1zhl0dlSLXOld302rhOQrhItLp2thuDD308Gv3yvkHMY/edit?usp=sharing</a>

If you are an M-A Student looking for access to the build server, please fill out the form <a> https://docs.google.com/document/d/14MWXYbr9kazaDxuQmgdHVRad1crJv6h6GJaEA4p0HTE/edit?usp=sharing </a>
15 changes: 11 additions & 4 deletions app/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,12 @@ <h1>AprilTag Detection with Controls and Pose Data</h1>
<button id="incrementExposureDown"> -3 Exposure </button>
</div>
<div class="control">
<input type="checkbox" id="rotate-image" name="rotate-image">
<label for="rotate-image">Rotate Image</label>
<input type="checkbox" id="rotate-image-vertically" name="rotate-image-vertically">
<label for="rotate-image-vertically">Rotate Image (CHECK BOTH BOXES) </label>
</div>
<div class="control">
<input type="checkbox" id="rotate-image-horizontally" name="rotate-image-horizontally">
<label for="rotate-image-horizontally">Rotate Image (CHECK BOTH BOXES) </label>
</div>

</div>
Expand Down Expand Up @@ -212,8 +216,11 @@ <h2>Pose Data:</h2>
};
});

document.getElementById('rotate-image').onchange = function() {
sendControl('rotate', this.checked);
document.getElementById('rotate-image-vertically').onchange = function() {
sendControl('flipVertical', this.checked);
};
document.getElementById('rotate-image-horizontally').onchange = function() {
sendControl('flipHorizontal', this.checked);
};

// Initial state
Expand Down
59 changes: 39 additions & 20 deletions src/ws_server.cu
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@ using json = nlohmann::json;

DEFINE_int32(camera_idx, 0, "Camera index");
DEFINE_string(cal_file, "", "path name to calibration file");
DEFINE_bool(rotate_img, true,
DEFINE_bool(rotate_vertical, false,
"Rotates image by 180 degrees prior to detecting apriltags");
DEFINE_bool(rotate_horizontal, false,
"Rotates image by 90 degrees prior to detecting apriltags");

enum ExposureMode { AUTO = 0, MANUAL = 1 };

Expand Down Expand Up @@ -78,8 +80,12 @@ class AprilTagHandler : public seasocks::WebSocket::Handler {
exposure_mode_ = j["value"].get<int>();
settings_changed_ = true;
}
if (j["type"] == "rotate") {
gui_rotate_img_ = j["value"].get<bool>();
if (j["type"] == "flipVertical") {
flipVertical_ = j["value"].get<bool>();
settings_changed_ = true;
}
if(j["type"] == "flipHorizontal"){
flipHorizontal_ = j["value"].get<bool>();
settings_changed_ = true;
}

Expand Down Expand Up @@ -165,20 +171,20 @@ class AprilTagHandler : public seasocks::WebSocket::Handler {

return true;
}

// TODO: Implement a faster version of this method!
void rotateImage(cv::Mat* bgr_img, const float angle) {
cv::Point2f center((bgr_img->cols - 1) / 2.0, (bgr_img->rows - 1) / 2.0);
cv::Mat matRotation = cv::getRotationMatrix2D(center, angle, 1.0);
cv::Mat rotatedImage;
cv::warpAffine(*bgr_img, rotatedImage, matRotation, bgr_img->size());
*bgr_img = rotatedImage.clone();
//Flipcode -1 = both directions
void flipVertical(const cv::Mat& bgr_img, cv::Mat* output_img){
cv::flip(bgr_img, *output_img, 0);
}
void flipHorizontal(const cv::Mat& bgr_img, cv::Mat* output_img){
cv::flip(bgr_img, *output_img, 1);
}
void flipBoth(const cv::Mat& bgr_img, cv::Mat* output_img){
cv::flip(bgr_img, *output_img, -1);
}

void startReadAndSendThread(const int camera_idx, const std::string& cal_file,
const bool rotate_img) {
const bool rotate_vertical, const bool rotate_horizontal) {
read_thread_ = std::thread(&AprilTagHandler::readAndSend, this, camera_idx,
cal_file, rotate_img);
cal_file, rotate_vertical, rotate_horizontal);
}

void joinReadAndSendThread() {
Expand All @@ -205,7 +211,7 @@ class AprilTagHandler : public seasocks::WebSocket::Handler {
}

void readAndSend(const int camera_idx, const std::string& cal_file,
const bool rotate_img) {
const bool rotate_vertical, const bool rotate_horizontal) {
std::cout << "Enabling video capture" << std::endl;
bool camera_started = false;
cv::VideoCapture cap;
Expand Down Expand Up @@ -286,7 +292,8 @@ class AprilTagHandler : public seasocks::WebSocket::Handler {
// Set the value of the gui rotate image variable to the value
// that is passed in on the command line. The user can change it
// later on from the gui.
gui_rotate_img_ = rotate_img;
flipVertical_ = rotate_vertical;
flipHorizontal_ = rotate_horizontal;

int frame_counter = 0;
cv::Mat bgr_img, yuyv_img;
Expand All @@ -310,9 +317,20 @@ class AprilTagHandler : public seasocks::WebSocket::Handler {
frame_counter++;

auto overallstart = std::chrono::high_resolution_clock::now();
if (gui_rotate_img_) {
rotateImage(&bgr_img, 180.0);
//Let's check the time this takes, can always combine to one call if both are true later.
//Best case scenario is we don't place the camera wrong so we do not need this method at all.
if(flipVertical_ && flipHorizontal_){
flipBoth(bgr_img.clone(), &bgr_img);
} else {
// if (flipVertical_) {
// flipVertical(bgr_img.clone(), &bgr_img);
// }
// if (flipHorizontal_) {
// flipHorizontal(bgr_img.clone(), &bgr_img);
// }
}


cv::cvtColor(bgr_img, yuyv_img, cv::COLOR_BGR2YUV_YUYV);
auto gpudetectstart = std::chrono::high_resolution_clock::now();
detector.Detect(yuyv_img.data);
Expand Down Expand Up @@ -422,7 +440,8 @@ class AprilTagHandler : public seasocks::WebSocket::Handler {
std::atomic<int> exposure_{50};
std::atomic<int> exposure_mode_{0};
std::atomic<bool> settings_changed_{false};
std::atomic<bool> gui_rotate_img_{false};
std::atomic<bool> flipVertical_{false};
std::atomic<bool> flipHorizontal_{false};
std::thread read_thread_;
};

Expand Down Expand Up @@ -452,7 +471,7 @@ int main(int argc, char* argv[]) {

handler
->startReadAndSendThread(FLAGS_camera_idx, FLAGS_cal_file,
FLAGS_rotate_img);
FLAGS_rotate_vertical, FLAGS_rotate_horizontal);
server->serve("", 8080);
handler->stop();
handler->joinReadAndSendThread();
Expand Down
Loading