使用 caffe 模型遇到 opencv/dnn 问题
Posted
技术标签:
【中文标题】使用 caffe 模型遇到 opencv/dnn 问题【英文标题】:Having issues with opencv/dnn with caffe model 【发布时间】:2018-10-08 22:34:06 【问题描述】:我正在尝试使用 caffe 模型和 opencv/dnn.hpp 在 opencv 中使用 openpose 示例
我一直在关注的教程 - https://www.learnopencv.com/deep-learning-based-human-pose-estimation-using-opencv-cpp-python/
如教程中所述,我们需要 2 个网络文件: 1 - prototxt - https://github.com/spmallick/learnopencv/blob/master/OpenPose/pose/coco/pose_deploy_linevec.prototxt
2 - caffe 模型 -posefs1.perception.cs.cmu.edu/OpenPose/models/pose/coco/pose_iter_440000.caffemodel
我按照教程制作的 ros 节点:
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/dnn/dnn.hpp>
#include <sensor_msgs/image_encodings.h>
#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <iostream>
using namespace std;
using namespace cv;
using namespace cv::dnn;
static const std::string OPENCV_WINDOW = "Image window";
#define COCO
#ifdef COCO
const int POSE_PAIRS[17][2] =
1,2, 1,5, 2,3,
3,4, 5,6, 6,7,
1,8, 8,9, 9,10,
1,11, 11,12, 12,13,
1,0,0,14,
14,16, 0,15, 15,17
;
static const std::string protoFile = "pose/coco/pose_deploy_linevec.prototxt";
static const std::string weightsFile = "pose/coco/pose_iter_440000.caffemodel";
int nPoints = 18;
#endif
class ImageConverter
ros::NodeHandle nh_;
image_transport::ImageTransport it_;
image_transport::Subscriber image_sub_;
public:
ImageConverter()
: it_(nh_)
image_sub_ = it_.subscribe("/zed/rgb/image_raw_color", 1, &ImageConverter::imageCb, this);
~ImageConverter()
cv::destroyWindow(OPENCV_WINDOW);
void imageCb(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;
if (cv_ptr->image.rows > 60 && cv_ptr->image.cols > 60)
detect_people(cv_ptr->image);
cv::waitKey(3);
void detect_people(cv::Mat msg)
int inWidth = msg.cols;
int inHeight = msg.rows;
float thresh = 0.1;
cv::Mat frame;
msg.copyTo(frame);
cv::Mat frameCopy = frame.clone();
int frameWidth = frame.cols;
int frameHeight = frame.rows;
cv::dnn::Net net = cv::dnn::readNetFromCaffe("pose_deploy_linevec.prototxt" ,"pose_iter_440000.caffemodel");
cv::Mat inpBlob = blobFromImage(frame, 1.0/255, cv::Size(inWidth, inHeight), cv::Scalar(0, 0, 0), false, false);
net.setInput(inpBlob);
cv::Mat output = net.forward();
int H = output.size[2];
int W = output.size[3];
std::vector<cv::Point> points(nPoints);
for (int n=0; n < nPoints; n++)
// Probability map of corresponding body's part.
cv::Mat probMap(H, W, CV_32F, output.ptr(0,n));
cv::Point2f p(-1,-1);
cv::Point maxLoc;
double prob;
cv::minMaxLoc(probMap, 0, &prob, 0, &maxLoc);
if (prob > thresh)
p = maxLoc;
p.x *= (float)frameWidth / W ;
p.y *= (float)frameHeight / H ;
cv::circle(frameCopy, cv::Point((int)p.x, (int)p.y), 8, Scalar(0,255,255), -1);
cv::putText(frameCopy, cv::format("%d", n), cv::Point((int)p.x, (int)p.y), cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(0, 0, 255), 2);
points[n] = p;
int nPairs = sizeof(POSE_PAIRS)/sizeof(POSE_PAIRS[0]);
for (int n = 0; n < nPairs; n++)
// lookup 2 connected body/hand parts
Point2f partA = points[POSE_PAIRS[n][0]];
Point2f partB = points[POSE_PAIRS[n][1]];
if (partA.x<=0 || partA.y<=0 || partB.x<=0 || partB.y<=0)
continue;
cv::line(frame, partA, partB, cv::Scalar(0,255,255), 8);
cv::circle(frame, partA, 8, cv::Scalar(0,0,255), -1);
cv::circle(frame, partB, 8, cv::Scalar(0,0,255), -1);
cv::imshow("Output-Skeleton", frame);
;
int main(int argc, char** argv)
ros::init(argc, argv, "image_converter");
ros::NodeHandle nh_;
ros::Publisher pub;
ImageConverter ic;
ros::spin();
return 0;
代码编译没有任何错误,但是当我运行代码时,它给出了以下错误消息:
运行节点时出现以下错误 错误 - OpenCV 错误:未指定的错误(失败:fs.is_open()。无法在 ReadProtoFromTextFile、文件 /tmp/binarydeb/ros-kinetic-opencv3-3.3.1/modules/dnn/src 中打开“pose_deploy_linevec.prototxt”) /caffe/caffe_io.cpp,第 1119 行 在抛出 'cv::Exception' 的实例后调用终止 什么():/tmp/binarydeb/ros-kinetic-opencv3-3.3.1/modules/dnn/src/caffe/caffe_io.cpp:1119:错误:(-2)失败:fs.is_open()。无法在函数 ReadProtoFromTextFile 中打开“pose_deploy_linevec.prototxt”
中止(核心转储)
请帮我解决这个问题。
【问题讨论】:
将路径更改为绝对路径并重试 Opencv 可能无法看到您的文件 【参考方案1】:此问题可能仅限于 windows 用户。 通过以下方式解决问题:
调用prototxt文件时使用/添加绝对路径。也添加扩展名。例如:
“pose/coco/pose_deploy_linevec.prototxt.txt”
我自己花了 3 个小时调试这个。希望它对其他人有所帮助。
【讨论】:
【参考方案2】:您选择了错误的文件路径。 只需替换这一行:
static const std::string protoFile = "pose/coco/pose_deploy_linevec.prototxt";
在您的笔记本电脑中使用 prototxt 文件的路径,如下所示:
static const std::string protoFile = "C:/Users/lenovo/Desktop/learnopencv-master/OpenPose/pose/coco/pose_deploy_linevec.prototxt";
【讨论】:
以上是关于使用 caffe 模型遇到 opencv/dnn 问题的主要内容,如果未能解决你的问题,请参考以下文章
Opencv C++ 调用 tensorflow 模型caffe模型
手把手教你使用LabVIEW OpenCV DNN实现手写数字识别(含源码)