Skip to content

Commit

Permalink
Merge pull request leggedrobotics#308 from leggedrobotics/noetic
Browse files Browse the repository at this point in the history
Noetic
  • Loading branch information
mbjelonic authored Apr 8, 2021
2 parents b9d9a7d + d8514fb commit 895a0fb
Show file tree
Hide file tree
Showing 9 changed files with 47 additions and 46 deletions.
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[submodule "darknet"]
path = darknet
url = https://github.com/pjreddie/darknet
url = https://github.com/leggedrobotics/darknet
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

## Overview

This is a ROS package developed for object detection in camera images. You only look once (YOLO) is a state-of-the-art, real-time object detection system. In the following ROS package you are able to use YOLO (V3) on GPU and CPU. The pre-trained model of the convolutional neural network is able to detect pre-trained classes including the data set from VOC and COCO, or you can also create a network with your own detection objects. For more information about YOLO, Darknet, available training data and training YOLO see the following link: [YOLO: Real-Time Object Detection](http://pjreddie.com/darknet/yolo/).
This is a ROS package developed for **object detection in camera images**. You only look once (YOLO) is a state-of-the-art, real-time object detection system. In the following ROS package you are able to use **YOLO (V3) on GPU and CPU**. The pre-trained model of the convolutional neural network is able to detect pre-trained classes including the data set from VOC and COCO, or you can also create a network with your own detection objects. For more information about YOLO, Darknet, available training data and training YOLO see the following link: [YOLO: Real-Time Object Detection](http://pjreddie.com/darknet/yolo/).

The YOLO packages have been tested under ROS Melodic and Ubuntu 18.04. This is research code, expect that it changes often and any fitness for a particular purpose is disclaimed.
The YOLO packages have been tested under **ROS Noetic** and **Ubuntu 20.04**. Note: We also provide branches that work under **ROS Melodic**, **ROS Foxy** and **ROS2**.

This is research code, expect that it changes often and any fitness for a particular purpose is disclaimed.

**Author: [Marko Bjelonic](https://www.markobjelonic.com), [email protected]**

Expand Down
2 changes: 1 addition & 1 deletion darknet
Submodule darknet updated 68 files
+9 −5 Makefile
+37 −0 README.md
+5 −4 cfg/alexnet.cfg
+0 −3 cfg/cifar.cfg
+0 −2 cfg/cifar.test.cfg
+2 −2 cfg/coco.data
+20 −11 cfg/darknet.cfg
+0 −3 cfg/darknet19.cfg
+0 −3 cfg/darknet19_448.cfg
+566 −0 cfg/darknet53.cfg
+559 −0 cfg/darknet53_448.cfg
+0 −3 cfg/densenet201.cfg
+7 −4 cfg/extraction.cfg
+0 −3 cfg/extraction22k.cfg
+0 −3 cfg/go.cfg
+0 −2 cfg/go.test.cfg
+6 −9 cfg/gru.cfg
+8 −0 cfg/openimages.data
+990 −0 cfg/resnet101.cfg
+0 −3 cfg/resnet152.cfg
+228 −0 cfg/resnet18.cfg
+392 −0 cfg/resnet34.cfg
+7 −8 cfg/resnet50.cfg
+1,053 −0 cfg/resnext101-32x4d.cfg
+1,562 −0 cfg/resnext152-32x4d.cfg
+523 −0 cfg/resnext50.cfg
+0 −2 cfg/rnn.cfg
+0 −2 cfg/rnn.train.cfg
+0 −3 cfg/strided.cfg
+0 −2 cfg/tiny.cfg
+8 −4 cfg/vgg-16.cfg
+2 −2 cfg/yolov2.cfg
+789 −0 cfg/yolov3-openimages.cfg
+822 −0 cfg/yolov3-spp.cfg
+182 −0 cfg/yolov3-tiny.cfg
+9 −9 cfg/yolov3.cfg
+601 −0 data/openimages.names
+2 −7 examples/art.c
+2 −2 examples/cifar.c
+47 −40 examples/classifier.c
+1 −5 examples/coco.c
+3 −6 examples/darknet.c
+2 −7 examples/detector.c
+267 −0 examples/instance-segmenter.c
+10 −23 examples/lsd.c
+2 −6 examples/nightmare.c
+2 −12 examples/regressor.c
+11 −28 examples/segmenter.c
+1 −1 examples/super.c
+1 −5 examples/yolo.c
+26 −21 include/darknet.h
+6 −0 src/activation_kernels.cu
+7 −0 src/activations.c
+2 −0 src/activations.h
+17 −9 src/convolutional_kernels.cu
+25 −11 src/convolutional_layer.c
+89 −7 src/data.c
+11 −26 src/demo.c
+28 −177 src/image.c
+12 −7 src/image.h
+119 −0 src/image_opencv.cpp
+225 −0 src/iseg_layer.c
+19 −0 src/iseg_layer.h
+6 −6 src/maxpool_layer.c
+8 −8 src/maxpool_layer_kernels.cu
+27 −11 src/parser.c
+2 −2 src/softmax_layer.c
+1 −1 src/yolo_layer.c
9 changes: 5 additions & 4 deletions darknet_ros/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
cmake_minimum_required(VERSION 2.8.12)
cmake_minimum_required(VERSION 3.5.1)
project(darknet_ros)

# Set c++11 cmake flags
set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_C_FLAGS "-Wall -Wno-unused-result -Wno-unknown-pragmas -Wno-unused-variable -Wfatal-errors -fPIC ${CMAKE_C_FLAGS}")
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

Expand Down Expand Up @@ -92,7 +92,7 @@ include_directories(
)

set(PROJECT_LIB_FILES
src/YoloObjectDetector.cpp src/image_interface.c
src/YoloObjectDetector.cpp src/image_interface.cpp
)

set(DARKNET_CORE_FILES
Expand All @@ -118,9 +118,10 @@ set(DARKNET_CORE_FILES
${DARKNET_PATH}/src/gru_layer.c ${DARKNET_PATH}/src/utils.c
${DARKNET_PATH}/src/upsample_layer.c ${DARKNET_PATH}/src/logistic_layer.c
${DARKNET_PATH}/src/l2norm_layer.c ${DARKNET_PATH}/src/yolo_layer.c
${DARKNET_PATH}/src/iseg_layer.c ${DARKNET_PATH}/src/image_opencv.cpp

${DARKNET_PATH}/examples/art.c ${DARKNET_PATH}/examples/lsd.c
${DARKNET_PATH}/examples/attention.c ${DARKNET_PATH}/examples/nightmare.c
${DARKNET_PATH}/examples/nightmare.c ${DARKNET_PATH}/examples/instance-segmenter.c
${DARKNET_PATH}/examples/captcha.c ${DARKNET_PATH}/examples/regressor.c
${DARKNET_PATH}/examples/cifar.c ${DARKNET_PATH}/examples/rnn.c
${DARKNET_PATH}/examples/classifier.c ${DARKNET_PATH}/examples/segmenter.c
Expand Down
19 changes: 10 additions & 9 deletions darknet_ros/include/darknet_ros/YoloObjectDetector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,19 @@ extern "C" {
#include <sys/time.h>
#include "box.h"
#include "cost_layer.h"
#include "darknet_ros/image_interface.h"
#include "detection_layer.h"
#include "network.h"
#include "parser.h"
#include "region_layer.h"
#include "utils.h"
}

extern "C" void ipl_into_image(IplImage* src, image im);
extern "C" image ipl_to_image(IplImage* src);
extern "C" void show_image_cv(image p, const char* name, IplImage* disp);
// Image interface.
#include "darknet_ros/image_interface.hpp"

extern "C" cv::Mat image_to_mat(image im);
extern "C" image mat_to_image(cv::Mat m);
extern "C" int show_image(image p, const char* name, int ms);

namespace darknet_ros {

Expand All @@ -70,9 +72,9 @@ typedef struct {
} RosBox_;

typedef struct {
IplImage* image;
cv::Mat image;
std_msgs::Header header;
} IplImageWithHeader_;
} CvMatWithHeader_;

class YoloObjectDetector {
public:
Expand Down Expand Up @@ -174,12 +176,11 @@ class YoloObjectDetector {
image buffLetter_[3];
int buffId_[3];
int buffIndex_ = 0;
IplImage* ipl_;
float fps_ = 0;
float demoThresh_ = 0;
float demoHier_ = .5;
int running_ = 0;

cv::Mat disp_;
int demoDelay_ = 0;
int demoFrame_ = 3;
float** predictions_;
Expand Down Expand Up @@ -234,7 +235,7 @@ class YoloObjectDetector {

void yolo();

IplImageWithHeader_ getIplImageWithHeader();
CvMatWithHeader_ getCvMatWithHeader();

bool getImageStatus(void);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@
#define IMAGE_INTERFACE_H

#include "image.h"
#include "opencv2/opencv.hpp"

static float get_pixel(image m, int x, int y, int c);
image** load_alphabet_with_file(char* datafile);
void generate_image(image p, IplImage* disp);
void generate_image(image p, cv::Mat& disp);

#endif
35 changes: 15 additions & 20 deletions darknet_ros/src/YoloObjectDetector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,9 +368,8 @@ void* YoloObjectDetector::detectInThread() {
void* YoloObjectDetector::fetchInThread() {
{
boost::shared_lock<boost::shared_mutex> lock(mutexImageCallback_);
IplImageWithHeader_ imageAndHeader = getIplImageWithHeader();
IplImage* ROS_img = imageAndHeader.image;
ipl_into_image(ROS_img, buff_[buffIndex_]);
CvMatWithHeader_ imageAndHeader = getCvMatWithHeader();
buff_[buffIndex_] = mat_to_image(imageAndHeader.image);
headerBuff_[buffIndex_] = imageAndHeader.header;
buffId_[buffIndex_] = actionId_;
}
Expand All @@ -380,8 +379,7 @@ void* YoloObjectDetector::fetchInThread() {
}

void* YoloObjectDetector::displayInThread(void* ptr) {
show_image_cv(buff_[(buffIndex_ + 1) % 3], "YOLO V3", ipl_);
int c = cv::waitKey(waitKeyDelay_);
int c = show_image(buff_[(buffIndex_ + 1) % 3], "YOLO", 1);
if (c != -1) c = c % 256;
if (c == 27) {
demoDone_ = 1;
Expand Down Expand Up @@ -424,7 +422,7 @@ void YoloObjectDetector::setupNetwork(char* cfgfile, char* weightfile, char* dat
demoThresh_ = thresh;
demoHier_ = hier;
fullScreen_ = fullscreen;
printf("YOLO V3\n");
printf("YOLO\n");
net_ = load_network(cfgfile, weightfile, 0);
set_batch_network(net_, 1);
}
Expand Down Expand Up @@ -457,9 +455,8 @@ void YoloObjectDetector::yolo() {

{
boost::shared_lock<boost::shared_mutex> lock(mutexImageCallback_);
IplImageWithHeader_ imageAndHeader = getIplImageWithHeader();
IplImage* ROS_img = imageAndHeader.image;
buff_[0] = ipl_to_image(ROS_img);
CvMatWithHeader_ imageAndHeader = getCvMatWithHeader();
buff_[0] = mat_to_image(imageAndHeader.image);
headerBuff_[0] = imageAndHeader.header;
}
buff_[1] = copy_image(buff_[0]);
Expand All @@ -469,17 +466,16 @@ void YoloObjectDetector::yolo() {
buffLetter_[0] = letterbox_image(buff_[0], net_->w, net_->h);
buffLetter_[1] = letterbox_image(buff_[0], net_->w, net_->h);
buffLetter_[2] = letterbox_image(buff_[0], net_->w, net_->h);
ipl_ = cvCreateImage(cvSize(buff_[0].w, buff_[0].h), IPL_DEPTH_8U, buff_[0].c);
disp_ = image_to_mat(buff_[0]);

int count = 0;

if (!demoPrefix_ && viewImage_) {
cv::namedWindow("YOLO V3", cv::WINDOW_NORMAL);
cv::namedWindow("YOLO", cv::WINDOW_NORMAL);
if (fullScreen_) {
cv::setWindowProperty("YOLO V3", cv::WND_PROP_FULLSCREEN, cv::WINDOW_FULLSCREEN);
cv::setWindowProperty("YOLO", cv::WND_PROP_FULLSCREEN, cv::WINDOW_FULLSCREEN);
} else {
cv::moveWindow("YOLO V3", 0, 0);
cv::resizeWindow("YOLO V3", 640, 480);
cv::moveWindow("YOLO", 0, 0);
cv::resizeWindow("YOLO", 640, 480);
}
}

Expand All @@ -495,7 +491,7 @@ void YoloObjectDetector::yolo() {
if (viewImage_) {
displayInThread(0);
} else {
generate_image(buff_[(buffIndex_ + 1) % 3], ipl_);
generate_image(buff_[(buffIndex_ + 1) % 3], disp_);
}
publishInThread();
} else {
Expand All @@ -512,9 +508,8 @@ void YoloObjectDetector::yolo() {
}
}

IplImageWithHeader_ YoloObjectDetector::getIplImageWithHeader() {
IplImage* ROS_img = new IplImage(camImageCopy_);
IplImageWithHeader_ header = {.image = ROS_img, .header = imageHeader_};
CvMatWithHeader_ YoloObjectDetector::getCvMatWithHeader() {
CvMatWithHeader_ header = {.image = camImageCopy_, .header = imageHeader_};
return header;
}

Expand All @@ -530,7 +525,7 @@ bool YoloObjectDetector::isNodeRunning(void) {

void* YoloObjectDetector::publishInThread() {
// Publish image.
cv::Mat cvImage = cv::cvarrToMat(ipl_);
cv::Mat cvImage = disp_;
if (!publishDetectionImage(cv::Mat(cvImage))) {
ROS_DEBUG("Detection image has not been broadcasted.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Institute: ETH Zurich, Robotic Systems Lab
*/

#include "darknet_ros/image_interface.h"
#include "darknet_ros/image_interface.hpp"

static float get_pixel(image m, int x, int y, int c) {
assert(x < m.w && y < m.h && c < m.c);
Expand All @@ -16,13 +16,13 @@ static float get_pixel(image m, int x, int y, int c) {
image** load_alphabet_with_file(char* datafile) {
int i, j;
const int nsize = 8;
image** alphabets = calloc(nsize, sizeof(image));
image** alphabets = (image**)calloc(nsize, sizeof(image));
char* labels = "/labels/%d_%d.png";
char* files = (char*)malloc(1 + strlen(datafile) + strlen(labels));
strcpy(files, datafile);
strcat(files, labels);
for (j = 0; j < nsize; ++j) {
alphabets[j] = calloc(128, sizeof(image));
alphabets[j] = (image*)calloc(128, sizeof(image));
for (i = 32; i < 127; ++i) {
char buff[256];
sprintf(buff, files, i, j);
Expand All @@ -33,16 +33,16 @@ image** load_alphabet_with_file(char* datafile) {
}

#ifdef OPENCV
void generate_image(image p, IplImage* disp) {
void generate_image(image p, cv::Mat& disp) {
int x, y, k;
if (p.c == 3) rgbgr_image(p);
// normalize_image(copy);

int step = disp->widthStep;
int step = disp.step;
for (y = 0; y < p.h; ++y) {
for (x = 0; x < p.w; ++x) {
for (k = 0; k < p.c; ++k) {
disp->imageData[y * step + x * p.c + k] = (unsigned char)(get_pixel(p, x, y, k) * 255);
disp.data[y * step + x * p.c + k] = (unsigned char)(get_pixel(p, x, y, k) * 255);
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions darknet_ros/test/ObjectDetection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ bool sendImageToYolo(ros::NodeHandle nh, const std::string& pathToTestImage) {

// Get test image
cv_bridge::CvImagePtr cv_ptr(new cv_bridge::CvImage);
cv_ptr->image = cv::imread(pathToTestImage, CV_LOAD_IMAGE_COLOR);
cv_ptr->image = cv::imread(pathToTestImage, cv::IMREAD_COLOR);
cv_ptr->encoding = sensor_msgs::image_encodings::RGB8;
sensor_msgs::ImagePtr image = cv_ptr->toImageMsg();

Expand Down Expand Up @@ -154,7 +154,8 @@ TEST(ObjectDetection, DetectANYmal) {
pathToTestImage += "quadruped_anymal_and_person";
pathToTestImage += ".JPG";

// Send dog image to yolo.
// Send ANYmal and person image to yolo.
ASSERT_TRUE(sendImageToYolo(nodeHandle, pathToTestImage));
ASSERT_TRUE(sendImageToYolo(nodeHandle, pathToTestImage));
ASSERT_TRUE(sendImageToYolo(nodeHandle, pathToTestImage));

Expand Down

0 comments on commit 895a0fb

Please sign in to comment.