将图像读入vec <mat> 16bit错误

时间:2016-04-01 12:19:05

标签: c++ opencv

我正在尝试将3D图像(存储为二进制文件)读入Mat的矢量(这样我可以逐片读取)但在尝试运行create_mat时总是给我分段错误。我很难找到问题所在。这是首先读取数据的最佳方式吗?

#include <cstdint>
#include <string>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
void read_tiff(string filename,unsigned long length,uint16_t* buffer)
{
  //Reads a binary file containing little endean array of uint16_t into a single array pointed by buffer
  FILE *ptr_file;
  ptr_file = fopen(filename.c_str(),"rb");
  rewind(ptr_file);
  uint16_t temp;
  unsigned int k;
  for (k=0;k<length;k++)
    {
      fread(&temp,2,1,ptr_file);
      buffer[k] = temp;     
    }  
  fclose(ptr_file);
  return;
}
void create_mat(vector<Mat> dst,const int width,const int height,const int stacks,uint16_t* src)
{
  int i,j,k;
  int counter = 0;
   for (i=0;i<stacks;i++)
    {
      for (j=0;j<height;j++)
    {
      for (k=0;k<width;k++)
        {
          (dst[i]).at<ushort>(j,k)= src[counter];
          cout<<src[counter]<<endl;
          //          cout<<dst[i].at<ushort>(j,k)<<endl;
          counter++;
        }
    }
    }

}
int main()
{
  string dir;
  dir = "/somedir.raw";
  cout<<dir<<std::endl;
  unsigned long length = 1365ul*1531ul*1265ul;
  uint16_t test[length];
  read_tiff(dir,length,test);
  int size[3] = {1265,1365,1531};
  vector<Mat> img(size[0],Mat(size[1],size[2],CV_16UC1)); 
  cout <<"image loading done"<<endl;
  create_mat(img,size[1],size[2],size[0],test);
  imwrite("test.jpg",img[400]);
  return 0;
}

1 个答案:

答案 0 :(得分:0)

请尝试使用此代码,该代码修复了我在评论中提到的2个问题:

代码更改以CHANGED:

标记
#include <cstdint>
#include <string>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
void read_tiff(string filename,unsigned long length,uint16_t* buffer)
{
  //Reads a binary file containing little endean array of uint16_t into a single array pointed by buffer
  FILE *ptr_file;
  ptr_file = fopen(filename.c_str(),"rb");
  rewind(ptr_file);
  uint16_t temp;
  unsigned int k;
  for (k=0;k<length;k++)
    {
      fread(&temp,2,1,ptr_file);
      buffer[k] = temp;     
    }  
  fclose(ptr_file);
  return;
}
void create_mat(vector<Mat> dst,const int width,const int height,const int stacks,uint16_t* src)
{
  int i,j,k;
  int counter = 0;
   for (i=0;i<stacks;i++)
    {
      for (j=0;j<height;j++)
    {
      for (k=0;k<width;k++)
        {
          (dst[i]).at<ushort>(j,k)= src[counter];
          cout<<src[counter]<<endl;
          //          cout<<dst[i].at<ushort>(j,k)<<endl;
          counter++;
        }
    }
    }

}
int main()
{
  string dir;
  dir = "/somedir.raw";
  cout<<dir<<std::endl;
  unsigned long length = 1365ul*1531ul*1265ul;
  uint16_t test[length];
  read_tiff(dir,length,test);
  int size[3] = {1265,1365,1531};
  // CHANGED: Instead of allocating Mat memory once and copy-constructing the Mat-header, create a new Mat header + memory for each vector element. Otherwise all the elements will share their pixel data (if you don't call a function that assigns new memory to the Mat)
  //vector<Mat> img(size[0],Mat(size[1],size[2],CV_16UC1)); 
  vector<Mat> img(size[0]);
  for(int i=0; i<size[0]; ++i)
      img[i] = Mat(size[2],size[1],CV_16UC1); // CHANGED: swapped height and width, because Mat constructor uses height-first


  cout <<"image loading done"<<endl;
  create_mat(img,size[1],size[2],size[0],test);
  imwrite("test.jpg",img[400]);
  return 0;
}