按照上一篇约定,这次更新对于视觉的入坑心得。这个比赛需要视觉的参与,包括补给区视觉标签的识别判断,敌方车辆的判断。
视觉标签的识别比较好搞,使用现成的Apriltag就可以了,但是对于敌方车辆的识别则见仁见智,opencv特征、滤波类、深度学习,都是很好的选择,这里就不对算法说太多,着重说一下踩得坑。
同样的,以下仅代表个人观点,若有错误请批评指正。
直接用的话可能会出现数据不准的情况,所以需要进行视觉标定,关于这方面的说明就更多了,甚至ROS官网就有说明,使用的是image_pipeline这个包,标定一般不会出问题,如果参数出问题了,我的方法是——改代码,把参数写在代码中,就不用在命令行中输入这些参数,虽然看起来很玄学,但确实之前命令行跑不通的程序正确执行了。详情直接搜视觉标定就可以了。
这个也是很简单的,使用apriltags2_ros,包在GitHub上就有,教程也是一大堆,唯一要注意的问题是——名称,就像上文说的,因为各个包作者不一样,所以可能名称对不上,造成消息订阅不到,这个也是小问题,改一下就好了。
cmake ..
find_package( OpenCV REQUIRED )
include_directories(
# include
${catkin_INCLUDE_DIRS}
${OpenCV_INCLUDE_DIRS}
)
target_link_libraries(${PROJECT_NAME}_node
PUBLIC
${catkin_LIBRARIES}
${OpenCV_LIBRARIES}
)
顺便一提,为了使用自己定义的消息类型,还需要加上这么一句:
generate_messages()
具体原理迫于时间压力还没有细究,感兴趣的朋友可以私信讨论一下;
from cv_bridge import CvBridge, CvBridgeError
def listener():
rospy.init_node('armor_detection_fromusb',anonymous=True)
rospy.Subscriber('/usb_cam/image_raw',Image,callback)
rospy.spin()
def callback(data):
cb=CvBridge()
cv_image=cb.imgmsg_to_cv2(data,"bgr8")
cv2.imshow('receive',cv_image)
cv2.waitKey(5)
img=cv_image
res=recgnize(img)
#cv2.rectangle(img, (res[0], res[1]), (res[2], res[3]), (0, 0, 255), 2)
cv2.imshow('contours', img)
cv2.waitKey(5)
C++
#include
#include
#include
void numberdeal(const sensor_msgs::ImageConstPtr& msg)
{
cv_bridge::CvImagePtr cv_ptr;
try
{
cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
}
catch (cv_bridge::Exception& e)
{
ROS_ERROR("cv_bridge exception: %s", e.what());
return;
}
Mat frame;
cv_ptr->image.copyTo(frame);
//其他处理过程
std::vector res = prc.RunPiplineAsImage(frame);
}
#include "./lpr/include/Pipeline.h"
#include
#include
#include
#include
#include
#include
#include
#include
using namespace pr;
using namespace std;
using namespace cv;
pr::PipelinePR prc("/home/dyson/roborts_ws/src/RoboRTS-ros/roborts_numberrecog/lpr/model/cascade.xml",
"/home/dyson/roborts_ws/src/RoboRTS-ros/roborts_numberrecog/lpr/model/HorizonalFinemapping.prototxt", "/home/dyson/roborts_ws/src/RoboRTS-ros/roborts_numberrecog/lpr/model/HorizonalFinemapping.caffemodel",
"/home/dyson/roborts_ws/src/RoboRTS-ros/roborts_numberrecog/lpr/model/Segmentation.prototxt", "/home/dyson/roborts_ws/src/RoboRTS-ros/roborts_numberrecog/lpr/model/Segmentation.caffemodel",
"/home/dyson/roborts_ws/src/RoboRTS-ros/roborts_numberrecog/lpr/model/CharacterRecognization.prototxt", "/home/dyson/roborts_ws/src/RoboRTS-ros/roborts_numberrecog/lpr/model/CharacterRecognization.caffemodel"
);
class NumberRecogize
{
public:
ros::NodeHandle nh_;
ros::Subscriber image_sub_;
ros::Publisher armor_pub_;
~NumberRecogize()
{
}
void numberdeal(const sensor_msgs::ImageConstPtr& msg)
{
cv_bridge::CvImagePtr cv_ptr;
try
{
cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
}
catch (cv_bridge::Exception& e)
{
ROS_ERROR("cv_bridge exception: %s", e.what());
return;
}
Mat frame;
cv_ptr->image.copyTo(frame);
std::vector res = prc.RunPiplineAsImage(frame);
roborts_msgs::ArmorDetection ar;
if(res.size()!=0){
ar.x1=res[0].ROI.x;
std::cout<("numberrecognize",2);
}
};
int main(int argc, char** argv){
ros::init(argc,argv,"numberrecognize");
NumberRecogize nr;
//ros::AsyncSpinner async_spinner(1);
//async_spinner.start();
//ros::waitForShutdown();
ros::spin();
return 0;
}
未完待续————————————————————————————————————————
欢迎批评指正!