使用 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 DNN 模块-风格迁移

Opencv C++ 调用 tensorflow 模型caffe模型

opencv3.1dnn 未处理异常

手把手教你使用LabVIEW OpenCV DNN实现手写数字识别(含源码)

OpenCV DNN模块——从TensorFlow模型导出到OpenCV部署详解

OpenCv dnn模块扩展研究--style transfer