|
|
@ -9,7 +9,7 @@ extern "C" {
|
|
|
|
|
|
|
|
|
|
|
|
#include <SDL2/SDL.h>
|
|
|
|
#include <SDL2/SDL.h>
|
|
|
|
#include <opencv2/opencv.hpp>
|
|
|
|
#include <opencv2/opencv.hpp>
|
|
|
|
#include <opencv2/highgui/highgui.hpp>
|
|
|
|
#include <opencv2/dnn/dnn.hpp>
|
|
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdlib.h>
|
|
|
@ -29,6 +29,8 @@ struct {
|
|
|
|
int color = 0;
|
|
|
|
int color = 0;
|
|
|
|
|
|
|
|
|
|
|
|
float x = 0, y = 0, z = 0;
|
|
|
|
float x = 0, y = 0, z = 0;
|
|
|
|
|
|
|
|
int target_x = 0, target_y = 0;
|
|
|
|
|
|
|
|
int yaw_cur = 0, pitch_cur = 0;
|
|
|
|
static Uint32 drive_timer_handler(Uint32 interval, void* param) {
|
|
|
|
static Uint32 drive_timer_handler(Uint32 interval, void* param) {
|
|
|
|
robot_drive((Robot)param, x, y, z);
|
|
|
|
robot_drive((Robot)param, x, y, z);
|
|
|
|
return 75;
|
|
|
|
return 75;
|
|
|
@ -48,16 +50,34 @@ bool stop = false;
|
|
|
|
bool track = false;
|
|
|
|
bool track = false;
|
|
|
|
|
|
|
|
|
|
|
|
static void processFrameThread(Robot robot) {
|
|
|
|
static void processFrameThread(Robot robot) {
|
|
|
|
cv::HOGDescriptor hog;
|
|
|
|
cv::dnn::Net net = cv::dnn::readNet("yolov3-tiny.weights", "yolov3-tiny.cfg");
|
|
|
|
hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while(!stop) {
|
|
|
|
while(!stop) {
|
|
|
|
std::unique_lock<std::mutex> lock(mtx);
|
|
|
|
std::unique_lock<std::mutex> lock(mtx);
|
|
|
|
|
|
|
|
|
|
|
|
if(!img.empty()) {
|
|
|
|
if(!img.empty()) {
|
|
|
|
cv::Mat gray;
|
|
|
|
found.clear();
|
|
|
|
cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);
|
|
|
|
weights.clear();
|
|
|
|
hog.detectMultiScale(gray, found, weights, 0, cv::Size(), cv::Size(), 1.1);
|
|
|
|
cv::Mat blob = cv::dnn::blobFromImage(img, 1/255.0, cv::Size(416, 416), cv::Scalar(0, 0, 0), true, false);
|
|
|
|
|
|
|
|
net.setInput(blob);
|
|
|
|
|
|
|
|
std::vector<cv::Mat> outs;
|
|
|
|
|
|
|
|
net.forward(outs, net.getUnconnectedOutLayersNames());
|
|
|
|
|
|
|
|
float *data = (float*)outs[0].data;
|
|
|
|
|
|
|
|
for(int i = 0; i < outs[0].rows; ++i) {
|
|
|
|
|
|
|
|
float final_score = data[4] * data[5];
|
|
|
|
|
|
|
|
if(final_score >= 0.0075)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
weights.push_back(final_score);
|
|
|
|
|
|
|
|
int cx = data[0] * img.cols;
|
|
|
|
|
|
|
|
int cy = data[1] * img.rows;
|
|
|
|
|
|
|
|
int width = data[2] * img.cols;
|
|
|
|
|
|
|
|
int height = data[3] * img.rows;
|
|
|
|
|
|
|
|
int left = cx - width / 2;
|
|
|
|
|
|
|
|
int top = cy - height / 2;
|
|
|
|
|
|
|
|
found.push_back(cv::Rect(left, top, width, height));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
data += 85;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
target = 0;
|
|
|
|
target = 0;
|
|
|
|
for(unsigned i = 0; i < weights.size(); i++) {
|
|
|
|
for(unsigned i = 0; i < weights.size(); i++) {
|
|
|
@ -65,9 +85,9 @@ static void processFrameThread(Robot robot) {
|
|
|
|
target = i;
|
|
|
|
target = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(track) {
|
|
|
|
if(track && !weights.empty()) {
|
|
|
|
float yaw = found[target].x;
|
|
|
|
float yaw = target_x = found[target].x;
|
|
|
|
float pitch = found[target].y;
|
|
|
|
float pitch = target_y = found[target].y;
|
|
|
|
|
|
|
|
|
|
|
|
// Normalize the coordinates
|
|
|
|
// Normalize the coordinates
|
|
|
|
yaw = 2 * (yaw - img.cols / 2) / img.cols;
|
|
|
|
yaw = 2 * (yaw - img.cols / 2) / img.cols;
|
|
|
@ -192,6 +212,8 @@ static void captureFrameThread(SDL_Window* window, const char* fname) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SDL_UpdateTexture(texture, NULL, img.data, img.cols * 3);
|
|
|
|
SDL_UpdateTexture(texture, NULL, img.data, img.cols * 3);
|
|
|
|
|
|
|
|
SDL_RenderDrawLine(renderer, 1280 / 2, 720 / 2, target_x, target_y);
|
|
|
|
|
|
|
|
|
|
|
|
SDL_RenderClear(renderer);
|
|
|
|
SDL_RenderClear(renderer);
|
|
|
|
SDL_RenderCopy(renderer, texture, NULL, NULL);
|
|
|
|
SDL_RenderCopy(renderer, texture, NULL, NULL);
|
|
|
|
SDL_RenderPresent(renderer);
|
|
|
|
SDL_RenderPresent(renderer);
|
|
|
@ -246,6 +268,9 @@ int main(int argc, char* argv[]) {
|
|
|
|
std::thread *captureThread = nullptr;
|
|
|
|
std::thread *captureThread = nullptr;
|
|
|
|
std::thread *processThread = nullptr;
|
|
|
|
std::thread *processThread = nullptr;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
target_x = 720 / 2;
|
|
|
|
|
|
|
|
target_y = 1280 / 2;
|
|
|
|
|
|
|
|
|
|
|
|
while(robot_work(robot)) {
|
|
|
|
while(robot_work(robot)) {
|
|
|
|
|
|
|
|
|
|
|
|
int h = 720, w = 1280;
|
|
|
|
int h = 720, w = 1280;
|
|
|
@ -267,9 +292,11 @@ int main(int argc, char* argv[]) {
|
|
|
|
case GIMBAL_ACTION_PUSH_CMD:
|
|
|
|
case GIMBAL_ACTION_PUSH_CMD:
|
|
|
|
if(fragment.message.push.gimbalaction.state != 1)
|
|
|
|
if(fragment.message.push.gimbalaction.state != 1)
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
|
|
|
|
yaw_cur = fragment.message.push.gimbalaction.yaw;
|
|
|
|
|
|
|
|
pitch_cur = fragment.message.push.gimbalaction.pitch;
|
|
|
|
printf("Gimbal action %d\n", fragment.message.push.gimbalaction.id);
|
|
|
|
printf("Gimbal action %d\n", fragment.message.push.gimbalaction.id);
|
|
|
|
printf("\tProgress %d\n", fragment.message.push.gimbalaction.progress);
|
|
|
|
printf("\tProgress %d\n", fragment.message.push.gimbalaction.progress);
|
|
|
|
printf("\tYaw %d, Pitch %d\n", fragment.message.push.gimbalaction.yaw, fragment.message.push.gimbalaction.pitch);
|
|
|
|
printf("\tYaw %d, Pitch %d\n", yaw_cur, pitch_cur);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case GIMBAL_ROTATE_CMD:
|
|
|
|
case GIMBAL_ROTATE_CMD:
|
|
|
|
if(fragment.message.resp.gimbalrot.retcode) {
|
|
|
|
if(fragment.message.resp.gimbalrot.retcode) {
|
|
|
@ -308,7 +335,6 @@ int main(int argc, char* argv[]) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::unique_lock<std::mutex> lock(mtx);
|
|
|
|
|
|
|
|
SDL_Event event;
|
|
|
|
SDL_Event event;
|
|
|
|
while(SDL_PollEvent(&event)) {
|
|
|
|
while(SDL_PollEvent(&event)) {
|
|
|
|
switch(event.type) {
|
|
|
|
switch(event.type) {
|
|
|
@ -353,7 +379,6 @@ int main(int argc, char* argv[]) {
|
|
|
|
case SDL_MOUSEBUTTONDOWN:
|
|
|
|
case SDL_MOUSEBUTTONDOWN:
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// Get window coordinates
|
|
|
|
// Get window coordinates
|
|
|
|
int target_x = 0, target_y = 0;
|
|
|
|
|
|
|
|
SDL_GetMouseState(&target_x, &target_y);
|
|
|
|
SDL_GetMouseState(&target_x, &target_y);
|
|
|
|
|
|
|
|
|
|
|
|
float yaw = target_x;
|
|
|
|
float yaw = target_x;
|
|
|
@ -375,7 +400,6 @@ int main(int argc, char* argv[]) {
|
|
|
|
default: break;
|
|
|
|
default: break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
lock.unlock();
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(captureThread != nullptr) {
|
|
|
|
if(captureThread != nullptr) {
|
|
|
|