2016-04-01 4 views
0

3D画像(バイナリファイルとして保存)をMatのベクトルに読み込もうとしていますが(スライス単位で読み取ることができるように)、実行しようとするとセグメンテーションエラーが表示されますcreate_mat。私は何が悪くなったのか探し出すのに苦労しています。これは最初の場所でデータを読み取る最善の方法ですか?画像をvecに読み込む<Mat> 16bitエラー

#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; 
} 
+0

でマークされています。代わりに参照渡しを意味しますか? –

+0

エラーではなくベクトルではないかもしれません img(size [0]、Mat(size [1]、size [2]、CV_16UC1));各ベクトル要素(=各Mat)が同じデータメモリにリンクするので、問題につながるでしょう! – Micka

+0

幅と高さを入れ替えます。 MatコンストラクタはMat(height、width、...) – Micka

答えて

0

私はコメントで述べた2の問題を修正し、このコードを、試してみてください:

コードの変更は、あなたのcreate_mat機能は、ベクトル IMGのコピーを作成します 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; 
} 
+1

ありがとうございます!そうです。 – henryhetired

関連する問題