将OpenCV :: Mat加载为.pgm

时间:2015-08-10 09:50:39

标签: opencv mat pgm

我有一个程序将.PGM图像文件加载到std :: vector m_data:

void LoadPgm( std::string const& filename ){
  std::ifstream in( filename.c_str(), std::ios::binary );
  if ( !in ){
     std::cerr << "Error in Image::LoadPgm: Could not open file " << filename << std::endl;
     std::exit(1);
  }

  std::string data = std::string( std::istreambuf_iterator< char >( in ),
                                  std::istreambuf_iterator< char >() );

  if ( ( data[0] != 'p' && data[0] != 'P' ) || data[1] != '5' ){
     std::cerr << "Error in Image::LoadPgm: Unsupported image format " << filename << std::endl;
     std::exit(1);
  }

  unsigned char const* p = reinterpret_cast< unsigned char* >(&data[2]);

  m_width  = ReadNumber( p );
  m_height = ReadNumber( p );

  if ( ReadNumber( p ) > 255 )
  {
     std::cerr << "Error in Image::LoadPgm: Unsupported image deep " 
               << filename << std::endl;
     std::exit(1);
  }

  p++;

  m_data.assign( p, p + m_width * m_height );
}

ReadNumber()的位置是:

unsigned long ReadNumber(unsigned char const*&buffer){
 do{
     if ( *(buffer++) == '#' ){
        while ( *(buffer++) != 10 );
     }

     switch (*buffer)
     {
        case   9 : 
        case  10 : 
        case  13 : 
        case ' ' : 
        case '#' :
        case '0' : 
        case '1' : 
        case '2' : 
        case '3' : 
        case '4' : 
        case '5' : 
        case '6' : 
        case '7' : 
        case '8' : 
        case '9' : break;
        default :  
        {
           std::cerr << "Error in Image::LoadPgm: invalid data" << std::endl;
           exit( 1 );
        }
     }
 } 
 while ( (*buffer < '0') || (*buffer > '9') );

 unsigned long value = 0;

 do
 {
     value = 10 * value;
     value += *(buffer++) - '0';
 } 
 while ( (*buffer>='0') && (*buffer<='9') );

 return value;
}

我的问题是我如何将(而不是.pgm文件)OpenCV Mat加载到m_data中(无需创建文件)。

修改

这是我的解决方案(感谢ypnos):

void LoadPgm(cv::Mat1b &cvimg ){
    Mat1b matimage;
    cvtColor(cvimg, matimage, CV_RGB2GRAY);

    // Create a pgm object
    std::vector<unsigned char> dest(matimage.rows*matimage.cols);
    std::copy(matimage.begin(), matimage.end(), dest.begin());
    std::stringstream in;
    in << "P5"     << std::endl;
    in << matimage.cols  << std::endl;
    in << matimage.rows << std::endl;
    in << "255"    << std::endl;
    in.write( reinterpret_cast<char*>( &dest[0] ), matimage.cols * matimage.rows );

    std::string data = std::string( std::istreambuf_iterator< char >( in ), std::istreambuf_iterator< char >() );

    if ( ( data[0] != 'p' && data[0] != 'P' ) || data[1] != '5' ){
        std::cerr << "Error in Image::LoadPgm: Unsupported image format " << std::endl;
        std::exit(1);
    }

    unsigned char const* p = reinterpret_cast< unsigned char* >(&data[2]);

    m_width  = ReadNumber( p );
    m_height = ReadNumber( p );

    if ( ReadNumber( p ) > 255 ){
        std::cerr << "Error in Image::LoadPgm: Unsupported image deep" << std::endl;
        std::exit(1);
    }

    p++;

    m_data.assign( p, p + m_width * m_height );
}

1 个答案:

答案 0 :(得分:1)

如果要将1通道无符号字符矩阵的所有像素可靠地复制到数组中,请执行以下操作:

cv::Mat1u source = …
std::vector<unsigned char> dest(source.rows*source.cols);

std::copy(source.begin(), source.end(), dest.begin());