/* * ***************************************************************** * * * * * Copyright (c) Fast Corporation, 1997 * * * * * * All Rights Reserved. Unpublished rights reserved under * * * the copyright laws of the Japan. * * * * * * The software contained on this media is proprietary to * * * and embodies the confidential technology of Fast * * * Corporation. Possession, use, duplication or * * * dissemination of the software and media is authorized only * * * pursuant to a valid written license from Fast Corporation. * * * * * ***************************************************************** */ /* CSC90X 濃度ヒストグラム測定 HISTLIST.C */ /*[作成者]S.Kodama */ /* 目的: 関数: 履歴: Ver 1.0 97/11/10 Ver 1.1 99/10/28 セーブデータ名称を変更 注記:m_menu.hをインクルードして下さい。 m_menu.c及びm_note.cをリンクして下さい。 */ /* * Include compiler runtime library */ #include #include /* * Include CSC90X library */ #include "f_stdlib.h" #include "f_time.h" #include "f_gui.h" #include "f_stdio.h" #include "f_graph.h" #include "f_image.h" #include "f_pinf.h" #include "f_video.h" #include "f_system.h" #include "f_file.h" #include "f_bgray.h" /* * Include CSC90X common local */ #include "m_menu.h" /* * プロトタイプ宣言 */ void main( void ); void main_menu_disp( void ); void disp_help( void ); int Initialize( void ); /* プログラム起動時の初期化 */ void Close( void ); /* プログラム終了処理 */ void Parameter_set( void ); /* パラメータ類の設定 */ void P_min( void ); /* 計測範囲最小濃度値 */ void P_max( void ); /* 計測範囲最大濃度値 */ void P_divide( void ); /* 計測範囲分割数 */ void P_save( void ); /* 設定値保存 */ void P_graph( void ); /* ヒストグラム表示 */ void Execute( void ); /* 測定実行 */ extern int message_note( void ); /* * メニュー項目 */ #define LANG_N 2 #define MAIN_MENU_N 4 static const char *str_main_menu[MAIN_MENU_N][LANG_N] = { { " SET ", " 設 定 " }, { " EXEC ", " 実 行 " }, { " PROC3 ", " 処理3 " }, { " PROC4 ", " 処理4 " } }; #define INIT_CUR_POS_X 255 #define INIT_CUR_POS_Y 239 #define MAX_DIVIDE 28 /* 最大分割数 */ /*--------------------------------------*/ /* 内容保持(ファイル化)パラメータ群 */ /*--------------------------------------*/ static struct SAVE_DATA { int min_level; /* 測定範囲の最小濃度レベル:0〜255 */ int max_level; /* 測定範囲の最大濃度レベル:0〜255 */ int divide; /* 測定範囲の分割数:1〜MAX_DIVIDE */ } *userp; /*--------------------------------*/ /* (サブルーチン間)共用エリア */ /*--------------------------------*/ static int memory_no1; /* 濃淡画像メモリ番号1 */ static unsigned char *memory_no1_address; /* 濃淡画像メモリ番号1ベースアドレス */ static int memory_no2; /* 濃淡画像メモリ番号2 */ static unsigned char *memory_no2_address; /* 濃淡画像メモリ番号2ベースアドレス */ /* * メイン */ void main( void ) { int sts; int xpos; int ypos; int s_xpos; int s_ypos; /* 初期メッセージ表示 */ if( NORMAL_RETURN != message_note() ) return; /* パラメタ初期化 */ xpos = INIT_CUR_POS_X; ypos = INIT_CUR_POS_Y; s_xpos = INIT_CUR_POS_X; s_ypos = INIT_CUR_POS_Y; /* 入力ビデオ制御 */ Lib_input_video_control( GRAY_PLANE ); /* ビデオ出力表示項目制御 */ Lib_display_control( GRAY_PLANE | LINE_PLANE | CHAR_PLANE ); /* ビデオ表示項目クリア */ Lib_memory_clear( LINE_PLANE | CHAR_PLANE ); /* カーソル初期化 */ Lib_init_cursor(); /* メインメニューの表示 */ main_menu_disp(); /* マウスカーソルの表示 */ Lib_draw_cursor( INIT_CUR_POS_X, INIT_CUR_POS_Y ); if( -1 == Initialize() ) return; /* イニシャライザが -1=ERRORを返答したらオシマイ */ /* メニュー制御 */ for (;;) { sts = 0; /* マウス位置読みとり */ sts = Lib_see_current_position( &xpos, &ypos ); if ( s_xpos != xpos || s_ypos != ypos ) { /* マウス表示位置移動 */ Lib_move_cursor( xpos, ypos ); s_xpos = xpos; s_ypos = ypos; } /* 処理振り分け */ if( CURSOR_EXECUTE == sts ) { if ( xpos > MENU_1_XS && xpos < MENU_1_XE && ypos > MENU_1_YS && ypos < MENU_1_YE ) { Lib_memory_clear( LINE_PLANE | CHAR_PLANE ); Parameter_set( ); /*設定*/ Lib_memory_clear( LINE_PLANE | CHAR_PLANE ); main_menu_disp(); } else if ( xpos > MENU_2_XS && xpos < MENU_2_XE && ypos > MENU_2_YS && ypos < MENU_2_YE ) { Lib_memory_clear( LINE_PLANE | CHAR_PLANE ); Execute( ); /*実行*/ Lib_memory_clear( LINE_PLANE | CHAR_PLANE ); main_menu_disp(); } else if ( xpos > MENU_H_XS && xpos < MENU_H_XE && ypos > MENU_H_YS && ypos < MENU_H_YE ) { Lib_memory_clear( LINE_PLANE | CHAR_PLANE ); disp_help(); /* ヘルプ */ main_menu_disp(); } else if ( xpos > MENU_E_XS && xpos < MENU_E_XE && ypos > MENU_E_YS && ypos < MENU_E_YE ) { break; /* 終了 */ } } } Close(); } /* * メインメニュー表示 */ static void main_menu_disp( void ) { int iLanguage; /* 日本語/英語表示文字列切替情報取得 */ iLanguage = Lib_get_disp_language(); /* 整列キー表示 -> ( m_menu.c ) */ SUB_menu_disp4he( (char *)str_main_menu[0][iLanguage], (char *)str_main_menu[1][iLanguage], (char *)NULL, (char *)NULL ); } /* * ヘルプ表示 */ static void disp_help( void ) { Lib_chrdisp( 10, 8, "【機能\概要】 HISTLIST" ); Lib_chrdisp( 11, 10, "<濃度ヒストグラム測定>" ); Lib_chrdisp( 11, 12, "指定した条件にて一覧表\を表\示します。" ); } /*============================================================*/ /*  初期処理、初期設定                   */ /*============================================================*/ int Initialize() { long size; size = (long)sizeof( struct SAVE_DATA ); if( NULL == ( userp = (void *)Lib_mlalloc( size )) ) /* パラメータ用メモリを確保 */ { Lib_invdisp( 2, 10, "ERROR:ユーザーパラメータ領域が確保できない。 動作不能!" ); Lib_time_delay( 5000 ); return( -1 ); } if( 0L == Lib_fload( "\\FS0\\HIST.DAT", (char *)userp, size ) ) /* 保存データを呼び出す */ { /* 保存データが無かったらデフォルト値で起動 */ userp->min_level = 0; /* 測定範囲の最小濃度レベル:デフォルト値=0 */ userp->max_level = 255; /* 測定範囲の最大濃度レベル:デフォルト値=255 */ userp->divide = 1; /* 測定範囲の分割数:デフォルト値=1 */ } /* 1枚目の画像メモリ番号とアドレスを得る */ memory_no1 = Lib_get_gray_memory(); memory_no1_address = (unsigned char *)Lib_adrs_gray_memory( memory_no1 ); /* 2枚目の画像メモリを新たに確保すると同時に番号とアドレスを得る */ if( ERROR_RETURN == ( memory_no2 = Lib_alloc_gray_memory() ) ) { Lib_invdisp( 2, 10, "ERROR:2枚目の画像メモリが確保できない。 動作不能!" ); Lib_time_delay( 5000 ); return( -1 ); } memory_no2_address = (unsigned char *)Lib_adrs_gray_memory( memory_no2 ); return( 0 ); } /*============================================================*/ /*  終了処理                   */ /*============================================================*/ void Close() { Lib_lfree( (char *)userp ); /* パラメータ用メモリの解放 */ Lib_free_gray_memory( memory_no2 ); /* 2枚目の画像メモリの解放 */ Lib_memory_clear( LINE_PLANE | CHAR_PLANE ); /* 文字、線画メモリをクリア */ Lib_freerun(); } /**************************************************************/ /**** パラメータ設定(メイン) ********************************/ /**************************************************************/ void Parameter_set() { char disp_buff[10]; int pad_level, w, h, no, id; Lib_memory_clear( LINE_PLANE | CHAR_PLANE ); Lib_get_standard_key_size( &w, &h ); /* メニューパッドのキーサイズを得る */ for(;;) { pad_level = Lib_view_open(); Lib_view_set_title( pad_level, "設定" ); Lib_view_set_null( pad_level, 5, 5, "最小値設定", 0 ); Lib_view_set_null( pad_level, 5, 35, "最大値設定", 1 ); Lib_view_set_null( pad_level, 5, 65, "分割数設定", 2 ); Lib_view_set_null( pad_level, 5, 95, "セーブ", 3 ); /* 「コメント」で現在値を表示する */ Lib_sprintf( disp_buff, "%03d", userp->min_level ); Lib_view_set_comment( pad_level, w + 10, 5, disp_buff, 4 ); Lib_sprintf( disp_buff, "%03d", userp->max_level ); Lib_view_set_comment( pad_level, w + 10, 35, disp_buff, 5 ); Lib_sprintf( disp_buff, "%02d", userp->divide ); Lib_view_set_comment( pad_level, w + 10, 65, disp_buff, 6 ); Lib_view_set_size( pad_level, 15, 15, 8, 5 ); Lib_draw_command( pad_level ); no = Lib_process_command( pad_level ); if( 0 <= no && no <= 2 ) { /* 共通前処理 */ id = Lib_shelter_plane( 0, 0, 511, 479, CHAR_PLANE ); Lib_memory_clear( BIN_PLANE | LINE_PLANE | CHAR_PLANE ); Lib_display_control( BIN_PLANE | GRAY_PLANE | LINE_PLANE | CHAR_PLANE ); Lib_erase_cursor(); Lib_freeze( TRANSMIT ); /* 各キーの処理へ飛ぶ */ switch( no ) { case 0: P_min(); break; /* 測定範囲の最小濃度値設定へ飛ぶ */ case 1: P_max(); break; /* 測定範囲の最大濃度値設定へ飛ぶ */ case 2: P_divide(); break; /* 測定範囲の分割数設定へ飛ぶ */ } /* 後処理(表示状態を元に戻す) */ Lib_memory_clear( BIN_PLANE | LINE_PLANE | CHAR_PLANE ); Lib_display_control( GRAY_PLANE | LINE_PLANE | CHAR_PLANE ); Lib_recover_plane( id ); Lib_draw_cursor( 256, 240 ); Lib_freerun(); } if( 3 == no ) P_save(); /* データ保存ルーチンへ飛ぶ */ Lib_erase_menu( pad_level ); Lib_view_close( pad_level ); if( PAD_QUIT == no ) break; } } /*============================================================*/ /*  計測範囲の最小濃度値設定 */ /*============================================================*/ void P_min() { int x, y, key, old_x; P_graph(); /* ヒストグラム表示 */ Lib_line( userp->max_level + 50, 430, userp->max_level + 50, 170, DASHED_LINE ); /* 最大リミットを点線表示 */ x = userp->min_level; Lib_dispval( 21, 29, x ); key = 0; Lib_move_cursor( x, 430 ); /* トラックボールに連動して、直線(濃度レベルを表す)を動かす */ while( 0 == key ) { Lib_drawline( x + 50, 430, x + 50, 170 ); old_x = x; key = Lib_see_current_position( &x, &y ); if( old_x != x ) { Lib_erasline( old_x + 50, 430, old_x + 50, 170 ); if( userp->max_level <= x ) x = userp->max_level - 1; if( x < 0 ) x = 0; Lib_dispval( 21, 29, x ); } Lib_move_cursor( x, 430 ); } if( CURSOR_EXECUTE == key ) userp->min_level = x; } /*============================================================*/ /*  計測範囲の最大濃度値設定 */ /*============================================================*/ void P_max() { int x, y, key, old_x; P_graph(); /* ヒストグラム表示 */ Lib_line( userp->min_level + 50, 430, userp->min_level + 50, 170, DASHED_LINE ); x = userp->max_level; Lib_dispval( 21, 29, x ); key = 0; Lib_move_cursor( x, 430 ); /* トラックボールに連動して、直線(濃度レベルを表す)を動かす */ while( 0 == key ) { Lib_drawline( x + 50, 430, x + 50, 170 ); old_x = x; key = Lib_see_current_position( &x, &y ); if( old_x != x ) { Lib_erasline( old_x + 50, 430, old_x + 50, 170 ); if( x <= userp->min_level ) x = userp->min_level + 1; if( 255 < x ) x = 255; Lib_dispval( 21, 29, x ); } Lib_move_cursor( x, 430 ); } if( CURSOR_EXECUTE == key ) userp->max_level = x; } /*============================================================*/ /*  計測範囲の分割数設定 */ /*============================================================*/ void P_divide() { int x, y, i, div, old_div, key; double width, add, pitch; P_graph(); /* ヒストグラム表示 */ div = userp->divide; Lib_dispval( 21, 10, div ); width = (double)( userp->max_level - userp->min_level ); key = 0; Lib_move_cursor( div, 0 ); /* トラックボールに連動して、直線(分割位置を表す)を動かす */ while( 0 == key ) { if( 1 < div ) { add = pitch = width / (double)div; for( i = 1; i < div; i++ ) { x = (int)add + userp->min_level; Lib_drawline( x + 50, 430, x + 50, 170 ); add += pitch; } } Lib_box( userp->min_level + 50, 170, userp->max_level + 50, 430, SOLID_LINE ); old_div = div; key = Lib_see_current_position( &div, &y ); if( old_div != div ) { if( 1 < old_div ) { add = pitch = width / (double)old_div; for( i = 1; i < old_div; i++ ) { x = (int)add + userp->min_level; Lib_erasline( x + 50, 430, x + 50, 170 ); add += pitch; } } if( MAX_DIVIDE < div ) div = MAX_DIVIDE; if( div < 1 ) div = 1; Lib_dispval( 21, 10, div ); } Lib_move_cursor( div, 430 ); } if( CURSOR_EXECUTE == key ) userp->divide = div; } /*------------------------------------------------------------*/ /*  ヒストグラム表示(線画だけ2値画像メモリに描画する) */ /*------------------------------------------------------------*/ void P_graph() { static struct HISTDATA histp; char disp_buff[10]; int i, x, ys, ye, bin_mem_no; double div; bin_mem_no = Lib_get_bin_memory(); /* カレント2値メモリ番号を得る */ Lib_bin_memory_cls( bin_mem_no ); /* 2値画像メモリクリア */ Lib_histogram( memory_no1, &histp ); /* ヒストグラム測定 */ div = (double)histp.max_frequency / 260.0; /* グラフを画面に表示するための除数を得る */ Lib_xbline( bin_mem_no, WHITE_COLOR, 50, 430, 50, 170 ); /* グラフの縦線(基準線) */ Lib_xbline( bin_mem_no, WHITE_COLOR, 50, 430, 305, 430 ); /* グラフの横線(基準線) */ x = 50; /* 表示位置オフセット(X座標50画素から右方向へヒストグラムを描き込む) */ ys = (int)( (double)histp.hist_tbl[0] / div ); for( i = 1; i < 256; i++ ) { ye = (int)( (double)histp.hist_tbl[i] / div ); Lib_xbline( bin_mem_no, WHITE_COLOR, x, 430 - ys, x + 1, 430 - ye ); x++; ys = ye; } Lib_video_transmit( BIN_PLANE ); /* 描き込んだヒストグラムをモニタTVに表示 */ /* 数値データの表示 */ Lib_chrdisp( 7, 28, "0" ); Lib_chrdisp( 39, 28, "255" ); Lib_chrdisp( 20, 28, "濃度値" ); Lib_sprintf( disp_buff, "%6d", histp.max_frequency ); Lib_chrdisp( 1, 11, disp_buff ); Lib_chrdisp( 3, 18, "画" ); Lib_chrdisp( 3, 19, "素" ); Lib_chrdisp( 3, 20, "数" ); } /*============================================================*/ /*  データ・セーブ                */ /*============================================================*/ void P_save() { int id; /* グラフィック メモリ データ退避ID */ long size; Lib_erase_cursor(); id = Lib_shelter_plane( 0, 0, 511, 479, CHAR_PLANE ); Lib_memory_clear( LINE_PLANE | CHAR_PLANE ); Lib_display_comment( 100, 200, "全ての設定データをセーブ中・・・・・" ); size = (long)sizeof( struct SAVE_DATA ); if( 0L == Lib_fsave( "\\FS0\\HIST.DAT", (char *)userp, size ) ) { Lib_memory_clear( CHAR_PLANE ); Lib_invdisp( 2, 10, "ERROR:設定データ類がPCカードに保存できません。" ); Lib_time_delay( 5000 ); } Lib_memory_clear( LINE_PLANE | CHAR_PLANE ); Lib_recover_plane( id ); Lib_draw_cursor( 256, 240 ); } /**************************************************************/ /**** 計測処理 ************************************************/ /**************************************************************/ void Execute() { static struct HISTDATA histp; static char chr_buff[64]; int i, j, time; int end, total_pixel; static int level_step[MAX_DIVIDE][2], val[MAX_DIVIDE]; double width, add, pitch; Lib_erase_cursor(); /* カーサー(矢印)を消去 */ Lib_memory_clear( LINE_PLANE | CHAR_PLANE ); /* 線画プレーン & 文字プレーンをクリア */ Lib_strtclk_count(); /* 処理時間計測スタート */ Lib_freeze( TRANSMIT ); /* 入力画像凍結 & モニタTVへ表示 */ Lib_histogram( memory_no1, &histp ); /* ヒストグラム測定 */ for( i = 0; i < MAX_DIVIDE; i++ ) val[i] = 0; /* 結果テーブルをゼロ・クリア */ /* 各分割範囲毎の総画素数を抽出 */ width = (double)( userp->max_level - userp->min_level ); pitch = width / (double)userp->divide; add = (double)userp->min_level; total_pixel = 0; for( i = 0; i < userp->divide; i++ ) { j = (int)add; end = (int)( add + pitch); if( i != ( userp->divide - 1 ) ) end--; level_step[i][0] = j; level_step[i][1] = end; for( ; j <= end; j++ ) val[i] += histp.hist_tbl[j]; add += pitch; total_pixel += val[i]; } /* 測定結果を一覧表にして画面に表示 */ Lib_chrdisp( 1, 1, " 濃度範囲 画素 " ); Lib_drawline( 0, 0, 0, 16 * userp->divide + 32 ); Lib_drawline( 78, 0, 78, 16 * userp->divide + 32 ); Lib_drawline( 130, 0, 130, 16 * userp->divide + 32 ); for( i = 0; i < userp->divide + 3; i++ ) Lib_drawline( 0, i * 16, 128, i * 16 ); for( i = 0; i < userp->divide; i++ ) { Lib_sprintf( chr_buff, " %3d〜%3d ", level_step[i][0], level_step[i][1] ); Lib_chrdisp( 1, i + 2, chr_buff ); Lib_sprintf( chr_buff, "%6d", val[i] ); Lib_chrdisp( 11, i + 2, chr_buff ); } Lib_sprintf( chr_buff, "合計 %6d", total_pixel ); Lib_chrdisp( 6, userp->divide + 2, chr_buff ); /* 処理時間表示 */ time = ( Lib_readclk_count() * 8138 ) / 10000; Lib_sprintf( chr_buff, "処理時間=%dmsec", time ); Lib_chrdisp( 48, 1, chr_buff ); /* オペレータが[確認]キーをクリックするまで結果表示を維持 */ Lib_draw_cursor( 480, 460 ); Lib_display_keyinput( 460, 450, "確認" ); /* 画面をクリアしてオシマイ */ Lib_memory_clear( LINE_PLANE | CHAR_PLANE ); Lib_freerun(); }