ページ 1 / 1
学校の課題なのですが・・・
Posted: 2007年2月20日(火) 14:35
by 超初心者
課題はCTの生データ切り出しプログラムを作成するというものなんですが、まったくわかりません。
流れとしては1.raw-fileをオープン。2.切り出し開始ビューまでファイルポインタをシーク。3.繰り返し処理
4.読み込み位置までシーク。5.切り出しサイズ分読み込み。6.出力ファイル名決定。7.出力ファイルオープン。8読み込んだデータを出力ファイルへ書き込み。9.出力ファイルクローズ10.rawファイルをクローズ。
という流れなんですが、まったく考えが浮かんできません。
丸投げはいけないとわかっているのですが、どうしても解決できません。よろしくお願いします。
Re:学校の課題なのですが・・・
Posted: 2007年2月20日(火) 15:03
by Yuki
>丸投げはいけないとわかっているのですが
1~10の流れの、1から全て分からないということですか?
単純にファイルをコピーするプログラムは作れますか?
Re:学校の課題なのですが・・・
Posted: 2007年2月20日(火) 15:08
by keichan
まずは1~10までで自身でできるところ、出来ないことを一つずつ確認してください。
1.ファイルオープン処理
2.ファイルのシーク処理
3.繰り返し処理(何の繰り返しか説明がないので分かりません)
4.2.と同様シーク処理
5.ファイルの読み込み(fread等)
6.これもどこからの情報でファイル名を決定するのか明記されていないのでわかりません
7.ファイルオープン処理
8.ファイルの書き込み(fwrite等)
9~10.ファイルクローズ処理
どれもわからないって事はない?ですよね??
Re:学校の課題なのですが・・・
Posted: 2007年2月20日(火) 15:24
by 超初心者
申し訳ありません。ほとんど理解できていないです。
ファイルのオープンとクローズくらいしか分かりません。
シークなどはまったく理解していないです。
さらにファイルはランダム、バイナリについても厳しいです。
ファイル名はRAWファイルのパスを入力すると言っていました。
1チャネル2バイト。
1024が1行にある。(2048個)
×列数で1ビューになることぐらいしかわかりません。
こんな質問で本当に申し訳ありません。ちなみにファイルのコピー
ぐらいなら作成できます。
Re:学校の課題なのですが・・・
Posted: 2007年2月20日(火) 16:45
by keichan
超初心者さんの仰っている RAWファイル というものが
どのようなフォーマットであるのか明記されていませんので、具体的なアドバイスができません。
もしかしてRAW graphics formatかな?と思いましたが、判断をつきかねます。
オープン:fopen
クローズ:fclose
シーク:fseek
バイナリ用読み込み:fread
バイナリ用書き込み:fwrite
テキスト用書き込み:fputc, fputs 等
現状提示されている仕様では上記関数を調べてやってみてください。
としか、言えません。
もっと突っ込んだアドバイスが欲しいと思うのであれば、
情報の出し惜しみをせずに全て開示してください。
ex)
>ファイル名はRAWファイルのパスを入力すると言っていました。
実行時に入力させるのか、実行時パラメータで入力するのか?
RAWファイルのフォーマットは?
>2.切り出し開始ビューまでファイルポインタをシーク。
切り出し開始地点はどうやって決めるの?
>3.繰り返し処理
何を"繰り返し"て処理するの?
.
.
.
等、不明な点を全て提示お願いします。
Re:学校の課題なのですが・・・
Posted: 2007年2月20日(火) 17:29
by Yuki
>シークなどはまったく理解していないです。
簡単に説明すると、シークとは指定された位置にファイルポインタを移動することを指します。
例えば、「abcdefg」というデータのファイルが存在した場合、
ファイルをオープンし、そのままデータを読み込むと「abcdefg」が取得できますよね。
ファイルをオープン後、【ファイルポインタをファイルの先頭から3バイト移動する】(シークする)処理後
そのファイルポインタからデータを読み込むと「defg」というデータが取得できます。
/* サンプルソース */
int main(void)
{
FILE *fp = NULL;
char buf[64];
memset( buf, 0x00, sizeof(buf));
fp = fopen( "test.txt", "rb" );
if( fp ){
fread( buf, sizeof(buf), 1, fp );
printf( "シーク無し:%s\n", buf );
fclose( fp );
fp = NULL;
}
memset( buf, 0x00, sizeof(buf));
fp = fopen( "test.txt", "rb" );
if( fp ){
fseek( fp, 3, SEEK_SET );
fread( buf, sizeof(buf), 1, fp );
printf( "シーク有り:%s\n", buf );
fclose( fp );
fp = NULL;
}
return 0;
}
これを応用して、今回の課題のファイルフォーマットから取得したいデータを抽出する方法を考えてみてください。
>1チャネル2バイト。
>1024が1行にある。(2048個)
>×列数で1ビューになることぐらいしかわかりません。
まず、このファイルフォーマットのイメージをつかむことが必要です。
切り出し開始ビューを区別できるものはありますか?
Re:学校の課題なのですが・・・
Posted: 2007年2月20日(火) 18:13
by 超初心者
皆さんありがとうございます。
現在分かっていることは、、、
総ビュー数 (tviews)
セグメント数 (segment)
切り出し開始ビュー (start_view)
切り出し個数 (raw_n)
切り出しサイズ (size_view)
切り出しピッチ (pitch_view)
を引数として扱うということです。
切り出し開始ビューまでファイルポインタを
シークとは、読み出したファイルに対してです。
ピッチは開始ビュー+ピッチ×0(開始位置)
次からは×1、×2となっていきます。
この数字を変数として使い繰り返せと言われました。
コマンドRaw Divait raw_file outraw_file tviews
segment raw_n start_view pitch_viewとなっており
raw_file 生データのファイル名をパスで入力
outraw_file 出力ファイル名をパスで入力します。
繰り返し処理とは切り出した個数の数
(0~raw-n)になるらしいです。
わかりにくくて本当に申し訳ありません。
Re:学校の課題なのですが・・・
Posted: 2007年2月21日(水) 08:02
by Yuki
>総ビュー数 (tviews)
>セグメント数 (segment)
>切り出し開始ビュー (start_view)
>切り出し個数 (raw_n)
>切り出しサイズ (size_view)
>切り出しピッチ (pitch_view)
>を引数として扱うということです。
これは関数の仕様ですよね?
関数の前に、シークするためのファイルの仕様は把握していますか?
プログラムが正しくできているか検証するためにも、テスト用のファイルを用意する必要があります。
ピッチとかコマンドとか言われても、超初心者さんがどこで何をしたいのかがわかりません。
>raw_file 生データのファイル名をパスで入力
このファイルの中に処理対象のファイルパスが入力されているということですか?
>outraw_file 出力ファイル名をパスで入力します。
このファイルの中に出力ファイルパスが入力されているということですか?
>(0~raw-n)になるらしいです。
raw-nはどこから求められるのですか?
回答者は質問者が抱えている問題を解決するお手伝いしかできません。
何が分からなくて、何が分かれば解決するのか自分の中で整理してみてください。
もし、超初心者さんが元々の課題の仕様を理解していないのでしたら、
出題者のかたに質問していただくか、課題をそのまま載せてください。
Re:学校の課題なのですが・・・
Posted: 2007年2月21日(水) 10:09
by 超初心者
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <io.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
int getfsize( path );
int main(void) {
int fdi,fdo;
short *rawdata;
// 生データ(in)
char *rawfile = "D:\\CT\\RawData256\\Case605\\Case_605_F13.raw";
// カットした生データ(out)
char cutRawfile[200] = "D:\\CT\\RawData256\\Case605\\Case_605_F13_Cut";
long fsize ; //ファイルサイズ
long cutsize;//カットサイズ
//何ビュー目を切り出すか
int viewNo;
char s[5];
printf("何ビュー目(1-3240)を切り出しますか?-->");
scanf("%d", &viewNo);
/* if(viewNo > 3240) {
printf("!!error!!\n");
exit(1);
}*/
sprintf(s,"%04d", viewNo);
strcat(cutRawfile, s);
strcat(cutRawfile, ".raw");
//ファイルサイズ取得 // 必要なくなったけど、残しておきます
if( (fsize = getfsize( rawfile )) < 0 ) {
printf("cannot get file size\n");
return -1;
}
// 生データファイルオープン
if( ( fdi = open( rawfile, _O_RDONLY | _O_BINARY ) ) < 0 ) {
printf("open error: read\n");
return -1;
}
// 書き込み用ファイルオープン
if((fdo = open( cutRawfile, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_BINARY, _S_IREAD|_S_IWRITE)) < 0) {
printf("open error: write\n");
close(fdi);
return -1;
}
printf("Now Processing...: malloc \n");
//1view(1曝射) = 2048 * 256ということなので、そのサイズ分、読み出すことにする
cutsize = 2048 * 256;
if( ( rawdata = (short*)malloc( (size_t)cutsize) ) == 0 ){
printf("malloc error\n");
close( fdi );
close( fdo );
return -1;
}
memset(rawdata, 0, (size_t)cutsize);
_lseeki64(fdi, (viewNo-1)*2048*256, SEEK_SET);
printf("Now Processing...: read file \n");
if( read( fdi, rawdata, (size_t)cutsize ) < cutsize ){
printf("read error\n");
free(rawdata);
close( fdi );
close( fdo );
return -1;
}
printf("Now Processing...: write file\n");
if( write( fdo, rawdata, (size_t)cutsize ) < cutsize ){
printf("write error\n");
free(rawdata);
close( fdi );
close( fdo );
return -1;
}
printf("!! Complete !! \n");
close( fdi );
close( fdo );
return 0;
}
int getfsize( path )
char *path ;
{
struct stat statbuf ;
if( stat( path, &statbuf ) == -1 )
return -1 ;
return( statbuf.st_size ) ;
}
自分の不甲斐なさで皆様にご迷惑をおかけして
すみません。よろしくお願いいたします。
Re:学校の課題なのですが・・・
Posted: 2007年2月21日(水) 10:33
by Yuki
>すみません。よろしくお願いいたします。
え~っと、なにをすれば良いでしょうか?
やりたいことは、このプログラムを関数化することですか?
Re:学校の課題なのですが・・・
Posted: 2007年2月21日(水) 14:18
by 超初心者
/* description
NAME
CutOneR-R.c : rNo番目の心拍をcartblとrawfileから切り出す
SYNOPSIS
% CutOneR-R cartbl(in) cartbl(out) rawfile(in) rawfile(out) views ttlviews rNo
*/
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <io.h>
#include <stdlib.h>
#include <string.h>
#define SEG 256
#define ONESEGSIZE 2048
#define ERROR 0
typedef struct {
int TubePos ; /* tube position (header[0]) */
int CarData ; /* cardiac data (header[9]) */
float CarPhase ; /* cardiac phase (0% - 100%) */
int CarTime ; /* offset from center phase */
} CARTBL ;
CARTBL CarTbl[200 * 1800] ; /* maximum 200 rotations */
void main( argc, argv )
int argc ;
char *argv[/url] ;
{
int fdi_raw, fdi_cartbl, fdo_raw, fdo_cartbl; // ファイルハンドル
int viewCnt = 0; // ビュー数をカウントする
int rr[30]; // 見つかったRのビュー数を格納
int startView, endView; //切り出し位置
int rCnt = 0; // Rをカウントする
int Ron = 0; // Rが見つかったとき1を立てる
int viewNum; // ビュー数
int ttlviews; // 総ビュー数
int rNo = 0; // 何番目のRかを指定
short *rawdata; // 切り出した生データを格納
long rawdataCutSize; // 切り出す生データのサイズ
// 引数の個数チェック
if(argc != 8) {
printf( "usage: %s cartbl(in) cartbl(out) rawfile(in) rawfile(out) views ttlviews rNo\n", argv[0] ) ;
exit( 1 ) ;
}
// ビュー数を取得
viewNum = atoi( argv[5] );
ttlviews = atoi( argv[6] );
// 何番目のRか
rNo = atoi( argv[7] );
if(rNo < 1) {
printf( "%s: error rNo\n", argv[0]) ;
exit(1);
}
// ファイルオープン(cartbl)
if( ( fdi_cartbl = open( argv[1], _O_RDONLY | _O_BINARY ) ) < 0 ) {
printf( "%s: can't open %s\n", argv[0], argv[1] ) ;
exit(1);
}
if((fdo_cartbl = open( argv[2], _O_CREAT|_O_TRUNC|_O_WRONLY|_O_BINARY, _S_IREAD|_S_IWRITE)) < 0) {
printf( "%s: can't open %s\n", argv[0], argv[2] ) ;
close(fdi_cartbl);
exit(1);
}
// 初期化
memset(rr, 0, sizeof(rr)) ;
// cartblの切り出し
//printf("No\t TubePos\t CarData\t CarPhase\t CarTime\n");
while( read(fdi_cartbl, &CarTbl[viewCnt], sizeof(CARTBL)) == sizeof(CARTBL) ) {
// printf("%2d\t %04x\t %04x\t %f\t %04x\n", viewCnt+1,
// CarTbl[viewCnt].TubePos, CarTbl[viewCnt].CarData,
// CarTbl[viewCnt].CarPhase, CarTbl[viewCnt].CarTime);
if( (Ron == 0) && ((CarTbl[viewCnt].CarData & 0x3000) == 0x3000) ) {
printf("R==0: viewCnt = %d\n", viewCnt);
Ron = 1;
rr[rCnt++] = viewCnt;
}
else if( (Ron == 1) && ((CarTbl[viewCnt].CarData & 0x3000) == 0) ){
Ron = 0;
}
viewCnt++;
}
// Rが見つからなかった場合
if(rCnt < 2 || rCnt <= rNo) {
printf( "%s: can't find R\n", argv[0]);
exit(1);
}
// 1つ目のR - 半回転 のビュー数を求める
if(rr[rNo-1] - (int)viewNum/2 < 0)
startView = 0;
else
startView = rr[rNo-1] - (int)viewNum/2;
// 2つ目のR + 半回転 のビュー数を求める
if(rr[rNo] + (int)viewNum/2 > ttlviews)
endView = ttlviews;
else
endView = rr[rNo] + (int)viewNum/2;
printf("cut range: startView = %d, endView = %d\n", startView, endView);
// 書き込み
if (write(fdo_cartbl, &CarTbl[startView], sizeof(CARTBL) * (endView - startView + 1) )
!= (int)(sizeof(CARTBL) * (endView - startView + 1)) ) {
printf("%s: can't write cartble\n", argv[0]);
close(fdi_cartbl);
close(fdo_cartbl);
exit(1);
}
close(fdi_cartbl);
close(fdo_cartbl);
// ファイルオープン(raw)
if( ( fdi_raw = open( argv[3], _O_RDONLY | _O_BINARY ) ) < 0 ) {
printf( "%s: can't open %s\n", argv[0], argv[3]) ;
exit(1);
}
if((fdo_raw = open( argv[4], _O_CREAT|_O_TRUNC|_O_WRONLY|_O_BINARY, _S_IREAD|_S_IWRITE)) < 0) {
printf( "%s: can't open %s\n", argv[0], argv[4]) ;
close(fdi_raw);
exit(1);
}
// ファイルの先頭からstartView分、読み飛ばす
_lseeki64(fdi_raw, ONESEGSIZE*startView, SEEK_SET);
// 切り出すサイズ
rawdataCutSize = (endView-startView)*ONESEGSIZE;
// メモリ確保
if( ( rawdata = (short *)malloc((size_t)rawdataCutSize) ) == ERROR ){
printf("%s: alloc error : rawdata\n", argv[0]) ;
goto exit;
}
// メモリ初期化
memset(rawdata, 0, (size_t)(rawdataCutSize));
// 読み出し
if( read(fdi_raw, rawdata, rawdataCutSize) != rawdataCutSize) {
printf("%s: can't read rawdata\n", argv[0]) ;
free(rawdata);
goto exit;
}
// 書き込み
if( write(fdo_raw, rawdata, rawdataCutSize) != rawdataCutSize ) {
printf("%s: can't write rawdata\n", argv[0]);
free(rawdata);
goto exit;
}
exit:
close(fdi_raw);
close(fdo_raw);
exit(0);
}
これらのソースを参考にしろと言われました。
Re:学校の課題なのですが・・・
Posted: 2007年2月21日(水) 14:51
by keichan
#昔の規格で記述されたソースですね
参考ソースは分かりましたが、
2007/02/21(水) 10:33 にYukiさんが質問されてる内容を答えていませんよ。
Re:学校の課題なのですが・・・
Posted: 2007年2月21日(水) 16:33
by 超初心者
>Yukiさん
>raw_file 生データのファイル名をパスで入力 。
>outraw_file 出力ファイル名をパスで入力します。
Yukiさんの考えの通りです。
ちなみに0~raw-nではなく0~raw_nでした。すみません。
すみません。関数化ではなく、生データ(rawデータ)の
切り出しプログラムを作りたいです。
切り出し場所はファイルの先頭=0で、ピッチは切り出し開始位置の幅で、
もし次の切り出し幅がなら20ならピッチは20になるということだそうです。
この場合、最初に各々の引数に値を格納するプログラムを作る
ことが必要だと思うのですが(違っていたらスミマセン)イメージが全くつかめません。
うまく説明できず本当に申しわけないです。
Re:学校の課題なのですが・・・
Posted: 2007年2月22日(木) 11:20
by Yuki
ファイルのフォーマットを教えてください。
+----------------------+--------------------+----------------------+--------------------+--------------------+
|開始ビュー1(?バイト)|ピッチ1(?バイト)|開始ビュー2(?バイト)|ピッチ2(?バイト)|・・・
+----------------------+--------------------+----------------------+--------------------+--------------------+
たぶん違うと思いますが、ファイルの仕様がないとプログラムがあっているのかもわかりません。
ちなみに2007/02/21(水) 10:09 のソースは何のソースですか?
Re:学校の課題なのですが・・・
Posted: 2007年2月23日(金) 13:29
by 超初心者
すみません。分からないです。ここまで
質問に答えていただき本当にありがとうございました。