Skip to content

Commit

Permalink
Add: ROS wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
BSSNBSSN committed Sep 17, 2022
1 parent aa70e2f commit 40c33ca
Show file tree
Hide file tree
Showing 39 changed files with 14,647 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
# Editor
*~
*.swp
.vscode

# Build files
Prj-Linux/lpr/TEST_*
Prj-Linux/*build*/
*.pyc
/Prj-PHP/build

/Prj-ROS/build
/Prj-ROS/devel
/Prj-ROS/logs
/Prj-ROS/.catkin_tools
48 changes: 48 additions & 0 deletions Prj-ROS/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Prj-ROS

HyperLPR的ROS包,封装了Prj-Linux的代码并为适配ROS进行了少量修改,在Ubuntu20.04中ros-noetic上进行了测试。

## 安装依赖

``` bash
sudo apt install ros-noetic-desktop-full
```
ros-noetic使用的opencv版本为opencv4,可能会与opencv3冲突,请注意停用opencv3以免无法编译运行

## 编译

本文件所在路径为catkin_ws,rospackage路径为 `/HyperLPR/Prj-ROS/src/hyperlpr`

``` bash
cd Prj-ROS
catkin build
echo "source ${PATH_TO_HYPERLPR}/Prj-ROS/devel/setup.bash" >> ~/.bashrc
```

进入`/Prj-ROS/src/hyperlpr/launch/bringup.launch`,修改`CameraTopic`为自己相机图像的topic

## 运行

``` bash
roslaunch hyperlpr bringup.launch
```

## 说明

与ros node有关的代码位于`/Prj-ROS/src/hyperlpr/src`中的`hyperlpr_node.h``hyperlpr_node.cpp`中,可以按需修改

运行时的rqt_graph如下

![image](./docs/rosgraph.png)

测试时使用的相机为Intel-RealSense D455,`bringup.launch`中默认CameraTopic为RealSense彩色图像topic

发布的三个topic分别为

+ /recognition_confidence 识别的置信度

+ /recognition_result 识别的结果,不过ROS不支持中文字符,所以在使用时需要对订阅的数据另作处理,想立即确定中文结果也可以查看terminal中ROS_INFO输出的结果

+ /recognized_image 框选出一帧所有可识别车牌的图像

以上三个topic均只对置信度大于75%的识别作出反应,可以调整代码中的置信度阈值以获得期待的识别效果
Binary file added Prj-ROS/docs/rosgraph.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 50 additions & 0 deletions Prj-ROS/src/hyperlpr/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
cmake_minimum_required(VERSION 3.0.2)
project(hyperlpr)

set(SRC_DETECTION src/PlateDetection.cpp src/util.h include/PlateDetection.h)

set(SRC_FINEMAPPING src/FineMapping.cpp )

set(SRC_FASTDESKEW src/FastDeskew.cpp )

set(SRC_SEGMENTATION src/PlateSegmentation.cpp )

set(SRC_RECOGNIZE src/Recognizer.cpp src/CNNRecognizer.cpp)

set(SRC_PIPLINE src/Pipeline.cpp)

set(SRC_SEGMENTATIONFREE src/SegmentationFreeRecognizer.cpp )


## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
find_package(OpenCV REQUIRED)

find_package(catkin REQUIRED COMPONENTS
cmake_modules
roscpp
rospy
std_msgs
sensor_msgs
geometry_msgs
cv_bridge
image_transport
)

catkin_package(
)

include_directories(
include
${catkin_INCLUDE_DIRS}
${OpenCV_INCLUDE_DIRS}
)


add_executable(${PROJECT_NAME}_node ${SRC_DETECTION} ${SRC_FINEMAPPING} ${SRC_FASTDESKEW} ${SRC_SEGMENTATION} ${SRC_RECOGNIZE} ${SRC_PIPLINE} ${SRC_SEGMENTATIONFREE} src/hyperlpr_node.cpp src/main.cpp)

target_link_libraries(${PROJECT_NAME}_node
${catkin_LIBRARIES}
${OpenCV_LIBS}
)
24 changes: 24 additions & 0 deletions Prj-ROS/src/hyperlpr/include/CNNRecognizer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// Created by Jack Yu on 21/10/2017.
//

#ifndef HYPERPR_CNNRECOGNIZER_H
#define HYPERPR_CNNRECOGNIZER_H

#include "Recognizer.h"
namespace pr {
class CNNRecognizer : public GeneralRecognizer {
public:
const int CHAR_INPUT_W = 14;
const int CHAR_INPUT_H = 30;

CNNRecognizer(std::string prototxt, std::string caffemodel);
label recognizeCharacter(cv::Mat character);

private:
cv::dnn::Net net;
};

} // namespace pr

#endif // HYPERPR_CNNRECOGNIZER_H
17 changes: 17 additions & 0 deletions Prj-ROS/src/hyperlpr/include/FastDeskew.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// Created by Jack Yu on 22/09/2017.
//

#ifndef HYPERPR_FASTDESKEW_H
#define HYPERPR_FASTDESKEW_H

#include <math.h>
#include <opencv2/opencv.hpp>
namespace pr {

cv::Mat fastdeskew(cv::Mat skewImage, int blockSize);
// cv::Mat spatialTransformer(cv::Mat skewImage);

} // namespace pr

#endif // HYPERPR_FASTDESKEW_H
29 changes: 29 additions & 0 deletions Prj-ROS/src/hyperlpr/include/FineMapping.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// Created by Jack Yu on 22/09/2017.
//

#ifndef HYPERPR_FINEMAPPING_H
#define HYPERPR_FINEMAPPING_H

#include <opencv2/dnn.hpp>
#include <opencv2/opencv.hpp>

#include <string>
namespace pr {
class FineMapping {
public:
FineMapping();

FineMapping(std::string prototxt, std::string caffemodel);
static cv::Mat FineMappingVertical(cv::Mat InputProposal, int sliceNum = 15,
int upper = 0, int lower = -50,
int windows_size = 17);
cv::Mat FineMappingHorizon(cv::Mat FinedVertical, int leftPadding,
int rightPadding);

private:
cv::dnn::Net net;
};

} // namespace pr
#endif // HYPERPR_FINEMAPPING_H
57 changes: 57 additions & 0 deletions Prj-ROS/src/hyperlpr/include/Pipeline.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//
// Created by Jack Yu on 22/10/2017.
//

#ifndef HYPERPR_PIPLINE_H
#define HYPERPR_PIPLINE_H

#include "CNNRecognizer.h"
#include "FastDeskew.h"
#include "FineMapping.h"
#include "PlateDetection.h"
#include "PlateInfo.h"
#include "PlateSegmentation.h"
#include "Recognizer.h"
#include "SegmentationFreeRecognizer.h"

namespace pr {

const std::vector<std::string> CH_PLATE_CODE{
"", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "0", "1", "2", "3", "4",
"5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G",
"H", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "U",
"V", "W", "X", "Y", "Z", "", "", "使", "", "", "", "",
"", "", "广", "", "", "", "", "", "", "", ""};

const int SEGMENTATION_FREE_METHOD = 0;
const int SEGMENTATION_BASED_METHOD = 1;

class PipelinePR {
public:
GeneralRecognizer *generalRecognizer;
PlateDetection *plateDetection;
PlateSegmentation *plateSegmentation;
FineMapping *fineMapping;
SegmentationFreeRecognizer *segmentationFreeRecognizer;

PipelinePR();
~PipelinePR();

void initialize(std::string detector_filename,
std::string finemapping_prototxt,
std::string finemapping_caffemodel,
std::string segmentation_prototxt,
std::string segmentation_caffemodel,
std::string charRecognization_proto,
std::string charRecognization_caffemodel,
std::string segmentationfree_proto,
std::string segmentationfree_caffemodel);

std::vector<std::string> plateRes;
std::vector<PlateInfo> RunPiplineAsImage(cv::Mat plateImage, int method);
};

} // namespace pr
#endif // HYPERPR_PIPLINE_H
32 changes: 32 additions & 0 deletions Prj-ROS/src/hyperlpr/include/PlateDetection.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// Created by Jack Yu on 20/09/2017.
//

#ifndef HYPERPR_PLATEDETECTION_H
#define HYPERPR_PLATEDETECTION_H

#include <PlateInfo.h>
#include <opencv2/opencv.hpp>
#include <vector>
namespace pr {
class PlateDetection {
public:
PlateDetection(std::string filename_cascade);
PlateDetection();
void LoadModel(std::string filename_cascade);
void plateDetectionRough(cv::Mat InputImage,
std::vector<pr::PlateInfo> &plateInfos,
int min_w = 36, int max_w = 800);
// std::vector<pr::PlateInfo> plateDetectionRough(cv::Mat
// InputImage,int min_w= 60,int max_h = 400);

// std::vector<pr::PlateInfo>
// plateDetectionRoughByMultiScaleEdge(cv::Mat InputImage);

private:
cv::CascadeClassifier cascade;
};

} // namespace pr

#endif // HYPERPR_PLATEDETECTION_H
94 changes: 94 additions & 0 deletions Prj-ROS/src/hyperlpr/include/PlateInfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
//
// Created by Jack Yu on 20/09/2017.
//

#ifndef HYPERPR_PLATEINFO_H
#define HYPERPR_PLATEINFO_H
#include <opencv2/opencv.hpp>
namespace pr {

typedef std::vector<cv::Mat> Character;

enum PlateColor { BLUE, YELLOW, WHITE, GREEN, BLACK, UNKNOWN };
enum CharType { CHINESE, LETTER, LETTER_NUMS, INVALID };

class PlateInfo {
public:
std::vector<std::pair<CharType, cv::Mat>> plateChars;
std::vector<std::pair<CharType, cv::Mat>> plateCoding;
float confidence = 0;
PlateInfo(const cv::Mat &plateData, std::string plateName, cv::Rect plateRect,
PlateColor plateType) {
licensePlate = plateData;
name = plateName;
ROI = plateRect;
Type = plateType;
}
PlateInfo(const cv::Mat &plateData, cv::Rect plateRect,
PlateColor plateType) {
licensePlate = plateData;
ROI = plateRect;
Type = plateType;
}
PlateInfo(const cv::Mat &plateData, cv::Rect plateRect) {
licensePlate = plateData;
ROI = plateRect;
}
PlateInfo() {}

cv::Mat getPlateImage() { return licensePlate; }

void setPlateImage(cv::Mat plateImage) { licensePlate = plateImage; }

cv::Rect getPlateRect() { return ROI; }

void setPlateRect(cv::Rect plateRect) { ROI = plateRect; }
cv::String getPlateName() { return name; }
void setPlateName(cv::String plateName) { name = plateName; }
int getPlateType() { return Type; }

void appendPlateChar(const std::pair<CharType, cv::Mat> &plateChar) {
plateChars.push_back(plateChar);
}

void appendPlateCoding(const std::pair<CharType, cv::Mat> &charProb) {
plateCoding.push_back(charProb);
}
std::string decodePlateNormal(std::vector<std::string> mappingTable) {
std::string decode;
for (auto plate : plateCoding) {
float *prob = (float *)plate.second.data;
if (plate.first == CHINESE) {
decode += mappingTable[std::max_element(prob, prob + 31) - prob];
confidence += *std::max_element(prob, prob + 31);
}

else if (plate.first == LETTER) {
decode += mappingTable[std::max_element(prob + 41, prob + 65) - prob];
confidence += *std::max_element(prob + 41, prob + 65);
}

else if (plate.first == LETTER_NUMS) {
decode += mappingTable[std::max_element(prob + 31, prob + 65) - prob];
confidence += *std::max_element(prob + 31, prob + 65);

} else if (plate.first == INVALID) {
decode += '*';
}
}
name = decode;

confidence /= 7;

return decode;
}

private:
cv::Mat licensePlate;
cv::Rect ROI;
std::string name;
PlateColor Type;
};
} // namespace pr

#endif // HYPERPR_PLATEINFO_H
Loading

0 comments on commit 40c33ca

Please sign in to comment.