- 締切済み
C++画像処理に困っています。。
#include<iostream> #include<fstream> using namespace std; int main() { char outfile[]="256x256x100.bin"; ifstream fin(outfile, ios::in| ios::binary); ofstream fout; if(!fin){ cout << "ファイル1はオープンできません。endl"; return 1; } } const int SIZE=256; const int SLICE=100; signed short int* matrix= new signed short int[(SIZE)*(SIZE)*(SLICE)]; for(int i=0; i<SIZE*SIZE*SLICE; i++){ fin.read((char*) &matrix[i],sizeof(signed short int)); cout << matrix[i]; } delete[] matrix; fin.close(); fout.close(); return 0; } 上のように256x256x100の三次元データ(XxYxZ)を読み込む事ができ、256 pixelx256 pixelの画像が100枚表示することが出来ました。 次に、その画像データをXZ軸方面から見た画像データにしたいのですが、どのようにすればいいのでしょうか? たぶんY方向のデータを足し算して平均を求めればよいとは思うのですが、 プログラミング初心者なので、処理の方法が全く思い浮かびません。 どなたか教えて頂けますでしょうか?
- みんなの回答 (5)
- 専門家の回答
みんなの回答
- goosyu
- ベストアンサー率58% (36/62)
デバッグはしていませんがソースを見た感じ次の問題があります。 ・inでファイルから読み取っていますが,それを何もしていません。 ・またmatrixには何にも入っていないので何も処理出来ません。 本来はmatrixにinを代入する処理が必要なのでしょう。 ☆改善案を提示します。 【変更前】 signed short int (*in)[SIZE][SIZE]= new signed short int[SLICE][SIZE][SIZE]; 【変更後】 double (*matrix)[SIZE][SIZE]=new double[SLICE][SIZE][SIZE]; 【変更前】 for(int xx=0; xx<SIZE; xx++){ fin.read((char*) &in[zz][yy][xx], sizeof(signed short int)); //256x256x100_int16binの読込 } 【変更後】 for(int xx=0; xx<SIZE; xx++){ signed short int item; fin.read((char*) &item, sizeof(signed short int)); //256x256x100_int16binの読込 matrix[zz][yy][xx] = (double)item; // short → doubleへ変換 } 【変更前】 //256x256x100→256x100x256の配列に格納する double (*out)[SLICE][SIZE]=new double[SIZE][SLICE][SIZE]; double (*matrix)[SIZE][SIZE]=new double[SLICE][SIZE][SIZE]; 【変更後】 //256x256x100→256x100x256の配列に格納する double (*out)[SLICE][SIZE]=new double[SIZE][SLICE][SIZE]; //double (*matrix)[SIZE][SIZE]=new double[SLICE][SIZE][SIZE];
- goosyu
- ベストアンサー率58% (36/62)
>>out[zz][yy][xx] = matrix[3-1-yy][zz][xx]; >の部分で3-1-yyとなるということがなかなか理解出来ません。 >どのように考えたらよいのでしょうか? ・「3-1-yy」は「2-yy」でも問題ありませんが「5x5x3の配列をサンプルにしていますが256x256x100の配列でも数字を置換することで対応出来ます」と書いたので,3の部分を100に置換して「100-1-yy」として動作出来るように計算式を分けています。本来3はdefineまたはconstの定数とすべきです。 ・「2-yy」でもなぜと思うのであれば,添付画像右側を見て下さい,左から右へ,上から下へピクセルを取得する場合,(x,y,z)=(0,0,2)から(4,0,0)へ順に行う為,zだけを見ると初期値z=2から1引いていき0までのループになります。ループ内の複写先で使うyyが0から2まで加算されていくのでそれを利用してzの値を作っています。
補足
#include <iostream> #include <fstream> #include <iomanip> using namespace std; int main() { char outfile[]="256x256x100_int16bin"; ifstream fin(outfile, ios::in| ios::binary); if(!fin){ cout << "256x256x100_int16binはオープン出来ません。endl"; return 1; } ofstream fout; fout.open("Projection.bin", ios::out|ios::binary|ios::trunc); if(!fout){ cout << "Projection.binはオープン出来ません。endl"; return 1; } const int SIZE=256; const int SLICE=100; signed short int (*in)[SIZE][SIZE]= new signed short int[SLICE][SIZE][SIZE]; for(int zz=0; zz<SLICE; zz++){ for(int yy=0; yy<SIZE; yy++){ for(int xx=0; xx<SIZE; xx++){ fin.read((char*) &in[zz][yy][xx], sizeof(signed short int)); //256x256x100_int16binの読込 } } } //256x256x100→256x100x256の配列に格納する double (*out)[SLICE][SIZE]=new double[SIZE][SLICE][SIZE]; double (*matrix)[SIZE][SIZE]=new double[SLICE][SIZE][SIZE]; for(int zz=0; zz<SIZE; zz++){ for(int yy=0; yy<SLICE; yy++){ for(int xx=0; xx<SIZE; xx++){ out[zz][yy][xx]=matrix[SLICE-1-yy][zz][xx]; } } } //256x256x100配列からXZ軸から256x100の配列にY軸の平均を格納する方法 double avg[SLICE][SIZE]; memset(avg, 0, sizeof(avg)); //初期化 for(int zz=0; zz<SIZE; zz++){ for(int yy=0; yy<SLICE; yy++){ for(int xx=0; xx<SIZE; xx++){ avg[yy][xx]+=matrix[SLICE-1-yy][zz][xx]; } } } for(int yy=0; yy<SLICE; yy++){ for(int xx=0; xx<SIZE; xx++){ avg[yy][xx]/=SIZE; //合計÷要素数 cout << avg[yy][xx]; fout.write((char*)&avg[yy][xx], sizeof(double)); } } fin.close(); fout.close(); delete[] in; delete[] out; delete[] matrix; return 0; } アドバイス通り256x256x100の配列でトライしてみたのですが、出力される数字が全部同じ数字になってしまい、きちんと出力されてないように思われます。動的メモリの確保の仕方がまずいのではないかと疑っているのですが、まだきちんと理解していないため上手くいきません。 もしよろしければ、アドバイスください! よろしくお願いします。
- goosyu
- ベストアンサー率58% (36/62)
配列の考え方についてサンプルを貼っておきます。 その2 //5x5x3→5x3x5の配列に格納する方法 int out[5][3][5]; for (zz=0;zz<5;zz++) { for (yy=0;yy<3;yy++) { for (xx=0;xx<5;xx++) { out[zz][yy][xx] = matrix[3-1-yy][zz][xx]; } } } //5x5x3配列からXZ軸から5x3の配列にY軸の平均を格納する方法 long avg[3][5]; memset(avg, 0, sizeof(avg)); // 初期化 for (zz=0;zz<5;zz++) { for (yy=0;yy<3;yy++) { for (xx=0;xx<5;xx++) { avg[yy][xx] += matrix[3-1-yy][zz][xx]; } } } for (yy=0;yy<3;yy++) { for (xx=0;xx<5;xx++) { avg[yy][xx] /= 5; // 合計÷要素数 } } ☆avgに小数までの精度が必要ならlongではなくdoubleで宣言が必要です。 ☆5x5x3の配列をサンプルにしていますが256x256x100の配列でも数字を置換することで対応出来ます。
お礼
なるほど!図を見ながらの解説で、大変良く理解することができました。 本当に助かります。どうもありがとうございました。
補足
>out[zz][yy][xx] = matrix[3-1-yy][zz][xx]; の部分で3-1-yyとなるということがなかなか理解出来ません。 どのように考えたらよいのでしょうか?
- goosyu
- ベストアンサー率58% (36/62)
- goosyu
- ベストアンサー率58% (36/62)
とりあえず考え方を確認したい為,どんな配列での結果を求めているのか提示してください。
お礼
すみません!無事解決できました。 今度は、別の配列に格納する方法でも試してみたいと思います。