/* * ***************************************************************** * * * * * 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 XYθ補正後画像減算 XYQSUB.C */ /*[作成者]H.Yagi */ /* 目的: 関数: 履歴: Ver 1.0 98/10/05 Ver 1.1 99/03/16 機能概要にコメント追加 Ver 2.0 00/05/19 グレイサーチパラメータパッドの追加 注記: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_search.h" #include "f_math.h" #include "f_gray.h" #include "f_file.h" /* * Include CSC90X common local */ #include "m_menu.h" /* * プロトタイプ宣言 */ void main( void ); void main_menu_disp( void ); void disp_help( void ); void para_set( void ); void gs_joken( void ); void ptn_reg( void ); void set_sub_wind( void ); void load( void ); void save( void ); void para_init( void ); void load_img( void ); void save_img( void ); void kijun( void ); void exec( void ); int search( int *, int *, int *, int * ); int d4i5_d( double ); void calc_WxWy( double, double, double, double, double, double, double *, double * ); void calc_CVxCVy( double, double, double, double, double, double, double *, double * ); int XXxyqsub( double, double, double, double, double, double, double, double, int, int, int, int, int, int, int ); void cross_mark( int, int, int ); 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 static char *select[3] = { "通常", " 高", "超高" }; int sts; int name1, name2; int gray_mem_no1, gray_mem_no2; double wwxa, wwya, wwva, wwxb, wwyb, wwvb; /*ワークサーチ位置(2箇所)*/ /* ファイル装置(FS0)へのセーブデータ構造体 */ typedef struct { double xa, ya, xb, yb; /*基準サーチ位置(2箇所)*/ int wxs, wys, wxe, wye; /*減算処理範囲 */ int seido; /* 精度 */ int complex; /* 複雑度 */ int mid_lower; /* 途中下限値 */ int last_lower; /* 最終下限値 */ } SAVE_DATA; static SAVE_DATA sv; /* * メイン */ 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; name1 = 0x314e5450; /* PTN1 */ name2 = 0x324e5450; /* PTN2 */ /* 入力ビデオ制御 */ 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 ); /* 濃淡メモリの確保1 */ if ( ERROR_RETURN != ( gray_mem_no1 = Lib_alloc_gray_memory() ) ) { Lib_gray_memory_cls( gray_mem_no1 ); /* 濃淡メモリの確保2 */ if ( ERROR_RETURN != ( gray_mem_no2 = Lib_alloc_gray_memory() ) ) { Lib_gray_memory_cls( gray_mem_no2 ); /*GRAY_PTN.SYSを使用する*/ if ( NORMAL_RETURN == Lib_gs_open_data_file( CONTINUE_PTN_AREA ) ) { load( ); /* DATA FILEのロード */ /* メニュー制御 */ 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 ); para_set(); /* 設定 */ 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 ); exec(); /* 実行 */ 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_gs_close_data_file(); } else Lib_display_message( 100, 200, "エラー", "パタンエリアは使用できません" ); Lib_free_gray_memory( gray_mem_no2 ); } else Lib_display_message( 70, 200, "エラー", "濃淡用画像メモリが確保できません" ); Lib_free_gray_memory( gray_mem_no1 ); } else Lib_display_message( 70, 200, "エラー", "濃淡用画像メモリが確保できません" ); } /* * メインメニュー表示 */ 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, "【機能\概要】 XYQSUB" ); Lib_chrdisp( 11, 10, "マスター画像と入力画像をグレイサーチによって" ); Lib_chrdisp( 11, 12, "XYθ補正を行い画像減算を実行するサンプルです。" ); Lib_chrdisp( 11, 14, "重い処理のため902シリーズでお使いください。" ); Lib_chrdisp( 11, 16, "処理ウインドサイズの大きさに比例して処理時間" ); Lib_chrdisp( 11, 18, "が増加しますのでご注意下さい。" ); } /***********************************************************************/ /* パラメータ設定    */ /***********************************************************************/ void para_set( void ) { int status_flag; int pad_level; int rtn; Lib_set_pad_maxstring( 16 ); 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_view_set_null( pad_level, 5, 125, "基準位置取得" , 4 ); Lib_view_set_null( pad_level, 5, 155, "パラメータセーブ", 5 ); Lib_view_set_size( pad_level, 30, 30, 5, 5 ); Lib_draw_command( pad_level ); for ( status_flag = ON; OFF != status_flag; ) { if ( ERROR_RETURN != ( rtn = Lib_process_command( pad_level ) ) ) { switch( rtn ) { case 0: /* サーチ条件 */ gs_joken(); break; case 1: /* パタン登録 */ ptn_reg(); break; case 2: /* 減算範囲 */ set_sub_wind(); break; case 3: /* マスター画像入力 */ save_img(); break; case 4: /* 基準学習 */ kijun(); break; case 5: /* セーブ */ save(); break; case 102: /* 終了 */ status_flag = OFF; break; } } } Lib_erase_command( pad_level ); Lib_view_close( pad_level ); Lib_set_pad_maxstring( 10 ); Lib_cls( ( LINE_PLANE | CHAR_PLANE ), BLACK_COLOR ); } /************************************************************************/ /* サーチ条件設定 */ /************************************************************************/ void gs_joken( void ) { int pad_level_gs; PVAL value_gs[4]; int no; int idc; idc = Lib_shelter_plane( 0, 0, (Lib_get_dx_size() - 1), (Lib_get_dy_size() - 1), CHAR_PLANE ); Lib_set_pad_maxstring( 10 ); pad_level_gs = Lib_view_open(); Lib_view_set_title( pad_level_gs, "サーチ条件" ); Lib_view_set_select ( pad_level_gs, 5, 5, "精度" , sv.seido - 1, 3 , select, 0 ); Lib_view_set_uniq_numeral( pad_level_gs, 5, 35, "複雑度" , sv.complex, 1, 9, 1 ); Lib_view_set_uniq_numeral( pad_level_gs, 5, 65, "途中下限値", sv.mid_lower , 1000, 9999 , 2 ); Lib_view_set_uniq_numeral( pad_level_gs, 5, 95, "最終下限値", sv.last_lower, 1000, 9999 , 3 ); Lib_view_set_size( pad_level_gs, 100, 130, 35, 5 ); Lib_draw_menu( pad_level_gs ); if( ERROR_RETURN != ( no = Lib_process_menu( pad_level_gs, value_gs ) ) ) { switch( no ) { case 101: /*「実行」が選択された */ sv.seido = value_gs[0].select_type + 1; sv.complex = value_gs[1].value_type; sv.mid_lower = value_gs[2].value_type; sv.last_lower = value_gs[3].value_type; break; case 102: /*「取り消し」が選択された */ break; } } Lib_erase_menu( pad_level_gs ); Lib_view_close( pad_level_gs ); Lib_set_pad_maxstring( 16 ); Lib_recover_plane( idc ); } /***********************************************************************/ /* パタン登録      */ /***********************************************************************/ void ptn_reg( void ) { int error; int idc; idc = Lib_shelter_plane( 0, 0, (Lib_get_dx_size() - 1), (Lib_get_dy_size() - 1), CHAR_PLANE ); Lib_set_pad_maxstring( 10 ); Lib_freeze( TRANSMIT ); if ( 0 == ( error = Lib_gs_defpat( name1 ) ) ) { if ( -1 == ( error = Lib_gs_defpat( name2 ) ) ) Lib_display_message( 150, 200, "エラー", "既に200個登録済みです" ); else if ( -2 == error ) Lib_display_message( 150, 200, "エラー", "パタン格納領域不足です" ); } else if ( -1 == error ) Lib_display_message( 150, 200, "エラー", "既に200個登録済みです" ); else if ( -2 == error ) Lib_display_message( 150, 200, "エラー", "パタン格納領域不足です" ); Lib_freerun(); Lib_set_pad_maxstring( 16 ); Lib_recover_plane( idc ); } /*********************************************************************/ /*  ウインド設定                          */ /*********************************************************************/ void set_sub_wind( void ) { PVAL value[2]; int pad_level_wind; int no; int x_size,y_size; int idc; idc = Lib_shelter_plane( 0, 0, (Lib_get_dx_size() - 1), (Lib_get_dy_size() - 1), CHAR_PLANE ); Lib_set_pad_maxstring( 10 ); pad_level_wind = Lib_view_open(); Lib_view_set_title( pad_level_wind, "減算範囲" ); x_size = sv.wxe - sv.wxs + 1; y_size = sv.wye - sv.wys + 1; Lib_view_set_box( pad_level_wind, 5, 5, "始点" , sv.wxs, sv.wys, 3, 1, 0 ); Lib_view_set_box( pad_level_wind, 5, 35, "サイズ", x_size, y_size, 3, 0, 1 ); Lib_view_set_size( pad_level_wind, 50, 80, 5, 5 ); Lib_draw_menu( pad_level_wind ); if( ERROR_RETURN != ( no = Lib_process_menu( pad_level_wind, value ) ) ) { switch( no ) { case 101: /*「実行」が選択された */ sv.wxs = value[0].box_type.x; sv.wys = value[0].box_type.y; sv.wxe = value[0].box_type.x + value[1].box_type.x - 1; sv.wye = value[0].box_type.y + value[1].box_type.y - 1; break; case 102: /*「取り消し」が選択された */ break; } } Lib_erase_menu( pad_level_wind ); Lib_view_close( pad_level_wind ); Lib_set_pad_maxstring( 16 ); Lib_recover_plane( idc ); } /************************************************************************/ /* 画像SAVE */ /************************************************************************/ void save_img( void ) { char out_f[20]; char ss[50]; int idc; idc = Lib_shelter_plane( 0, 0, (Lib_get_dx_size() - 1), (Lib_get_dy_size() - 1), CHAR_PLANE ); Lib_change_gray_memory( gray_mem_no1 ); Lib_freeze( TRANSMIT ); Lib_change_gray_memory( 0 ); Lib_sprintf( out_f, "\\FS0\\XYQSUB.IMG" ); Lib_chrdisp( 1, 30, "セーブ中..." ); if ( NORMAL_RETURN != Lib_save_gray_memory( gray_mem_no1, out_f ) ) { Lib_cls( CHAR_PLANE, BLACK_COLOR ); Lib_sprintf( ss, "Image File %s Save Error", out_f ); Lib_display_message( 70, 200, "エラー", ss ); } Lib_cls( CHAR_PLANE, BLACK_COLOR ); Lib_recover_plane( idc ); } /***********************************************************************/ /* 基準学習       */ /***********************************************************************/ void kijun( void ) { int out_inf[8]; int xs,ys,xe,ye; int idc; idc = Lib_shelter_plane( 0, 0, (Lib_get_dx_size() - 1), (Lib_get_dy_size() - 1), CHAR_PLANE ); if ( 0 == Lib_gs_infpat( name1, out_inf ) ) { sv.xa = out_inf[4] + ( out_inf[2] / 10 ); sv.ya = out_inf[5] + ( out_inf[3] / 10 ); xs = out_inf[4]; ys = out_inf[5]; xe = xs + out_inf[0] - 1; ye = ys + out_inf[1] - 1; Lib_box( xs, ys, xe, ye, SOLID_LINE ); cross_mark( sv.xa, sv.ya, 5 ); if ( 0 == Lib_gs_infpat( name2, out_inf ) ) { sv.xb = out_inf[4] + ( out_inf[2] / 10 ); sv.yb = out_inf[5] + ( out_inf[3] / 10 ); xs = out_inf[4]; ys = out_inf[5]; xe = xs + out_inf[0] - 1; ye = ys + out_inf[1] - 1; Lib_box( xs, ys, xe, ye, SOLID_LINE ); cross_mark( sv.xb, sv.yb, 5 ); Lib_box( sv.wxs, sv.wys, sv.wxe, sv.wye, SOLID_LINE ); /*減算範囲表示*/ Lib_display_keyinput( 460, 0, "確認" ); } else Lib_display_message( 70, 200, "エラー", "サーチパタン2が登録されていません。" ); } else Lib_display_message( 70, 200, "エラー", "サーチパタン1が登録されていません。" ); Lib_cls( LINE_PLANE, BLACK_COLOR ); Lib_recover_plane( idc ); } /************************************************************************/ /* グレイサーチ実行    */ /************************************************************************/ int search( xa, ya, xb, yb ) int *xa; int *ya; int *xb; int *yb; { int Rslt_Buf[3]; int rtn; Lib_gs_window( ON_DISPLAY, 0, 0, 511, 479 ); /* サーチ実行1 */ if ( 0 < ( rtn = Lib_gs_search( ON_DISPLAY, name1, 1, sv.seido, sv.complex, sv.mid_lower, sv.last_lower, Rslt_Buf ) ) ) { *xa = Rslt_Buf[0]; *ya = Rslt_Buf[1]; /* サーチ実行2 */ if ( 0 < ( rtn = Lib_gs_xsearch( SAME_IMAGE, ON_DISPLAY, name2, 1, sv.seido, sv.complex, sv.mid_lower, sv.last_lower, Rslt_Buf ) ) ) { *xb = Rslt_Buf[0]; *yb = Rslt_Buf[1]; } } return( rtn ); } /***********************************************************************/ /* 入力数値(double)の4捨5入した数値(int)を返す */ /***********************************************************************/ int d4i5_d( double in ) { int out; if ( in >= 0.0 ) out = (int)( in + 0.5 ); else out = (int)( in - 0.5 ); return( out ); } /************************************************************************/ /* 設定データの読込                          */ /************************************************************************/ void load( void ) { Lib_set_cursor_shape( HOURGLASS_TYPE ); Lib_chrdisp( 1, 30, "ロード中..." ); if ( 0 == Lib_fload( "\\FS0\\XYQSUB.DAT", (char *)&sv, sizeof( SAVE_DATA ) ) ) { /* ファイルなしの場合の初期設定 */ para_init(); } load_img( ); /*マスタ画像読み込み*/ Lib_chrdisp( 1, 30, "       " ); Lib_set_cursor_shape( ARROW_TYPE ); } /************************************************************************/ /* 設定データの保存                          */ /************************************************************************/ void save( void ) { int idc; idc = Lib_shelter_plane( 0, 0, (Lib_get_dx_size() - 1), (Lib_get_dy_size() - 1), CHAR_PLANE ); Lib_set_cursor_shape( HOURGLASS_TYPE ); Lib_chrdisp( 1, 30, "セーブ中..." ); if ( 0 == Lib_fsave( "\\FS0\\XYQSUB.DAT", (char *)&sv, sizeof( SAVE_DATA ) ) ) Lib_chrdisp( 1, 30, "XYQSUB.DAT fsave_err!" ); if ( ERROR_RETURN == Lib_gs_save_data_file() ) /* サーチパタンのセーブ */ Lib_display_message( 70, 200, "エラー", "GRAY_PTN.SYS をセーブできません。" ); Lib_cls( CHAR_PLANE, BLACK_COLOR ); Lib_set_cursor_shape( ARROW_TYPE ); Lib_recover_plane( idc ); } /************************************************************************/ /* 設定データの初期化                         */ /************************************************************************/ void para_init( void ) { sv.xa = 0.0; sv.ya = 0.0; sv.xb = 0.0; sv.yb = 0.0; sv.wxs = 200; sv.wys = 200; sv.wxe = 299; sv.wye = 299; sv.seido = 1; sv.complex = 1; sv.mid_lower = 5000; sv.last_lower = 7000; } /************************************************************************/ /* 画像LOAD */ /************************************************************************/ void load_img( void ) { char in_f[20]; Lib_sprintf( in_f, "\\FS0\\XYQSUB.IMG" ); Lib_load_gray_memory( gray_mem_no1, in_f ); } /***********************************************************************/ /* 実行         */ /***********************************************************************/ void exec( void ) { int rtn; int x1, y1, x2, y2; int xx[4], yy[4]; double Wx, Wy; double CVx, CVy; Lib_strtclk_count(); /*タイマーカウントモードのスタート*/ Lib_freeze( TRANSMIT ); if ( 1 == ( rtn = search( &x1, &y1, &x2, &y2 ) ) ) { wwxa = (double)x1 / 10.0; wwya = (double)y1 / 10.0; wwxb = (double)x2 / 10.0; wwyb = (double)y2 / 10.0; /*左上*/ calc_WxWy ( sv.xa, sv.ya, sv.xb, sv.yb, (double)sv.wxs, (double)sv.wys, &Wx, &Wy ); calc_CVxCVy( wwxa, wwya, wwxb, wwyb, Wx, Wy, &CVx, &CVy ); xx[0] = d4i5_d( CVx ); yy[0] = d4i5_d( CVy ); /*右上*/ calc_WxWy ( sv.xa, sv.ya, sv.xb, sv.yb, (double)sv.wxe, (double)sv.wys, &Wx, &Wy ); calc_CVxCVy( wwxa, wwya, wwxb, wwyb, Wx, Wy, &CVx, &CVy ); xx[1] = d4i5_d( CVx ); yy[1] = d4i5_d( CVy ); /*左下*/ calc_WxWy ( sv.xa, sv.ya, sv.xb, sv.yb, (double)sv.wxs, (double)sv.wye, &Wx, &Wy ); calc_CVxCVy( wwxa, wwya, wwxb, wwyb, Wx, Wy, &CVx, &CVy ); xx[2] = d4i5_d( CVx ); yy[2] = d4i5_d( CVy ); /*右下*/ calc_WxWy ( sv.xa, sv.ya, sv.xb, sv.yb, (double)sv.wxe, (double)sv.wye, &Wx, &Wy ); calc_CVxCVy( wwxa, wwya, wwxb, wwyb, Wx, Wy, &CVx, &CVy ); xx[3] = d4i5_d( CVx ); yy[3] = d4i5_d( CVy ); /*検査画像側減算処理範囲*/ Lib_drawline( xx[0], yy[0], xx[1], yy[1] ); Lib_drawline( xx[0], yy[0], xx[2], yy[2] ); Lib_drawline( xx[1], yy[1], xx[3], yy[3] ); Lib_drawline( xx[2], yy[2], xx[3], yy[3] ); XXxyqsub( sv.xa, sv.ya, sv.xb, sv.yb, wwxa, wwya, wwxb, wwyb, sv.wxs, sv.wys, sv.wxe, sv.wye, gray_mem_no1, 0, 0 ); /*XYθ補正後画像減算*/ Lib_time_disp( 0, 0 ); Lib_xvideo_transmit( 0, GRAY_PLANE ); Lib_display_keyinput( 460, 0, "確認" ); } else if ( 0 == rtn ) Lib_display_message( 100, 200, "サーチエラー", "対象物がありません" ); else if ( -1 == rtn ) Lib_display_message( 100, 200, "サーチエラー", "パタンが登録されていません" ); Lib_freerun(); Lib_cls( ( GRAY_PLANE | CHAR_PLANE | LINE_PLANE ), BLACK_COLOR ); } /************************************************************************/ /* Wx,Wy算出       */ /************************************************************************/ void calc_WxWy( ox1, oy1, ox2, oy2, x, y, Wx, Wy ) double ox1, oy1, ox2, oy2; /*基準サーチ位置(2箇所)*/ double x, y; /*変換元座標 */ double *Wx, *Wy; /*Wx, Wy */ { double xc, yc, qc; xc = (double)(ox1 + ox2) / 2.0; yc = (double)(oy1 + oy2) / 2.0; qc = atan2( oy2 - oy1, ox2 - ox1 ); *Wx = x * cos( qc ) + y * sin( qc ) - xc * cos( qc ) - yc * sin( qc ); *Wy = -x * sin( qc ) + y * cos( qc ) + xc * sin( qc ) - yc * cos( qc ); } /************************************************************************/ /* 変換後座標( CVx, CVy )算出   */ /************************************************************************/ void calc_CVxCVy( wx1, wy1, wx2, wy2, Wx, Wy, CVx, CVy ) double wx1, wy1, wx2, wy2; /*ワークのサーチ位置(2箇所)*/ double Wx, Wy; /*変換元座標係数 */ double *CVx, *CVy; /*変換後座標 */ { double xc, yc, qc; xc = (double)(wx1 + wx2) / 2.0; yc = (double)(wy1 + wy2) / 2.0; qc = atan2( wy2 - wy1, wx2 - wx1 ); *CVx = Wx * cos( qc ) - Wy * sin( qc ) + xc; *CVy = Wx * sin( qc ) + Wy * cos( qc ) + yc; } /************************************************************************/ /* XYθ補正後画像減算   */ /************************************************************************/ int XXxyqsub( Mas_x1, Mas_y1, Mas_x2, Mas_y2, x1, y1, x2, y2, wxs, wys, wxe, wye, Mas_mem_no, tgt_mem_no, dst_mem_no ) double Mas_x1, Mas_y1, Mas_x2, Mas_y2; /*入力:マスタ画像でのアライメント位置(2箇所) */ double x1, y1, x2, y2; /*入力:検査画像でのアライメント位置(2箇所) */ int wxs, wys, wxe, wye; /*入力:処理範囲 */ int Mas_mem_no, tgt_mem_no; /*入力:マスタ画像メモリNo、検査画像のメモリNo */ int dst_mem_no; /*入力:出力結果を格納するメモリNo */ /* 戻り値:   0:正常 */ /* -1:異常終了 */ { register int i, a; register int wk; register unsigned char *p, *q, *r, *wind_base; register unsigned char *base_g1; register unsigned char *base_g2; register unsigned char *base_g3; int windx, windy; int fx; int xx, yy; double Wx, Wy; double CVx, CVy; if ( NULL == ( base_g1 = (void *)Lib_adrs_gray_memory( Mas_mem_no ) ) || NULL == ( base_g2 = (void *)Lib_adrs_gray_memory( tgt_mem_no ) ) || NULL == ( base_g3 = (void *)Lib_adrs_gray_memory( dst_mem_no ) ) ) return( ERROR_RETURN ); fx = Lib_get_fx_size(); windx = wxe - wxs + 1; windy = wye - wys + 1; wind_base = base_g1 + wys * fx + wxs; for ( i = 0; i < windy; i++ ) { p = wind_base + ( fx * i ); for ( a = 0; a < windx; a++ ) { calc_WxWy ( Mas_x1, Mas_y1, Mas_x2, Mas_y2, (double)(wxs + a), (double)(wys + i), &Wx, &Wy ); calc_CVxCVy( x1, y1, x2, y2, Wx, Wy, &CVx, &CVy ); xx = d4i5_d( CVx ); yy = d4i5_d( CVy ); q = base_g2 + yy * fx + xx; r = base_g3 + yy * fx + xx; wk = ( *p & 0xff ) - ( *q & 0xff ); if ( wk < 0 ) wk = -wk; *r = ( unsigned char )wk; p++; q++; r++; } } return( NORMAL_RETURN ); } /***** 十字マーク *****/ void cross_mark( x, y, length ) int x; int y; int length; { Lib_drawline( x - length, y, x + length, y ); Lib_drawline( x, y - length, x, y + length ); }