使用caffe模型的opencv / dnn有问题

时间:2018-10-08 22:34:06

标签: opencv caffe ros

我正在尝试使用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()。无法在文件/tmp/binarydeb/ros-kinetic-opencv3-3.3.1/modules/dnn/src中打开ReadProtoFromTextFile中的“ pose_deploy_linevec.prototxt”) /caffe/caffe_io.cpp,第1119行 抛出'cv :: Exception'实例后终止调用   what():/ 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”

已中止(核心已弃用)

请帮助我解决此问题。

2 个答案:

答案 0 :(得分:0)

此问题可能仅与Windows用户有关。 通过以下方法解决问题:

  • 在调用prototxt文件时使用/添加绝对路径。
  • 也添加扩展名。例如:

      

    “ pose / coco / pose_deploy_linevec.prototxt.txt”

花费了3个小时亲自调试。希望它对其他人有帮助。

答案 1 :(得分:0)

您选择了错误的文件路径。 只需替换此行:

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";