/* * ***************************************************************** * * * * * 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 直線検出ハフ変換 HOUGH.C */ /*[作成者]K.Masuda */ /* 目的: 関数: 履歴: Ver 1.0 97/11/11 Ver 2.0 99/05/13 しきい値設定中にハングアップする不具合を修正 パラダイム関数の中で画像メモリを確保していて そのメモリ番号の変数がローカル変数だったため Ver 3.0 2001/09/21 PNT_T,BOX_TをMY_PNT_T,MY_BOX_Tに変更し、本ソ             ース内で定義。 注記:m_menu.hをインクルードして下さい。 m_menu.c及びm_note.cをリンクして下さい。 */ /*#define FILE_MODE*/ /* ファイルから読み込むときにはコメントを取る */ /* * 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_filter.h" #include "f_hough.h" #include "f_file.h" /* * Include CSC90X common local */ #include "m_menu.h" /* 画質定義 */ typedef enum { GOOD_IMAGE, BAD_IMAGE, WORST_IMAGE, IMAGE_N } IMAGE_T; typedef struct { int x; int y; } MY_PNT_T; typedef struct { MY_PNT_T st; MY_PNT_T ed; } MY_BOX_T; /* * プロトタイプ宣言 */ void main( void ); void main_menu_disp( void ); void disp_help( void ); void exec( void ); int wait_keyin( void ); void draw_box( int, int, int, int ); void erase_box( int, int, int, int ); void smp_time_disp( int, int, char * ); void edge_test( int, int, PARADIGM * ); void detect_edge( IMAGE_T, int, int, MY_BOX_T *, int, int, int ); void detect_edge_for_any_cross( int, int, MY_BOX_T *, int, int, int ); void detect_edge_for_lg_filter( IMAGE_T, int, int, MY_BOX_T *, int, int, int ); int create_region( MY_BOX_T * ); IMAGE_T get_image_condition( void ); void my_freeze( int ); void set_param_for_edge_test( MY_BOX_T *, IMAGE_T ); void draw_calc_line( double, double ); int get_parameter( int *, int *, int *, int *, int *, int * ); int hough_exec( int, int, int, int, HLINE_T * ); unsigned int get_rand( void ); int display_elapsed_time( int, int, char * ); extern int message_note( void ); /* * メニュー項目 */ #define LANG_N 2 #define MAIN_MENU_N 4 const char *str_main_menu[MAIN_MENU_N][LANG_N] = { { " EXEC ", " 実 行 " }, { " PROC2 ", " 処理2 " }, { " PROC3 ", " 処理3 " }, { " PROC4 ", " 処理4 " } }; #define INIT_CUR_POS_X 255 #define INIT_CUR_POS_Y 239 #define FX_SIZE 512 /* X方向分解能 */ #define FY_SIZE 480 /* Y方向分解能 */ #define XS_LIMIT 2 #define YS_LIMIT 2 #define XE_LIMIT ( FX_SIZE - 1 - XS_LIMIT ) #define YE_LIMIT ( FY_SIZE - 1 - YS_LIMIT ) #define MENU_START_X 50 /* メニュー表示パッド始点X座標 */ #define MENU_START_Y 80 /* メニュー表示パッド始点Y座標 */ #define ERR_START_X 50 /* エラー表示パッド始点X座標 */ #define ERR_START_Y 80 /* エラー表示パッド始点Y座標 */ #define MARGIN 5 /* パッド上のキーのマージン */ #define LARGE_CONV_SIZE 5 /* 大きいほうのコンボルバの幅 */ #define SMALL_CONV_SIZE 3 /* 小さいほうのコンボルバの幅 */ #define SIGMA_COEFF (5.0/255.0) /* LGフィルタのσに対する補正係数 */ #define NEIB_VAL 4 /* 同上処理で使う近傍値 */ #define EDGE_DENS 255 /* エッジにしたときの濃度 */ #define BUFF_SIZE 60 typedef enum { NO_TOUCH, /* 下記の両キーとも押下されない */ EXECUTE, /* EXECUTE キー(左側キー)押下 */ CANCEL /* CANCEL キー(右側キー)押下 */ } BTN_T; int counter; static unsigned int next; /* ランダム発生用 */ int disp_mem2; /* * メイン */ 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; next = 0; /* 入力ビデオ制御 */ 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 ); /* メニュー制御 */ 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 ); Lib_time_delay( 500 ); exec( ); /*実行*/ 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; /* 終了 */ } } } Lib_window( 0, 0, 511, 479 ); } /* * メインメニュー表示 */ 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 *)NULL, (char *)NULL, (char *)NULL ); } /* * ヘルプ表示 */ void disp_help( void ) { Lib_chrdisp( 10, 8, "【機能\概要】 HOUGH" ); Lib_chrdisp( 11, 10, "直線検出ハフ変換" ); } /* * 実行 */ void exec() { int convolver[LARGE_CONV_SIZE*LARGE_CONV_SIZE]; /* LGフィルタの係数 */ int conv_size; /* コンボルバサイズ */ int multiplier; /* LGフィルタの倍率 */ double sigma; /* LGフィルタのσ値 */ HLINE_T line_coeff[MAX_LINE_N]; int disp_mem; MY_BOX_T area; int i, process; double b, m; int wb; int line_n, random_n, region_r, region_q, thresh; int keep_cur_mem, keep_xs, keep_ys, keep_xe, keep_ye; int get_line_n; IMAGE_T image; int cur_mem, wrk_mem, display; counter = 0; if( ERROR_RETURN != ( disp_mem = Lib_alloc_gray_memory() ) ) { cur_mem = Lib_get_gray_memory(); Lib_freerun(); for( process = ON; ON == process; ) { Lib_gray_memory_cls( cur_mem ); Lib_gray_memory_cls( disp_mem ); Lib_chrdisp( 1, 1, "抽出エリア設定" ); if( OFF == create_region( &area ) ) { Lib_free_gray_memory( disp_mem ); return; } draw_box( area.st.x, area.st.y, area.ed.x, area.ed.y ); Lib_chrdisp( 1, 1, " " ); image = get_image_condition(); if( WORST_IMAGE == image || BAD_IMAGE == image || GOOD_IMAGE == image ) { set_param_for_edge_test( &area, image ); if( ON == get_parameter( &get_line_n, &random_n, ®ion_r, ®ion_q, &thresh, &display ) ) { if( BAD_IMAGE == image || WORST_IMAGE == image ) { conv_size = ( WORST_IMAGE == image ) ? LARGE_CONV_SIZE : SMALL_CONV_SIZE; sigma = ( double )thresh * SIGMA_COEFF; Lib_get_convolver( conv_size, sigma, convolver, &multiplier ); } my_freeze( NOT_TRANSMIT ); Lib_strtclk_count(); Lib_gray_memory_cls( disp_mem ); Lib_set_stage_window( area.st.x, area.st.y, area.ed.x, area.ed.y ); if( WORST_IMAGE == image || BAD_IMAGE == image ) { if( ERROR_RETURN != ( wrk_mem = Lib_alloc_gray_memory() ) ) { Lib_gray_memory_cls( wrk_mem ); if( WORST_IMAGE == image ) Lib_lg_filter( cur_mem, wrk_mem, convolver, multiplier, 5 ); else Lib_lg_filter( cur_mem, wrk_mem, convolver, multiplier, 3 ); Lib_set_stage_window( area.st.x + conv_size / 2, area.st.y + conv_size / 2, area.ed.x - conv_size / 2, area.ed.y - conv_size / 2 ); Lib_zero_cross( wrk_mem, disp_mem, NEIB_VAL, EDGE_DENS ); Lib_free_gray_memory( wrk_mem ); } else Lib_any_cross( cur_mem, disp_mem, NEIB_VAL, thresh, EDGE_DENS ); } else Lib_any_cross( cur_mem, disp_mem, NEIB_VAL, thresh, EDGE_DENS ); display_elapsed_time( 1, 1, "エッジ抽出" ); if( area.st.x < XS_LIMIT ) area.st.x = XS_LIMIT; if( area.st.y < YS_LIMIT ) area.st.y = YS_LIMIT; if( area.ed.x > XE_LIMIT ) area.ed.x = XE_LIMIT; if( area.ed.y > YE_LIMIT ) area.ed.y = YE_LIMIT; Lib_strtclk_count(); if( ON == display ) Lib_xvideo_transmit( disp_mem, GRAY_PLANE ); keep_cur_mem = Lib_get_gray_memory(); Lib_get_stage_window( &keep_xs, &keep_ys, &keep_xe, &keep_ye ); Lib_change_gray_memory( disp_mem ); Lib_set_stage_window( area.st.x, area.st.y, area.ed.x, area.ed.y ); line_n = hough_exec( get_line_n, random_n, region_r, region_q, line_coeff ); Lib_change_gray_memory( keep_cur_mem ); Lib_set_stage_window( keep_xs, keep_ys, keep_xe, keep_ye ); display_elapsed_time( 1, 2, "ハフ変換" ); if( 0 <= line_n ) { for( i = 0; i < line_n; i++ ) { if( line_coeff[i].b == 0 ) { b = - ( double )line_coeff[i].c * 4096.0 / ( double )line_coeff[i].a; wb = ( int )b; Lib_drawline( wb, 0, wb, Lib_get_fy_size() - 1 ); } else { m = - ( double )line_coeff[i].a / ( double )line_coeff[i].b; b = - ( double )line_coeff[i].c * 4096.0 / ( double )line_coeff[i].b; draw_calc_line( m, b ); } } } else { switch( line_n ) { case HERR_PARAMETER: Lib_display_message( ERR_START_X, ERR_START_Y, "エラー", "パラメータに誤りがあります。" ); break; case HERR_INITIALIZE: Lib_display_message( ERR_START_X, ERR_START_Y, "エラー", "初期化を失敗しました。" ); break; case HERR_CALCULATE: Lib_display_message( ERR_START_X, ERR_START_Y, "エラー", "計算出来ませんでした。" ); break; case HERR_TERMINATE: Lib_display_message( ERR_START_X, ERR_START_Y, "エラー", "終了処理に失敗しました。" ); break; } } if( CANCEL == wait_keyin() ) process = OFF; else { Lib_freerun(); Lib_memory_clear( LINE_PLANE | CHAR_PLANE ); } } else erase_box( area.st.x, area.st.y, area.ed.x, area.ed.y ); } else erase_box( area.st.x, area.st.y, area.ed.x, area.ed.y ); } Lib_free_gray_memory( disp_mem ); } Lib_freerun(); } /* * 直線係数から直線描画 */ void draw_calc_line( a, b ) double a; /* 入力:傾き */ double b; /* 入力:y切片 */ /*[関数値] なし */ /*[処理概要] y = a * x + bから直線を描画する。 */ /*[注記] なし */ { double d_x, d_y; int x, y; int width, height; int xs_conc, ys_conc, xe_conc, ye_conc; int x_disp, y_disp; /* ビデオ座標系の諸パラメータの取得 */ width = Lib_get_fx_size(); height = Lib_get_fy_size(); /* 関心座標系の諸パラメータの取得 */ xs_conc = 0; ys_conc = 0; xe_conc = width; ye_conc = height; if( - 1.0 <= a && a <= 1.0 ) { for( x = xs_conc; x <= xe_conc; x++ ) { d_x = ( double )x; d_y = a * d_x + b; y = ( int )d_y; x_disp = x; y_disp = y; Lib_pset( x_disp, y_disp, GRAPH_DRAW ); } } else { for( y = ys_conc; y <= ye_conc; y++ ) { d_y = ( double )y; d_x = d_y / a - b / a; x = ( int )d_x; x_disp = x; y_disp = y; Lib_pset( x_disp, y_disp, GRAPH_DRAW ); } } } /* * 条件設定 */ int get_parameter( line, random_n, same_line_r, same_line_q, bias, disp ) int *line; int *random_n; int *same_line_r; int *same_line_q; int *bias; int *disp; { int no; int pad_level; PVAL value[6]; int active; active = OFF; if( 0 == counter ) { /* システム既定値 */ *line = 1; *same_line_r = 5; *same_line_q = 5; *random_n = 1; *bias = 128; *disp = ON; } pad_level = Lib_view_open(); Lib_view_set_title( pad_level, "パラメータ" ); Lib_view_set_uniq_numeral( pad_level, 5, 5, "抽出本数" , ( long )*line , 1L, 99L, 0 ); Lib_view_set_uniq_numeral( pad_level, 5, 35, "ρ方向領域" , ( long )*same_line_r, 1L, 99L, 1 ); Lib_view_set_uniq_numeral( pad_level, 5, 65, "θ方向領域" , ( long )*same_line_q, 1L, 99L, 2 ); Lib_view_set_uniq_numeral( pad_level, 5, 95, "間引き係数" , ( long )*random_n , 1L, 99L, 3 ); Lib_view_set_uniq_numeral( pad_level, 5, 125, "しきい値" , ( long )*bias , 6L, 255L, 4 ); Lib_view_set_uniq_alter ( pad_level, 5, 155, "エッジ表\示", *disp , 5 ); Lib_set_paradigm( pad_level, 4, WHOLE_TIMING, edge_test ); Lib_view_set_size( pad_level, MENU_START_X, MENU_START_Y, MARGIN, MARGIN ); Lib_draw_menu( pad_level ); if( ERROR_RETURN != ( no = Lib_process_menu( pad_level, value ) ) ) { switch( no ) { case 101: /* select " EXEC " */ *line = ( int )value[0].value_type; *same_line_r = ( int )value[1].value_type; *same_line_q = ( int )value[2].value_type; *random_n = ( int )value[3].value_type; *bias = ( int )value[4].value_type; *disp = ( int )value[5].on_off_type; active = ON; break; case 102: /* select "CANC" */ break; } } Lib_erase_menu( pad_level ); Lib_view_close( pad_level ); counter++; return( active ); } /***************************************************************************************/ /***** エッジ関連 *****/ /***************************************************************************************/ /* エッジ検出テストのためのエリア設定 */ struct { MY_BOX_T area; /* エッジ検出範囲 */ IMAGE_T image; /* 画質(これによりフィルタが変わる)*/ } edge_param; /* 上記情報エリアへの入力 */ void set_param_for_edge_test( area, image ) MY_BOX_T *area; /* 入力:エッジ検出範囲 */ IMAGE_T image; /* 入力:画質 */ { edge_param.area = *area; edge_param.image = image; } /* エッジ検出テスト */ void edge_test( timing, numb, val ) int timing; int numb; PARADIGM val[]; { int thresh; int cur_mem; switch( timing ) { case START_TIMING: if( ERROR_RETURN != ( disp_mem2 = Lib_alloc_gray_memory() ) ) { Lib_gray_memory_cls( disp_mem2 ); my_freeze( NOT_TRANSMIT ); cur_mem = Lib_get_gray_memory(); thresh = ( int )val[0].long_type; my_freeze( NOT_TRANSMIT ); detect_edge( edge_param.image, cur_mem, disp_mem2, &edge_param.area, NEIB_VAL, thresh, EDGE_DENS ); Lib_xvideo_transmit( disp_mem2, GRAY_PLANE ); } break; case PROCESS_TIMING: if( ERROR_RETURN != disp_mem2 ) { cur_mem = Lib_get_gray_memory(); thresh = ( int )val[0].long_type; my_freeze( NOT_TRANSMIT ); detect_edge( edge_param.image, cur_mem, disp_mem2, &edge_param.area, NEIB_VAL, thresh, EDGE_DENS ); Lib_xvideo_transmit( disp_mem2, GRAY_PLANE ); } break; case END_TIMING: if( ERROR_RETURN != disp_mem2 ) { Lib_freerun(); Lib_free_gray_memory( disp_mem2 ); } break; } } /* エッジ検出 */ void detect_edge( image, src_mem, dst_mem, area, neib, thresh, val ) IMAGE_T image; /* 入力:画質 */ int src_mem; /* 入力:変換前の濃淡プレーン */ int dst_mem; /* 入力:変換後の濃淡プレーン */ MY_BOX_T *area; /* 入力:処理領域 */ int neib; /* 入力:4近傍(=4)または8近傍(=8)の別 */ int thresh; /* 入力:バイアス(0とみなす値) */ int val; /* 入力:エッジの際に入れる値 */ { Lib_set_stage_window( area->st.x, area->st.y, area->ed.x, area->ed.y ); if( GOOD_IMAGE == image ) detect_edge_for_any_cross( src_mem, dst_mem, area, neib, thresh, val ); else detect_edge_for_lg_filter( image, src_mem, dst_mem, area, neib, thresh, val ); } /* 「任意値クロッシング」のみによるエッジ検出 */ void detect_edge_for_any_cross( src_mem, dst_mem, area, neib, thresh, val ) int src_mem; /* 入力:変換前の濃淡プレーン */ int dst_mem; /* 入力:変換後の濃淡プレーン */ MY_BOX_T *area; /* 入力:処理領域 */ int neib; /* 入力:4近傍(=4)または8近傍(=8)の別 */ int thresh; /* 入力:バイアス(0とみなす値) */ int val; /* 入力:エッジの際に入れる値 */ { Lib_any_cross( src_mem, dst_mem, neib, thresh, val ); } /* 「LGフィルタ+ゼロクロッシング」によるエッジ検出 */ void detect_edge_for_lg_filter( image, src_mem, dst_mem, area, neib, thresh, val ) IMAGE_T image; /* 入力:画質 */ int src_mem; /* 入力:変換前の濃淡プレーン */ int dst_mem; /* 入力:変換後の濃淡プレーン */ MY_BOX_T *area; /* 入力:処理領域 */ int neib; /* 入力:4近傍(=4)または8近傍(=8)の別 */ int thresh; /* 入力:バイアス(0とみなす値) */ int val; /* 入力:エッジの際に入れる値 */ { int convolver[LARGE_CONV_SIZE*LARGE_CONV_SIZE]; double sigma; int multiplier; int conv_size; int wrk_mem; if( ERROR_RETURN != ( wrk_mem = Lib_alloc_gray_memory() ) ) { Lib_gray_memory_cls( wrk_mem ); sigma = ( double )thresh * SIGMA_COEFF; conv_size = ( WORST_IMAGE == image ) ? LARGE_CONV_SIZE : SMALL_CONV_SIZE; Lib_get_convolver( conv_size, sigma, convolver, &multiplier ); if( WORST_IMAGE == image ) Lib_lg_filter( src_mem, wrk_mem, convolver, multiplier, 5 ); else Lib_lg_filter( src_mem, wrk_mem, convolver, multiplier, 3 ); Lib_set_stage_window( area->st.x + conv_size / 2, area->st.y + conv_size / 2, area->ed.x - conv_size / 2, area->ed.y - conv_size / 2 ); Lib_zero_cross( wrk_mem, dst_mem, neib, val ); Lib_free_gray_memory( wrk_mem ); } else Lib_any_cross( src_mem, dst_mem, neib, thresh, val ); } /* 領域生成 */ int create_region( area ) MY_BOX_T *area; /* 出力処理エリア */ { int status; MY_PNT_T cursor, old; int active; active = OFF; /* 始点の指定 */ Lib_chrdisp( 1, 30, "始点を入力して下さい。" ); status = Lib_get_current_position( &cursor.x, &cursor.y ); /* 位置取得 */ switch( status ) { /* 実行指令のとき */ case EXECUTE: area->st.x = cursor.x; area->st.y = cursor.y; /* 終点の指定 */ Lib_chrdisp( 1, 30, "終点を入力して下さい。" ); Lib_see_current_position( &cursor.x, &cursor.y ); old.x = cursor.x; old.y = cursor.y; draw_box( area->st.x, area->st.y, cursor.x, cursor.y ); for( status = NO_TOUCH; EXECUTE != status && CANCEL != status; ) { /* while push EXECUTE key */ /* get cursor information */ status = Lib_see_current_position( &cursor.x, &cursor.y ); if( cursor.x != old.x || cursor.y != old.y ) { /* if the position changed then the display updated */ if( cursor.x < area->st.x ) cursor.x = area->st.x; if( cursor.y < area->st.y ) cursor.y = area->st.y; /* move cursor */ Lib_move_cursor( cursor.x, cursor.y ); erase_box( area->st.x, area->st.y, old.x, old.y ); draw_box( area->st.x, area->st.y, cursor.x, cursor.y ); old.x = cursor.x; old.y = cursor.y; } } Lib_chrdisp( 1, 30, " " ); if( EXECUTE == status ) { area->ed.x = cursor.x; area->ed.y = cursor.y; active = ON; } break; case CANCEL: break; } erase_box( area->st.x, area->st.y, area->ed.x, area->ed.y ); return( active ); } /* 画像の状態取得 */ IMAGE_T get_image_condition() { int no, pad_level; int width, height; Lib_get_standard_key_size( &width, &height ); pad_level = Lib_view_open(); Lib_view_set_title( pad_level, "画像の状態" ); Lib_view_set_null( pad_level, width * 0 + MARGIN * 1, 0 * height + MARGIN * 1, "良 い", 0 ); Lib_view_set_null( pad_level, width * 1 + MARGIN * 2, 0 * height + MARGIN * 1, "悪 い", 1 ); Lib_view_set_null( pad_level, width * 0 + MARGIN * 1, 1 * height + MARGIN * 2, "最 悪", 2 ); Lib_view_set_size( pad_level, MENU_START_X, MENU_START_Y, MARGIN, MARGIN ); Lib_draw_command( pad_level ); no = Lib_process_command( pad_level ); Lib_erase_command( pad_level ); Lib_view_close( pad_level ); return( no ); } /* 箱描画 */ void draw_box( xs, ys, xe, ye ) int xs, ys, xe, ye; { Lib_box( xs, ys, xe, ye, SOLID_LINE ); } /* 箱消去 */ void erase_box( xs, ys, xe, ye ) int xs, ys, xe, ye; { Lib_box( xs, ys, xe, ye, BLACK_LINE ); } /* 画像入力 */ void my_freeze( mode ) int mode; { #ifdef FILE_MODE char *p; int mem; Lib_freeze( NOT_TRANSMIT ); mem = Lib_get_gray_memory(); if( 0 != ( p = Lib_adrs_gray_memory( mem ) ) ) { Lib_fload( "\\FS0\\GRAY_SV0.IMG", p, 512L*480L ); Lib_xvideo_transmit( mem, GRAY_PLANE ); } #else Lib_freeze( mode ); #endif } /******************************************************************************/ /***** ハフ変換実行ライブラリ *****/ /******************************************************************************/ /* ハフ変換 */ int hough_exec( value, random_n, region_r, region_q, line_coeff ) int value; /* 入力:HOUGH_LINE_MODE時 :最大検出直線数HOUGH_THRESH_MODE時:直線検出のためのしきい値*/ int random_n; /* 入力:データ間引き係数(データ数=全座標点/random_n)*/ int region_r; /* 入力:極大点決定の領域のρ方向の大きさ(片ρ幅) */ int region_q; /* 入力:極大点決定の領域のθ方向の大きさ(片θ幅) */ HLINE_T line_coeff[]; /* 出力:直線係数 */ { int fnc_status; unsigned char *src; int x, y, fx, fy, line_n; int xs, ys, xe, ye; Lib_get_stage_window( &xs, &ys, &xe, &ye ); fx = Lib_get_fx_size(); fy = Lib_get_fy_size(); if( 0 < xs && xs <= xe && xe < fx && 0 < ys && ys <= ye && ye < fy && 0 < value && value <= MAX_LINE_N && 0 < region_r && 0 < region_q ) { src = ( unsigned char * )Lib_adrs_gray_memory( CURRENT_MEMORY ); if( ERROR_RETURN != Lib_lhough_open() ) { for( y = ys + 1; y < ye; y++ ) for( x = xs + 1; x < xe; x++ ) if( 0 != *( src + y * fx + x ) && 0 == ( get_rand() % random_n ) ) { Lib_lhough_voting( x, y ); } line_n = Lib_lhough_detection( value, region_r, region_q, line_coeff ); if( ERROR_RETURN == line_n ) fnc_status = HERR_CALCULATE; else fnc_status = line_n; if( ERROR_RETURN == Lib_lhough_close() ) fnc_status = HERR_TERMINATE; } else fnc_status = HERR_INITIALIZE; } else fnc_status = HERR_PARAMETER; return( fnc_status ); } unsigned get_rand() { register unsigned int l_w; next = next * 1103515245L + 12345; l_w = ( next / 65536L ) % 32768L; return ( l_w & 0xffff ); } /* キー入力待ち */ int wait_keyin() /*[関数値] なし */ /*[処理概要] キー入力待機ルーチン */ /*[注記] なし */ { int dummy_x, dummy_y; int status; Lib_chrdisp( 1, 30, "継続→実行キー  終了→取消キー"); Lib_look_current_position( &dummy_x, &dummy_y ); for( status = NO_TOUCH; EXECUTE != status && CANCEL != status; status = Lib_see_current_position( &dummy_x, &dummy_y ) ); Lib_chrdisp( 1, 30, " "); return( status ); } /* 経過タイム表示 */ int display_elapsed_time( column, row, string ) int column; /* 入力:表示列 */ int row; /* 入力:表示行 */ char *string; /* 入力:表示文字列へのポインタ */ { char s[BUFF_SIZE]; int time; time = Lib_readclk_count(); /*タイマーカウントモードの読み取り*/ time = ( time * 8138 ) / 10000; strcpy( s, " " ); Lib_chrdisp( column, row, s ); Lib_sprintf( s,"%10s %4d(msec)", string, time ); Lib_chrdisp( column, row, s ); return( time ); }