• 締切済み

ガンマ変換 C言語でプログラムの作成

次式のように、原画像の任意の階調値fから、点線の矢印のようにして交換後の階調値gを決める。このような階調値の変換を表す配列 unsigned char trans[256];を用いて画像の濃度補正を行うプログラム作成せよとあるのですが、どのような計算式を用いて任意の変換の プログラムを作成してよいかわかりません。 同、問題でガンマ変換のプログラムは作成したのですが、 詳しい方で添付画像のようなプログラムを作成できる方がいましたらよろしくお願いします。 ESPライブラリを使用していますので、添付ファイルにソースとヘッダファイルと図を添付しています   プログラムの開始: sを押す         終了: xを押す --------------------------------------------------------------*/ #include <stdio.h> #include <stdlib.h> #include "mypgmesp.h" /* ESP関係の関数が定義されているヘッダファイル */ #define FINAL_LEVEL 64 //最終的な表現階調数// // 関数のプロトタイプ宣言 void gamma_histgram(void); /*************************************************************************    このプログラムを実行したとき、はじめに実行される処理を書く *************************************************************************/ void ESP_Ready(void) { ESP_Open_Window(); } /*************************************************************************    このプログラムが終了したとき、実行される処理を書く *************************************************************************/ void ESP_Finish(void) { } /*************************************************************************    startボタンが押されたときに、実行される処理を書く *************************************************************************/ void ESP_Main(void) { int ret; /* 準備 */ ESP_Prepare(); /* 画像データを image1 に読み込んで表示する */ ret = ESP_load_image_data(); if(ret){ ESP_StartMenu(); return; } /////////////////////////////////////////////////// // 以下に関数や命令を記述する gamma_histgram(); // ここまで /////////////////////////////////////////////////// /* image2 を保存し表示する */ ESP_save_image_data(); /* メッセージの表示 */ ESP_StartMenu( ); } ////////////////////////////////////////////////// // 以下の関数内にプログラムを追加する /////////////////////////////////////////////////// void gamma_histgram(void) { int i, x, y,g; /* ループ変数 */ long int target_value;//変換後の頻度の目標値// double gam = 2.0,j; unsigned char trans[256]; ESP_Printf("ガンマ補正を行う\n"); for (i = 0; i < 256; i ++){ j=i; g=255*pow(j/255.0,1.0/gam); if(g>255) { trans[i]=255; } else if (g<0) { trans[i]=0; } else { trans[i]=(unsigned char)g; } x_size2=x_size1; y_size2=y_size1; for ( y = 0; y < y_size2; y ++ ) { for ( x = 0; x < x_size2; x ++ ) image2[y][x] = trans[image1[y][x]]; } } }

この投稿のマルチメディアは削除されているためご覧いただけません。

みんなの回答

  • orenotan
  • ベストアンサー率0% (0/0)
回答No.1

補足でヘッダファイルと濃度補正の図です /* ------------------------------------------------------- pgm ファイルを読み書きし、 ウィンドウ出力するためのヘッダファイル mypgmesp.h Ver 1.10 # 入力画像と出力画像のパス変更,拡張子の省略 ----------------------------------------------------------*/ #include <string.h> #include <stdlib.h> #include <esplib.h> /* 定数宣言 */ #define MAX_IMAGESIZE 1024 /* 想定する縦・横の最大画素数 */ #define MAX_BRIGHTNESS 255 /* 想定する最大階調値 */ #define GRAYLEVEL 256 /* 想定する階調数(=最大階調値+1) */ #define MAX_FILENAME 256 /* 想定するファイル名の最大長 */ #define MAX_BUFFERSIZE 256 /* 利用するバッファ最大長 */ #define IN_PATH "input" // 入力画像のパス #define OUT_PATH "output" // 出力画像のパス #define IMAGE_PREFIX ".pgm" // 画像の拡張子 #define ZOOM_E 120 /* 小さな画像を表示するときの自動ズーム調整 */ #define ZOOM 100 /* グラフィック表示のウィンドウの表示倍率 */ #define TXT_M 1 /* テキスト表示ウィンドウ番号 */ #define TXT_F 2 /* テキスト表示ウィンドウ番号 */ #define IMG_A 1 /* グラフィックウィンドウ番号 */ #define IMG_B 2 /* グラフィックウィンドウ番号 */ #define TXT_WIN_WIDTH_M 600 /* テキスト表示のウィンドウ横サイズ */ #define TXT_WIN_HIGHT_M 500 /* テキスト表示のウィンドウ縦サイズ */ #define TXT_WIN_WIDTH_F 200 /* テキスト表示のウィンドウ横サイズ */ #define IMG_WIN_WIDTH 120 /* グラフィック表示のウィンドウ横サイズ */ #define IMG_WIN_HIGHT 120 /* グラフィック表示のウィンドウ縦サイズ */ /* 大域変数の宣言 */ /* 画像用配列1,画像用配列2 */ unsigned char image1[MAX_IMAGESIZE][MAX_IMAGESIZE], image2[MAX_IMAGESIZE][MAX_IMAGESIZE]; int x_size1, y_size1, /* image1 の横画素数,縦画素数 */ x_size2, y_size2; /* image2 の横画素数,縦画素数 */ char in_fname[100][20]; int in_fno; /* 関数のプロトタイプ宣言 */ int ESP_load_image_data(void); /* 画像読み込み用関数 */ void ESP_save_image_data(void); /* 画像書き込み用関数 */ void ESP_Draw_image_data(int ino); void ESP_Open_Window(void); void ESP_Prepare(void); void ESP_StartMenu(void); /* 以下は関数の本体 */ int ESP_load_image_data( ) /* pgm 画像,横画素数,縦画素数のデータをファイルから読み込み,*/ /* image1[ ][ ],x_size1,y_size1 にそれぞれ代入する. */ { char file_name[MAX_FILENAME]; /* ファイル名用の文字配列 */ char buffer[MAX_BUFFERSIZE]; /* データ読み込み用作業変数 */ FILE *fp; /* ファイルポインタ */ int max_gray; /* 最大階調値 */ int x, y,i; /* ループ変数 */ /* 入力ファイルのオープン */ ESP_SelectTW(TXT_M); ESP_Printf("-----------------------------------------------------\n"); ESP_Printf(" モノクロ階調画像入力ルーチン\n"); ESP_Printf("-----------------------------------------------------\n"); ESP_Printf("ファイル形式は pgm, バイナリ形式とします.\n"); ESP_Printf("ファイルは Release\\%s フォルダから読み込みます.\n", IN_PATH); ESP_Printf("入力ファイルウィンドウの番号指定は /番号 です.\n"); ESP_Printf("入力ファイル名 (*.pgm) : "); ESP_Input(file_name); if(file_name[0] == '/'){ i=1; x=0; while(file_name[i]!='\0'){ x = x * 10 + (file_name[i]-'0'); i++; } if(x <= in_fno && x > 0) strcpy(file_name, in_fname[x-1]); } sprintf(buffer, "%s\\%s",IN_PATH, file_name); strcpy(file_name, buffer); fp = fopen( file_name, "rb" ); if ( NULL == fp ){ ESP_Printf("その名前のファイルは存在しません.\n"); ESP_Input(buffer); //exit(1); return 1; } /* ファイルタイプ(=P5)の確認 */ fgets( buffer, MAX_BUFFERSIZE, fp ); if ( buffer[0] != 'P' || buffer[1] != '5' ){ ESP_Printf("ファイルのフォーマットが P5 とは異なります.\n"); ESP_Input(buffer); exit(1); } /* x_size1, y_size1 の代入(#から始まるコメントは読み飛ばす) */ x_size1 = 0; y_size1 = 0; while ( x_size1 == 0 || y_size1 == 0 ){ fgets( buffer, MAX_BUFFERSIZE, fp ); if ( buffer[0] != '#' ){ sscanf( buffer, "%d %d", &x_size1, &y_size1 ); } } /* max_gray の代入(#から始まるコメントは読み飛ばす) */ max_gray = 0; while ( max_gray == 0 ){ fgets( buffer, MAX_BUFFERSIZE, fp ); if ( buffer[0] != '#' ){ sscanf( buffer, "%d", &max_gray ); } } /* パラメータの画面への表示 */ ESP_Printf("横の画素数 = %d, 縦の画素数 = %d\n", x_size1, y_size1 ); ESP_Printf("最大階調値 = %d\n",max_gray); if ( x_size1 > MAX_IMAGESIZE || y_size1 > MAX_IMAGESIZE ){ ESP_Printf("想定値 %d x %d を超えています.\n", MAX_IMAGESIZE, MAX_IMAGESIZE); ESP_Printf("もう少し小さな画像を使って下さい.\n"); ESP_Input(buffer); exit(1); } if ( max_gray != MAX_BRIGHTNESS ){ ESP_Printf("最大階調値が不適切です.\n"); ESP_Input(buffer); exit(1); } /* 画像データを読み込んで画像用配列に代入する */ for ( y = 0; y < y_size1; y ++ ){ for ( x = 0; x < x_size1; x ++ ){ image1[y][x] = (unsigned char)fgetc( fp ); } } ESP_Draw_image_data(1); ESP_Printf("データは正しく読み込まれました.\n"); ESP_Printf("-----------------------------------------------------\n"); fclose(fp); return 0; } void ESP_save_image_data() /* image2[ ][ ], x_size2, y_size2 のデータを,それぞれ pgm 画像,*/ /* 横画素数,縦画素数としてファイルに保存する. */ { char file_name[MAX_FILENAME]; /* ファイル名用の文字配列 */ char buffer[MAX_BUFFERSIZE]; /* データ読み込み用作業変数 */ FILE *fp; /* ファイルポインタ */ int x, y, i; /* ループ変数 */ /* 出力ファイルのオープン */ ESP_Printf("-----------------------------------------------------\n"); ESP_Printf(" モノクロ階調画像(pgm形式)出力ルーチン\n"); ESP_Printf("-----------------------------------------------------\n"); ESP_Printf("ファイルは Release\\%s フォルダに書き出します.\n", OUT_PATH); ESP_Printf("入力ファイルウィンドウの番号指定は /番号 です.\n"); ESP_Printf("拡張子を省略した場合は自動付加します.\n"); ESP_Printf("出力ファイル名を省略した場合は outimage.pgm とします.\n"); ESP_Printf("出力ファイル名 (*.pgm) : "); ESP_Input(file_name); if(file_name[0] == '/'){ i=1; x=0; while(file_name[i]!='\0'){ x = x * 10 + (file_name[i]-'0'); i++; } if(x <= in_fno && x > 0) strcpy(file_name, in_fname[x-1]); } else if(file_name[0] == '\0'){ strcpy(file_name, "outimage.pgm"); } else if(strstr(file_name, IMAGE_PREFIX) == NULL){ strcat(file_name, IMAGE_PREFIX); } sprintf(buffer,"%s\\%s", OUT_PATH, file_name); strcpy(file_name, buffer); ESP_Printf("出力ファイル: %s\n", file_name); fp = fopen(file_name, "wb"); if ( NULL == fp ){ strcpy(buffer,"mkdir "); strcat(buffer, OUT_PATH); system(buffer); fp = fopen(file_name, "wb"); } /* ファイル識別子 "P5" を先頭に出力する */ fputs( "P5\n", fp ); /* # で始まるコメント行(省略可能) */ fputs( "# Created by Image Processing\n", fp ); /* 画像の横幅,縦幅の出力 */ fprintf( fp, "%d %d\n", x_size2, y_size2 ); /* 最大階調値の出力 */ fprintf( fp, "%d\n", MAX_BRIGHTNESS ); /* 画像データの出力 */ for ( y = 0; y < y_size2; y ++ ){ for ( x = 0; x < x_size2; x ++ ){ fputc( image2[y][x], fp ); } } ESP_Draw_image_data(2); ESP_Printf("データは正しく出力されました.\n"); ESP_Printf("-----------------------------------------------------\n"); fclose(fp); } void ESP_Draw_image_data(int ino){ /* inoに指定された画像をウィンドウに表示する */ /* ino == 1 : 入力画像の表示 */ /* ino == 2 : 出力画像の表示 */ int x, y; /* ループ変数 */ int x0, y0; /* 表示画像のサイズ */ int zv; /* ウィンドウ位置の調整変数 */ if(ino == 1){ /* 入力画像のサイズ設定 */ x0 = x_size1; y0 = y_size1; /* 最低ウィンドウサイズを考慮したウィンドウ位置調整 */ zv= (ZOOM_E - x0); if(zv < 2) zv = 2; /* 入力画像表示のウィンドウサイズの変更のための出力ウィンドウ位置を変更 */ ESP_PlaceImage(IMG_B, x0+ zv +5, TXT_WIN_HIGHT_M+40); } else if(ino == 2){ /* 出力画像のサイズ設定 */ x0 = x_size2; y0 = y_size2; } /* ウィンドウサイズの変更・ズームの設定・更新 */ ESP_ResizeImage(ino, x0, y0); ESP_ZoomImage(ino, 100); ESP_UpdateAll(); /* 画像の描画 */ ESP_Select(ino); for ( y = 0; y < y0; y ++ ){ for ( x = 0; x < x0; x ++ ){ if(ino==1) ESP_Pset(x,y,image1[y][x]); else if(ino==2) ESP_Pset(x,y,image2[y][x]); } } } void ESP_Open_Window(void){ /* メッセージテキストウィンドウを開く */ ESP_OpenTextWindow(TXT_M, 0, 0, TXT_WIN_WIDTH_M,TXT_WIN_HIGHT_M); ESP_OpenTextWindow(TXT_F, TXT_WIN_WIDTH_M + 8, 0, TXT_WIN_WIDTH_F,TXT_WIN_HIGHT_M); /* 起動メッセージ表示 */ ESP_SelectTW(TXT_M); ESP_Printf("プログラム開始: s キーを押してください\n"); ESP_Printf("プログラム終了: x キーを押してください\n"); /* 入力ファイルウィンドウにヘッダを表示 */ ESP_SelectTW(TXT_F); ESP_Printf("%s\n"," No: 入力ファイル"); /* グラフィックウィンドウを開く */ ESP_CreateImage8(IMG_A, "入力", 0 , TXT_WIN_HIGHT_M+40, IMG_WIN_WIDTH, IMG_WIN_HIGHT,ZOOM); ESP_CreateImage8(IMG_B, "出力",IMG_WIN_WIDTH + 7, TXT_WIN_HIGHT_M+40, IMG_WIN_WIDTH, IMG_WIN_HIGHT,ZOOM); } void ESP_Prepare(void){ char file_name[MAX_FILENAME]; /* ファイル名用の文字配列 */ char buf[MAX_BUFFERSIZE]; /* データ読み込み用作業変数 */ FILE *fp; /* ファイルポインタ */ int cnt; /* カウント */ in_fno=0; sprintf(buf, "dir /b %s > _temp.txt", IN_PATH); system(buf); fp = fopen( "_temp.txt", "r" ); if ( NULL == fp ){ ESP_Printf("_temp.txtファイルは存在しません.\n"); ESP_Input(buf); exit(1); } ESP_SelectTW(TXT_F); fgets( buf,20,fp); //ファイルから1行読み込み while(!feof(fp)){ //EOFになるまで cnt=strlen(buf); //1行の文字数を数える buf[cnt-1] = '\0'; //改行を取り除く if(strstr(buf,IMAGE_PREFIX) != NULL){ strcpy(in_fname[in_fno],buf); //配列の末尾に追加 in_fno++; ESP_Locate(0, in_fno); ESP_Printf("%3d:%s\n", in_fno, buf); if(in_fno == 30) break; } fgets( buf,20,fp); //ファイルから1行読み込み } fclose(fp); //ファイルのクローズ sprintf(buf, "del _temp.txt"); system(buf); /* テキストウィンドウのクリア */ ESP_SelectTW(TXT_M); ESP_ClearTextWindow(); } void ESP_StartMenu(void){ /* メッセージの表示 */ ESP_SelectTW(TXT_M); ESP_Printf("\n=======================================\n"); ESP_Printf("プログラム開始: s キーを押してください\n"); ESP_Printf("プログラム終了: x キーを押してください\n"); }

関連するQ&A

  • C言語を使ったプログラム作成

    ご教授お願い致します。 strcpy(),strcat(),strcmp() 上記3つの標準関数と同じ機能を持った関数をポインタを使用してプログラム作成 関数名 (1)*u_strcpy (2)*u_strcat (3)*u_strcmp strcpy()は char *u_strcpy(char *s,char *t) { char *p=s; while(*s++=*t++) return p; } void main(void) { char x[10],y[10]; scanf("%s %s",x,y); printf("%s\n",u_strcpy(y,x)); } で正常に動いたので大丈夫だと思いますが他2つがわかりません。

  • 構造体ポインタ、及び、戻り値のあるマクロ関数の作成方法について

    ●開発環境 [OS] Linux 2.6.9 [コンパイラ] GCC 3.4.6 ●質問 以下のプログラム中のTEST関数を、 マクロ関数(#define)にしたいのですが、 やり方がわかりません。 ご存知の方がいらっしゃいましたら、ご教授願います。 -------------------------------- #include <stdio.h> typedef struct t_str_abc { unsigned int x; unsigned int y; } str_abc; unsigned int TEST( str_abc *kou ); void main(void) { str_abc kouzou; unsigned int ret; kouzou.x = 1; kouzou.y = 2; ret = TEST(&kouzou); printf("ret = %d\n", ret); } unsigned int TEST( str_abc *kou ) { unsigned int state; state = kou->x + kou->y; return state; } --------------------------------

  • 組織的ディザ法のプログラムがうまくいきません

    下記のプログラムはPGM画像に組織的ディザ法を行い、2値化を行うプログラムなのですがうまく作動しません。 どこがダメなのかわかる方回答お願いします。 また、PGMのフォーマットをP5しか読み込むことしか出来ないのですが、これを P2のアスキーで読み込めるように変更できないでしょうか? /* 組織的ディザ法のプログラム dither.c */ #include<stdio.h> #include<stdlib.h> #include<string.h> #include"mypgm.h" #define BLOCK_SIZE 4 /* ブロックの横(=縦)画素数 */ #define NEW_LEVEL 16 /* 擬似階調数(= BLOCK_SIZE の2乗) */ #define MAXWIDTH 1000 #define MAXHEIGHT 1000 /* 原画像 image1[y][x] のディザ画像を作り image2[y][x] に代入 */ void make_dither_image( ) { double width; /* 16段階画像の階調値の単位幅 */ int x,y,i,j,m,n; int x_block = x_size1 / BLOCK_SIZE; /* 横のブロック数 */ int y_block = y_size1 / BLOCK_SIZE; /* 縦のブロック数 */ int gray_16 = (int)( image1[y][x] / width ); /* 新しい階調(16階調での値) */ /* Bayer 型ディザ行列 */ int dither_matrix [4][4] = { { 0, 8, 2, 10}, {12, 4, 14, 6}, { 3, 11, 1, 9}, {15, 7, 13, 5} }; /* 横,縦の画素数がBLOCK_SIZEの倍数であるかのチェック */ if ( x_size1 % BLOCK_SIZE != 0 || y_size1 % BLOCK_SIZE != 0 ){ printf("原画像の横・縦の画素数が不適切です.\n"); exit(1); } /* 16階調の画像を作る */ //一度、画像を16階調に変換して(正確にはディザブロック分の1)さらに2階調(白黒)に変換する。 width = MAX_BRIGHTNESS / (double)NEW_LEVEL; x_size2 = x_size1; y_size2 = y_size1; for (y = 0; y < y_size1; y ++ ){ for (x = 0; x < x_size1; x ++ ){ if ( gray_16 > NEW_LEVEL - 1 ) gray_16 = NEW_LEVEL - 1; image2[y][x] = (unsigned char)gray_16; } } /* ディザ画像を作る */ printf("ディザ画像を作ります.\n"); for (i = 0; i < y_block; i ++ ){ for (j = 0; j < x_block; j ++ ){ int x = BLOCK_SIZE * j; int y = BLOCK_SIZE * i; for (m = 0; m < BLOCK_SIZE; m ++ ){ for (n = 0; n < BLOCK_SIZE; n ++ ){ if ( image2[y + m][x + n] <= dither_matrix[m][n] ) image2[y + m][x + n] = 0; else image2[y + m][x + n] = MAX_BRIGHTNESS; } } } } } 【mypgm.h】 http://cis.k.hosei.ac.jp/~wakahara/mypgm.h

  • C言語のプログラムを見てください

    ある100行の値がx列、y列の2列あるファイルを読み込んでそれを配列に入れ、yの最小値及びそれと同じ行にあるxの値を表示するプログラムを書きたいのですがy列の最小値を表示するプログラムを書き終えた所でコンパイルして実行してみると正しく値が表示されませんでした。それどころか実行するたびに値が変わってしまいます。どこがおかしいのかわからないため、ご指摘のほどよろしくお願いします。また、できれば同じ行にあるx列の値も表示させるプログラムを教えてください。 よろしくお願いします。 #include <stdio.h> #include <stdlib.h> #define N 100 int main(void) { int x[N],i; double y[N],min; FILE *fp; fp=fopen("book.dat","r"); if(fp==NULL){ puts("can't open file!"); exit(-1); } for(i=0;i<N;i++){ fscanf(fp,"%d %lf", &x[N],&y[N]); printf("x=%d\n y=%lf\n",x[N],y[N]); } min=y[0]; for(i=1;i<N;i++){ if(y[i]<min) min=y[i]; } fclose(fp); printf("最小値:%lf\n",min); return 0; }

  • とあるプログラムを教えてほしいのですが

    はじめましてこんばんは hommado と申します。 じつは先週の授業でこんな問題を出されたんですがもしできたらとあるプログラムを教えてほしいのです。 問題は 「キーボードから何階調にするのかを読み込むことで、入力画像LAX.bmpを任意の階調数に変換する」という プログラムです。 一応下に素体のプログラムをおいたんで、其のプログラムに何か付け足す感じでお願いします。「/*******↓基本的には、この範囲に画像処理プログラムを書く****/」から 「 /********↑**************************************************/」の中にプログラムを書くかんじなのでもし分かったら教えてください。お願いします。 あと何か他の所に付け足すようなところがあったら教えてください ここから元のプログラム // Bitmapファイルを読み込んで, // 別のファイルに出力するだけのプログラムです #include<stdio.h> #define XSIZE 256 /* 画像の横サイズ*/ #define YSIZE 256 /* 画像の縦サイズ*/ void main(void) { int x,y; char fni[40],fno[40]; /* 入力ファイルと出力ファイルの名前を格納するための配列*/ unsigned char head[1078],buf[YSIZE][XSIZE]; /* 入力ファイル(ビットマップファイル)のヘッダ情報と輝度値情報を格納するための配列*/ unsigned char in_image[YSIZE][XSIZE]; /* 入力画像の画素の輝度値を格納するための配列*/ unsigned char out_image[YSIZE][XSIZE]; /* 出力画像の画素の輝度値を格納するための配列*/ FILE *fp,*fp2; /* ファイルポインタ*/ printf("ファイル名を入れてください:"); scanf("%s",fni); fp=fopen(fni,"rb"); /* 読み込み& バイナリモードでオープンする*/ /* 配列head にビットマップファイルのヘッダ情報が格納されます*/ fread(head,sizeof(unsigned char),1078,fp); /* unsigned char 型のデータ×個を配列head に読み込む*/ /* 配列buf にビットマップファイルの輝度値情報が格納されます*/ fread(buf,sizeof(unsigned char),XSIZE*YSIZE,fp); for(y=0;y<YSIZE;y++){ for(x=0;x<XSIZE;x++){ in_image[y][x]=buf[y][x]; /* 画像の左下の画素が座標buf[0][0] です*/ } } printf("読み込み終了しました!\n"); printf("出力ファイル名を入れてください:"); scanf("%s",fno); /*******↓基本的には、この範囲に画像処理プログラムを書く****/       ここにプログラムを書いてください!      (もしここ以外で、他の所で付け足すプログラムがあったら何行目に       何を書くのかも教えてください) /********↑**************************************************/ fp2=fopen(fno,"wb"); /* 書き込み& バイナリモードでオープンする*/ /* 配列head の内容を出力ファイルに書き込む*/ fwrite(head,sizeof(unsigned char),1078,fp2); /* 配列out_image の内容を出力ファイルに書き込む*/ fwrite(out_image,sizeof(unsigned char),XSIZE*YSIZE,fp2); fclose(fp); /* ファイルをクローズする*/ fclose(fp2); /* ファイルをクローズする*/ printf("作業完了!\n"); }

  • C言語に直して下さい

    VisualC++で円周率を求めるプログラムなのだそうですが、 自分はC言語しか使ったことがないため、よく分かりません。 Cでコンパイルできるように直していただけないでしょうか。 よろしくお願いします。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define N 21 #define K 100000 void add(unsigned long a[],unsigned long b[]) { int c = 0, tmp; for (int i = N - 1; i > -1; i--) { tmp = a[i] + b[i] + c; a[i] = tmp % K; c = tmp / K; } } void sub(unsigned long a[],unsigned long b[]) { int c = 0, x = 0; for (int i = N - 1; i > -1 ; i--) { x = c; if (a[i] < b[i] + x ) c = 1; else c = 0; a[i] = c * K + a[i] - b[i] - x; } } void div(unsigned long a[], unsigned long x) { int c=0, tmp; if (x >= K) { printf("Div Error\n"); getchar(); exit(1); return; } for (int i = 0; i < N ; i++) { tmp = (a[i] + c * K) / x; c = (a[i] + c * K) % x; a[i] = tmp; } } void clear(unsigned long a[]) { memset(a,0x00,sizeof(a)*N); } void set(unsigned long a[], unsigned long b[]) { memcpy(a,b,sizeof(a)*N); } void set(unsigned long a[], unsigned long b) { if (b<K) { clear(a); a[0]=b; } } int _tmain(int argc, _TCHAR* argv[]) { unsigned long pai[N], fn[N], gn[N], tmp1[N], tmp2[N]; int i; unsigned long n; clear(pai); clear(fn); clear(gn); clear(tmp1); clear(tmp2); set(fn, 16*5); set(gn, 4*239); for(n=0;n<40000;n++) { div(fn, 25); div(gn, 239); div(gn, 239); set(tmp1, fn); div(tmp1, 2*n+1); set(tmp2, gn); div(tmp2, 2*n+1); if (n%2==0) { add(pai, tmp1); sub(pai, tmp2); }else{ add(pai, tmp2); sub(pai, tmp1); } } for (i=0;i<N;i++) { printf("%5lu ", pai[i]); } getchar(); return 0; }

  • らべリnグについての質問です

    数字が書かれた画像を2値化し、ラベリングして数字だけを抜き出して出力したいのですが、どうも上手くいきません。 色々試しても見たのですが、数字だけを取り出すことはできませんでした。 以下のプログラムのどこを直せば、ラベリングされた画像を抜き出すことができるのでしょうか? 一週間やってもできませんでした… 何方か教えて下さると大変助かります #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #define Y_SIZE 512 //縦の最大画素数 #define X_SIZE 512 //横の最大画素数 #define HIGH 255 //最大階調値 #define LOW 0 //最小階調値 #define Level 256 #define FileName 256 #define MaxBufferSize 640 #define L_BASE 100 #define Black 1 #define White 2 unsigned char image[Y_SIZE][X_SIZE]; //入力画像用配列 unsigned char label_image[Y_SIZE][X_SIZE]; unsigned char image_h[Y_SIZE][X_SIZE]; int x_size, y_size; int Label=200; long hist[256]; void set(unsigned char image[Y_SIZE][X_SIZE], int xs, int ys, int label); void save(unsigned char output_img[Y_SIZE][X_SIZE],int output_ysize,int output_xsize); void load(void) { 入力画像 } void hist1(unsigned char image_in[Y_SIZE][X_SIZE], int x, int y, long hist[256]) { ヒストグラム処理 } void hist2(long hist[256], unsigned char image_h[Y_SIZE][X_SIZE]) { ヒストグラムを画像化 } void thr(unsigned char image_in[Y_SIZE][X_SIZE], unsigned char image_out[Y_SIZE][X_SIZE], int thresh, int type) { 閾値処理 閾値180 タイプ白 } 画像のラベリング処理 int labeling(unsigned char image_in[Y_SIZE][X_SIZE], unsigned char image_label[Y_SIZE][X_SIZE]) { int i, j, label; for (i = 0; i < Y_SIZE; i++) for (j = 0; j < X_SIZE; j++) image_label[i][j] = image_in[i][j]; label = L_BASE; for (i = 0; i < Y_SIZE; i++) for (j = 0; j < X_SIZE; j++) { if (image_label[i][j] == HIGH) { if (label >= HIGH) return -1; set(image_label, j, i, label); label++; }} return label - L_BASE; } 連結している画素すべてにラベル付け void set(unsigned char image[Y_SIZE][X_SIZE], int xs, int ys, int label) { int i, j, cnt, im, ip, jm, jp; image[ys][xs] = label; while(1) { cnt = 0; for (i = 0; i < Y_SIZE; i++) for (j = 0; j < X_SIZE; j++) if (image[i][j] == label) { im = i-1; ip = i+1; jm = j-1; jp = j+1; if (im < 0) im = 0; if (ip >= Y_SIZE) ip = Y_SIZE-1; if (jm < 0) jm = 0; if (jp >= X_SIZE) jp = X_SIZE-1; if (image[i ][jp] == HIGH) { image[i ][jp] = label; cnt++; } if (image[im][jp] == HIGH) { image[im][jp] = label; cnt++; } if (image[im][j ] == HIGH) { image[im][j ] = label; cnt++; } if (image[im][jm] == HIGH) { image[im][jm] = label; cnt++; } if (image[i ][jm] == HIGH) { image[i ][jm] = label; cnt++; } if (image[ip][jm] == HIGH) { image[ip][jm] = label; cnt++; } if (image[ip][j ] == HIGH) { image[ip][j ] = label; cnt++; } if (image[ip][jp] == HIGH) { image[ip][jp] = label; cnt++; } } if (cnt == 0) break; } save(image,ys,xs); } //ラベリング画像の出力 void save(unsigned char output_img[Y_SIZE][X_SIZE],int output_ysize,int output_xsize) { char f_name[FileName]; FILE *fp; int i, j,n; printf("Output File (*.pgm) : "); scanf("%s",f_name); fp = fopen(f_name, "wb"); fputs( "P5\n", fp ); fputs( "# Created by Image Processing\n", fp ); fprintf( fp, "%d %d\n", output_xsize, output_ysize ); fprintf( fp, "%d\n", HIGH); 画像データの出力 for (i=0; i<output_ysize; i++) for (j=0; j<output_xsize; j++) fputc(output_img[i][j], fp); fclose(fp); } int main(void){ int thresh=180, type=White; 入力画像 load(); ヒストグラム処理 hist1(image, x_size, y_size, hist); ヒストグラム画像化 hist2(hist,image_h); 閾値処理 thr(image, image_h, thresh, type); labeling(image_h, label_image); return 0; }

  • C言語の変換する関数について教えてください。

    キーボードからローマ字で入力された名前の英文字を変換する関数を定義し、その関数の機能を確認するプログラムを作成する問題について教えてください。 (1)英小文字であればそれを英大文字に変換する関数 (2)英大文字であればそれを英小文字に変換する関数 (3)英小文字であればそれを英大文字に、英大文字であればそれを英小文字に変換する関数 ただし、キーボードから入力された名前を格納する配列と、変換後の名前を格納する配列を別にする。 また、名前は関数main()内で表示する。 #include <ctype.h> #include <stdio.h> void name_toupper(char istr[], char ostr[]) { unsigned i = 0; while (istr[i]) { ostr[i] = toupper(istr[i]); i++; } } void name_tolower(char istr[], char ostr[]) { unsigned i = 0; while (istr[i]) { ostr[i] = tolower(istr[i]); i++; } } void name_change(char istr[], char ostr[]) { unsigned i = 0; while (istr[i]) { if(isupper(istr[i])) { ostr[i] = toupper(istr[i]); } else { ostr[i] = tolower(istr[i]); } i++; } } int main(void) { char buffer[100]; printf("文字"); gets(buffer); name_toupper(buffer); printf("大文字: %s\n", buffer); name_tolower(buffer); printf("小文字: %s\n", buffer); name_change(buffer); printf("大小交換: %s\n", buffer); return 0; } 上のプログラムでは、呼び出し時のパラメータが足りないとエラーが発生してしまいます。文字列を入れておく配列をbuffer以外にもう一つ作らなくてはいけないと思うのですが、うまくいきません。 教えてください。よろしくお願いします。

  • (C言語)プログラムが動きません。

    下のC言語のプログラムを書いたのですが、動きません。上手く作動していれば画面に「結果をrunge1.csvに書き込みました」と表示されてテキストファイルが作成されるはずですが、プログラムを実行しても何のメッセージも表示されずファイルも作成されません。ですが、bcpadのエラーメッセージの欄には何も表示されず、どこを直せばいいのか分かりません。アドバイスを下さい。お願いします。 /*ルンゲ・クッタ法による微分方程式y'+y*y=xの解*/ #include<stdio.h> #include<math.h> #define N 100 int main(void) { char *file="runge1.csv"; double x0=0.0,x1=5.0,y0=0.0,x,y,h,k1,k2,k3,k4; int i; FILE *fp; h=(x0-x1)/N; x=x0; y=y0; fp=fopen(file,"w"); fprintf(fp,"x,Runge-y\n"); fprintf(fp,"%3.2f,%3.5f\n",x,y); for(i=1;i<=N;i++){ x+=h; k1=(x-y*y)*h; k2=(x-y*y+k1/2.0)*h; k3=(x-y*y+k2/2.0)*h; k4=(x-y*y+k3)*h; y=(x-y*y)+(k1+2*k2+2*k3+k4)/6.0; fprintf(fp,"%3.2f,%3.5f\n",x,y); } fclose(fp); printf("結果を%sに書き込みました。\n",file); return(0); }

  • C言語、行列の積を求めるプログラムについて

    「次に示す行列x,yの積を求めるプログラムを作成せよ。   x[2][3]={{1,2,3},{4,5,6}} y=[3][2]={{1,5},{5,3},{81}}」 という問題です。自分ではとりあえず、 #include<stdio.h> int main(void) { int i,j; int x[2][3]={{1,2,3},{4,5,6}}; int y[3][2]={{1,5},{5,3},{8,1}}; int xy[3][3]={0}; for(i=0;i<3;i++) for(j=0;j<3;j++) xy[i][j]=x[i][j]*y[i][j]; for(i=0;i<3;i++){ for(j=0;j<3;j++) printf("%3d",xy[i][j]); putchar('\n'); } return 0; } というプログラムを作ってみましたが、ダメでした。 ちゃんと積の表示が出るようにするにはどこをどう変えるべきでしょうか?

専門家に質問してみよう