首页 > 解决方案 > 无法创建包含对象的矢量

问题描述

我正在尝试创建一些代码来获取一些图片的颜色并转移到另一个。为此,我使用 opencv 对图片进行分割和处理。

我创建了一个名为 Shape 的类,其中包含一个形状的轮廓(使用 opencv findContours() 查找创建 std::vector> )、一个用作对象 id 的随机字符串和一个 cv::Vec3b 的颜色形状。

但是,当我遍历 opencv 找到的轮廓并创建一个对象(Shape 类)并想要添加到列表中时,它只是添加其中一些然后在控制台上出现分段错误。

这是我的代码:

#include <random>
#include <string>

#include <algorithm>
#include <opencv2/opencv.hpp>

using contourType = std::vector < std::vector < cv::Point > >;



std::string randomString (  )
{
    auto randchar = [  ](  ) -> char {

        const char charset[  ] =
        "0123456789"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz";

        const size_t max_index = ( sizeof ( charset ) - 1);

        return charset[ rand (  ) % max_index ];
    };

    std::string str ( 14, 0 );
    std::generate_n ( str.begin (  ), 14, randchar );

    return str;
};



class Shape {

  public:

    std::string idShape;
    std::vector < cv::Point > contour;
    cv::Vec3b color;

    Shape () {

    };

    void setShape ( std::vector < cv::Point > cnt, cv::Vec3b clr ) {

      idShape = randomString (  );
      contour = cnt;
      color = clr;

    };

    cv::Point centroid ( bool showImage ) {

      cv::Moments m = cv::moments ( contour, true );
      cv::Point centroid ( m.m10 / m.m00, m.m01 / m.m00 );

      return centroid;
    };

};



class Frame {

  public:

    std::string idFrame;
    cv::Size size;
    int type;
    std::vector < Shape > shapes;

    Frame ( cv::Size imSize, int tp ) {

      idFrame = randomString (  );
      size = imSize;
      type = tp;

    };

    int addShape ( Shape shape ) {

      shapes.push_back ( shape );

      return 0;

    };

};



contourType findShapes ( cv::Mat img, bool showImage ) {

  //Threshold
  cv::adaptiveThreshold ( img, img, 255, cv::ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, 5, 1 );

  //Erotion
  cv::Mat kernel = cv::getStructuringElement ( cv::MORPH_RECT, cv::Size ( 2, 2 ), cv::Point ( 0, 0 ) );
  cv::erode ( img, img, kernel );

  //Find contours
  contourType contours;
  cv::Mat contourImg = img.clone (  );
  cv::findContours ( contourImg, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE );
shapes
  //Show image if true 2nd. argument
  if ( showImage == true ) {

    cv::Mat contourImage ( img.size (  ), CV_8UC3, cv::Scalar ( 0, 0, 0 ) );
    cv::Scalar colors[ 3 ];

    colors[ 0 ] = cv::Scalar ( 255, 0, 0 );
    colors[ 1 ] = cv::Scalar ( 0, 255, 0 );
    colors[ 2 ] = cv::Scalar ( 0, 0, 255 );

    for ( size_t idx = 0; idx < contours.size (  ); idx++ ) {
        cv::drawContours ( contourImage, contours, idx, colors[ idx % 3 ], CV_FILLED /*thick*/ );
        std::cout << idx;
    };

    cv::imshow ( "Contour Image", contourImage );
    cv::waitKey ( 0 );

  };

  return contours;
};



cv::Vec3b findColor ( cv::Mat img, std::vector < cv::Point > contour, bool print ) {

  //Read pixel intensity
  cv::Vec3b intensity;
  cv::Point coordinate = contour[ 1 ];
  intensity = img.at < cv::Vec3b > ( coordinate );

  //Print pixel values
  if ( print == true ) {

    std::cout << intensity << std::endl;

  };

  return intensity;
};



int main ( int argc, char** argv ) {

  std::string url = argv[1];
  int type = 0;

  cv::Mat img;
  img = cv::imread ( url, 0 );

  Frame frame ( img.size (  ), type );

  contourType shapes;
  shapes = findShapes ( img, false );

  cv::Mat imColor;
  imColor = cv::imread ( url, 1 );

  std::list<Shape> te;

  for ( size_t i = 0; i < shapes.size (  ); i++  ) {

    Shape shape;

    shape.setShape ( shapes[i], findColor ( imColor, shapes[i], false ) );

    te.push_back( shape ); //Here is where it fails after adding a few objects, running out of memory? The idea is to contain the Shape object inside the a Frame members shapes property. But i'm testing first like this, just adding it to a list.


  };

  return 0;
}

它仅将 29 个形状添加到列表中,然后控制台中出现错误“分段错误(核心转储)”。但图像大约有 67 个形状。

标签: c++opencv

解决方案


推荐阅读