ros-perception / opencv_apps

http://wiki.ros.org/opencv_apps
64 stars 70 forks source link

Assertion failedのエラーが出る #73

Closed k-sekiya closed 6 years ago

k-sekiya commented 6 years ago

ロボットシステムを受講している者です。 10/23の資料のp9の画像処理プログラムの開発でopencvを用いて顔検出のプログラムを書いてみたのですが以下のようなエラーが出てしまいます。

OpenCV Error: Assertion failed (scn == 3 || scn == 4) in cvtColor, file /tmp/binarydeb/ros-kinetic-opencv3-3.2.0/modules/imgproc/src/color.cpp, line 9748
terminate called after throwing an instance of 'cv::Exception'
  what():  /tmp/binarydeb/ros-kinetic-opencv3-3.2.0/modules/imgproc/src/color.cpp:9748: error: (-215) scn == 3 || scn == 4 in function cvtColor

プログラムは以下です。

#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/features2d/features2d.hpp"
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/objdetect/objdetect.hpp>

class MyCvPkg
{
  image_transport::Subscriber img_sub_;
  image_transport::ImageTransport it_;

  void imageCallback(const sensor_msgs::ImageConstPtr &msg) {
    ROS_INFO("Received image");
    cv::Mat in_img = cv_bridge::toCvCopy(msg, msg->encoding)->image;

    //write opencv code
    cv::Mat face_img =in_img.clone();
    double scale = 4.0;
    cv::Mat gray, smallImg(cv::saturate_cast<int>(face_img.rows/scale), cv::saturate_cast<int>(face_img.cols/scale), CV_8UC1);
    // グレースケール画像に変換
    cv::cvtColor(face_img, gray, CV_BGR2GRAY);
    // 処理時間短縮のために画像を縮小
    cv::resize(gray, smallImg, smallImg.size(), 0, 0, cv::INTER_LINEAR);
    cv::equalizeHist( smallImg, smallImg);

  // 分類器の読み込み
    std::string cascadeName = "./haarcascade_frontalface_alt.xml"; // Haar-like
    //std::string cascadeName = "./lbpcascade_frontalface.xml"; // LBP
    cv::CascadeClassifier cascade;
    //if(!cascade.load(cascadeName))
    //return -1;

    std::vector<cv::Rect> faces;
    // マルチスケール(顔)探索
    // 画像,出力矩形,縮小スケール,最低矩形数,(フラグ),最小矩形
    cascade.detectMultiScale(smallImg, faces,
                 1.1, 2,
                 CV_HAAR_SCALE_IMAGE
                 ,
                 cv::Size(30, 30));

    // 結果の描画
  std::vector<cv::Rect>::const_iterator r = faces.begin();
  for(; r != faces.end(); ++r) {
    cv::Point center;
    int radius;
    center.x = cv::saturate_cast<int>((r->x + r->width*0.5)*scale);
    center.y = cv::saturate_cast<int>((r->y + r->height*0.5)*scale);
    radius = cv::saturate_cast<int>((r->width + r->height)*0.25*scale);
    cv::circle( face_img, center, radius, cv::Scalar(80,80,255), 3, 8, 0 );
  }

  cv::imshow("window", face_img);//画像を表示.
  cv::waitKey(1);

    //write opencv code
  }
public:
  MyCvPkg(ros::NodeHandle nh = ros::NodeHandle()) : it_(nh)
  {
    img_sub_ = it_.subscribe("image", 3, &MyCvPkg::imageCallback, this);
    cv::namedWindow("Fast", 1);
  }
};

int main (int argc, char **argv)
{
  ros::init(argc, argv, "my_cv_pkg_node");
  MyCvPkg mcp;
  ros::spin();
}

opencvのコード自体はうまく行ったのですが、rosで画像処理をするとエラーが出てしまいます。 エラーの原因を教えていただきたいです。

furushchev commented 6 years ago

@k-sekiya Welcome to open source programming. The code you posted looks not related to this repository, so it's better to post to a forum for general ROS community like https://answers.ros.org/ . Seemingly, you specified the desired encoding of converted images to the same as original images here [1]:

    cv::Mat in_img = cv_bridge::toCvCopy(msg, msg->encoding)->image;

So the encoding of in_img can be any encoding depending on the encoding of input images. However, in cvtColor function, you assume BGR as the encoding of the input image. Here if the encoding of the input image is not BGR, it can occur such an error.

    cv::cvtColor(face_img, gray, CV_BGR2GRAY);

But I did not execute your code, so it might not be true. Hope it helps you.

[1] http://docs.ros.org/diamondback/api/cv_bridge/html/c++/namespacecv__bridge.html#a49fedf7e642d505557b866f6e307a034

k-sekiya commented 6 years ago

@furushchev Thank you.

furushchev commented 6 years ago

@k-sekiya Is your problem solved? Please could you refer the link if you post a question to other sites like answers.ros.org just for helping those who may suffer the same problem that you met?