/* * ***************************************************************** * * * * * 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 計算幾何学「点分布画像の高密度領域抽出」サンプル 90xnpc.c */ /*[作成者]G.Ochiai & A.Sekimori */ /*[概要] 2値メモリ上に疎密のばらつきがある点データを乱数で発生させます。 */ /* 各点に対して、一定距離以内にある点の数を求め、その数に関するしきい値によって、 */ /* 点分布の密なところを抽出します。 */ /* 結果は密なところにある点だけを残して表示することで表わされます。 */ /* 目的: 関数: 履歴: Ver 1.0 98/08/12 注記:m_menu.hをインクルードして下さい。 m_menu.c及びm_note.cをリンクして下さい。 */ /* Include compiler runtime library */ #include #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_cmpgeo.h" #include "f_math.h" #include "f_binmem.h" /* Include CSC90X common local */ #include "m_menu.h" /* プロトタイプ宣言 */ void main( void ); void main_menu_disp( void ); void disp_help( void ); extern int message_note( void ); static void determ_param( int *, int * ); static void get_binary_image( int ); static void execute( int, int, int ); static void display_points_data( WPNT2_T[ ], int ); static int get_dense_points( int[ ], int, int, int[ ] ); static void display_result( WPNT2_T[ ], int, int[ ], int ); /* メニュー項目 */ #define LANG_N 2 #define MAIN_MENU_N 3 static const char *str_main_menu[MAIN_MENU_N][LANG_N] = { { "SET PARAM ", " 設 定 " }, { "MAKE POINT", " 点群生成 " }, { " EXECUTE ", " 実 行 " }, }; #define INIT_CUR_POS_X 255 #define INIT_CUR_POS_Y 239 #define MAX_PNT_NUM 4096 #define DENSE_AREA_RDS 75 #define DENSE_AREA_NUM 6 #define DENSE_PNT_NUM 512 #define RANDOM_PNT_NUM 1024 #define X_LENGTH 3 /* メイン */ void main( void ) { int sts; int xpos; int ypos; int s_xpos; int s_ypos; int dist; /* 近くにある、と判断する距離 */ int thres; /* 密な所にある、とみなす為の点の数のしきい値 */ int bin_mem_no; /* 初期メッセージ表示 */ 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; dist = 10; thres = 15; /* ビデオ出力表示項目制御 */ Lib_display_control( BIN_PLANE | LINE_PLANE | CHAR_PLANE ); /* ビデオ表示項目クリア */ Lib_memory_clear( BIN_PLANE | LINE_PLANE | CHAR_PLANE ); /* カーソル初期化 */ Lib_init_cursor(); /* メインメニューの表示 */ main_menu_disp(); /* マウスカーソルの表示 */ Lib_draw_cursor( INIT_CUR_POS_X, INIT_CUR_POS_Y ); /* カレント2値メモリ番号 */ bin_mem_no = Lib_get_bin_memory( ); /* 2値メモリ上に点データを作成 */ /*get_binary_image( bin_mem_no );*/ /* メニュー制御 */ 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 ); /*「設定」が選択された */ determ_param( &dist, &thres ); 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 ); /*「点群生成」が選択された */ /* 2値メモリ上に点データを作成 */ get_binary_image( bin_mem_no ); Lib_memory_clear( LINE_PLANE | CHAR_PLANE ); main_menu_disp(); } else if ( xpos > MENU_3_XS && xpos < MENU_3_XE && ypos > MENU_3_YS && ypos < MENU_3_YE ) { Lib_memory_clear( LINE_PLANE | CHAR_PLANE ); /*「実行」が選択された */ execute( dist, thres, bin_mem_no ); 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; /* 終了 */ } } } } /* メインメニュー表示 */ 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 *)str_main_menu[2][iLanguage], (char *)NULL ); } /* ヘルプ表示 */ void disp_help( void ) { Lib_chrdisp( 4, 8, "【機能\概要】 90XNPC" ); Lib_chrdisp( 5, 10, "ビジョンツールライブラリ計算幾何学のサンプルソ\フトです。" ); Lib_chrdisp( 5, 12, "2値メモリ上に疎密のばらつきがある点データを乱数で発生" ); Lib_chrdisp( 5, 14, "させます。計算幾何学によって各点に対して、一定距離以内" ); Lib_chrdisp( 5, 16, "にある点の数を求め、その数に関するしきい値によって" ); Lib_chrdisp( 5, 18, "点分布の密なところを抽出します。" ); Lib_chrdisp( 5, 20, "【 設 定 】しきい値を設定します。" ); Lib_chrdisp( 5, 22, "【点群生成】乱数により点群を生成します。" ); Lib_chrdisp( 5, 24, "【 実 行 】抽出を実行します。" ); Lib_chrdisp( 5, 27, "※注意※ 点群生成を再実行しない限り前の点群で実行します。" ); } /***** パラメータの決定 *****/ static void determ_param( dist, thres ) int *dist; /* 点の近く、と定める距離 */ int *thres; /* 密な点、と認める点の数のしきい値 */ { int no; /* 実行キーまたは取消キーの入力情報 */ int pad_level; /* パッドレベル */ PVAL value[2]; /* 各メニューの値 */ Lib_cls( ( LINE_PLANE | CHAR_PLANE ), BLACK_COLOR ); /* パッドのオープン */ pad_level = Lib_view_open( ); /* パッドのタイトル */ Lib_view_set_title( pad_level, "パラメータ" ); /* モード・キーの表示 */ Lib_view_set_uniq_numeral( pad_level, 30, 5, "距離(半径)", *dist, 1L, 50L, 0 ); Lib_view_set_uniq_numeral( pad_level, 30, 35, "点数下限値", *thres, 1L, 100L, 1 ); /* パッドの位置、右マージン、下マージンの設定 */ Lib_view_set_size( pad_level, 15, 15, 30, 5 ); /* パッドの表示 */ Lib_draw_menu( pad_level ); if ( ERROR_RETURN != ( no = Lib_process_menu( pad_level, value ) ) ) /* メニュー値の取得 */ { switch( no ) { case 101: /*「実行」が選択された */ *dist = value[0].value_type; *thres = value[1].value_type; break; case 102: /*「取り消し」が選択された */ break; } } /* パッドの消去 */ Lib_erase_menu( pad_level ); /* パッドのクローズ */ Lib_view_close( pad_level ); } /***** 2値メモリ上に点データを作成 *****/ static void get_binary_image( bin_mem_no ) int bin_mem_no; /* 2値画像メモリ番号 */ { int fx, fy; int sx, sy, ex, ey; int cx, cy; int r, q; int x, y; int n, i; unsigned int *bin_base_adrs; /* フリーズ */ Lib_freeze( NOT_TRANSMIT ); /* 2値メモリのクリア */ Lib_bin_memory_cls( bin_mem_no ); /* 2値メモリの先頭アドレス */ bin_base_adrs = ( unsigned int * )Lib_adrs_bin_memory( bin_mem_no ); /* 画像の大きさ */ fx = Lib_get_fx_size( ); fy = Lib_get_fy_size( ); /* 点の分布範囲 */ sx = 0; sy = 0; ex = fx - 1; ey = fy - 1; /* 密な場所の点データ作成 */ for( n = 0 ; n < DENSE_AREA_NUM ; n ++ ) { /* 中心の位置を乱数で決定 */ cx = rand( )%( fx - 2 * DENSE_AREA_RDS ) + DENSE_AREA_RDS; cy = rand( )%( fy - 2 * DENSE_AREA_RDS ) + DENSE_AREA_RDS; /* 各点の作成 */ for( i = 0 ; i < DENSE_PNT_NUM ; i ++ ) { r = rand( )% DENSE_AREA_RDS; q = rand( )% 3600; x = r * Lib_cosfunc( q )/ 32767 + cx; y = r * Lib_sinfunc( q )/ 32767 + cy; Lib_write_bin_pixel( bin_base_adrs, x, y, WHITE_COLOR ); } } /* ランダムノイズの発生 */ for( i = 0 ; i < RANDOM_PNT_NUM ; i ++ ) { x = rand( )% fx; y = rand( )% fy; Lib_write_bin_pixel( bin_base_adrs, x, y, WHITE_COLOR ); } /* 2値画像の表示 */ Lib_video_transmit( BIN_PLANE ); } /***** 実行 *****/ static void execute( dist, thres, bin_mem_no ) int dist; /* 近くにある、と判断する距離 */ int thres; /* 密な所にある、とみなす為の点の数のしきい値 */ int bin_mem_no; /* 2値画像メモリ番号 */ { WPNT2_T *pnts; /* 点データ */ int pnt_num; /* 点データの点の数 */ int sx, sy, ex, ey; /* 処理範囲 */ int *num_tbl; /* 一定距離(=dist)以内にある点の数の一覧表 */ int *dns_pnt_tbl; /* 密な所にある点の番号表 */ int dns_pnt_num; /* その番号表に含まれる点の数 */ /* 処理範囲;全面 */ sx = 0; sy = 0; ex = Lib_get_fx_size( ) - 1; ey = Lib_get_fy_size( ) - 1; Lib_window( sx, sy, ex, ey ); /* 画面のクリア */ Lib_cls( ( BIN_PLANE | LINE_PLANE | CHAR_PLANE ), BLACK_COLOR ); /* 点データ格納バッファの確保 */ if( NULL != ( pnts = ( WPNT2_T * )Lib_mlalloc( sizeof( WPNT2_T )* MAX_PNT_NUM ) ) ) { /* 回答番号表の確保 */ if( NULL != ( num_tbl = ( int * )Lib_mlalloc( sizeof( int )* MAX_PNT_NUM ) ) ) { /* 回答番号表の確保 */ if( NULL != ( dns_pnt_tbl = ( int * )Lib_mlalloc( sizeof( int )* MAX_PNT_NUM ) ) ) { /* 2値画像から点データを取得 */ pnt_num = Lib_cg_get_data_from_binmem( bin_mem_no, sx, sy, ex, ey, WHITE_COLOR, pnts, MAX_PNT_NUM ); /* 処理時間測定開始 */ Lib_strtclk_count( ); /* 主処理;一定距離(=dist)以内にある点の数の一覧表の作成 */ Lib_cg_2d_near_pnts_count( pnts, pnt_num, dist, RASTER_SCAN_ORDER, num_tbl ); /* 主処理2;一定距離(=dist)以内にある点の数が thres 以上のものを選択 */ dns_pnt_num = get_dense_points( num_tbl, pnt_num, thres, dns_pnt_tbl ); /* 処理時間測定終了・表示 */ Lib_time_disp( 300, 450 ); /* 回答を表示する */ display_result( pnts, pnt_num, dns_pnt_tbl, dns_pnt_num ); Lib_display_keyinput( 460, 0, "確認" ); /* 回答番号表の解放 */ Lib_lfree( ( BYTE * )dns_pnt_tbl ); } else Lib_display_message( 100, 200, "エラー", "ワークメモリを確保できませんでした。" ); /* 回答番号表の解放 */ Lib_lfree( ( BYTE * )num_tbl ); } else Lib_display_message( 100, 200, "エラー", "ワークメモリを確保できませんでした。" ); /* 点データ格納バッファの解放 */ Lib_lfree( ( BYTE * )pnts ); } else Lib_display_message( 100, 200, "エラー", "ワークメモリを確保できませんでした。" ); } /***** 一定距離(=dist)以内にある点の数が thres 以上のものを選択 *****/ static int get_dense_points( num_tbl, pnt_num, thres, dns_pnt_tbl ) int num_tbl[ ]; /* 各点の近傍点数表 */ int pnt_num; /* 点の全数 */ int thres; /* 密、と判定するしきい値 */ int dns_pnt_tbl[ ]; /* 密、と判定された点の番号表 */ { int dns_pnt_num; /* 選択された点の数 */ int i; /* 点の選択 */ for( i = 0, dns_pnt_num = 0 ; i < pnt_num ; i ++ ) { if( thres <= num_tbl[ i ] ) { dns_pnt_tbl[ dns_pnt_num ++ ] = i; } } /* 選択された点の数を返す */ return( dns_pnt_num ); } /***** 回答を表示する *****/ static void display_result( pnts, pnt_num, dns_pnt_tbl, dns_pnt_num ) WPNT2_T pnts[]; /* 点データ */ int pnt_num; /* 点データの数 */ int dns_pnt_tbl[]; /* 密な点の番号表 */ int dns_pnt_num; /* 密な点の数 */ { char str[ 64 ]; int crs_x, crs_y; int i; /* カーソルの消去 */ Lib_look_current_position( &crs_x, &crs_y ); Lib_erase_cursor( ); /* 元データを消去 */ Lib_cls( LINE_PLANE, BLACK_COLOR ); /* 密な場所にある点のみ表示 */ for( i = 0 ; i < dns_pnt_num ; i ++ ) { /* 密なところにある点の座標 */ Lib_pset( pnts[ dns_pnt_tbl[ i ] ].x, pnts[ dns_pnt_tbl[ i ] ].y, GRAPH_DRAW ); } /* 点の数の表示 */ Lib_sprintf( str, "pnt num = %5d", pnt_num ); Lib_chrdisp( 1, 29, str ); Lib_sprintf( str, "dns pnt num = %5d", dns_pnt_num ); Lib_chrdisp( 1, 30, str ); /* カーソルの復帰 */ Lib_draw_cursor( crs_x, crs_y ); }