外部デバイスからの入力

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
tomomi

外部デバイスからの入力

#1

投稿記事 by tomomi » 13年前

今、手書き文字認識のプログラムを作っています。
手書き文字認識と言っても、位置情報は全く使わず、ペンで書いた線の長さのみを用います。
ペンの長さはLEGOのマインドストリームのタッチセンサーを使い、センサーがオンの間の時間を長さに置き換えます。

質問は、どのようにすればタッチセンサーで計測した数値をデータとして取り込むことができるのかということです。下記のプログラムではタブレットを用いた場合なのですが、どこを変えればいいのでしょうか。

fpを2つ使っていて「/dev/ttyb」と「Moji_data」とありますが、「Moji_data」は2番の登録文字参照するときに使われるものだということはわかるのですが、「/dev/ttyb」がタブレットを表しているのでしょうか。
とても困っていますのでよろしくお願いします。

c言語 / gcc / iBook



#include <stdio.h>
#include <stdlib.h>
#include <math.h>

/*
#define debug
*/


#define VALID 1
#define INVALID 0
#define ON 1
#define OFF 0
#define MAXSIZE 128
#define MAX 2147483647

struct fdat{
char header;
char sw1, sw2;
int x_pos, y_pos;
};

int moji[MAXSIZE], moji_data[MAXSIZE], word[MAXSIZE], newword;
float value = MAX;
char line[MAXSIZE];


/********************************************
dat2pos(char *data, struct fdat *fdat_p)
********************************************/
int dat2pos(data, fdat_p)
char data[];
struct fdat *fdat_p ;
{
/* chack header */
switch ( data[0] ){
case '@':
fdat_p -> header = VALID ;
break ;
case 'A':
fdat_p -> header = INVALID ;
break;
default:
return -1; /* error code */
}

/* set SW1, SW2 data */
if ( (data[1] & 0x1 ) != 0 )
fdat_p -> sw1 = ON ;
else
fdat_p -> sw1 = OFF ;
if ( (data[1] & 0x2 ) != 0 )
fdat_p -> sw2 = ON ;
else
fdat_p -> sw2 = OFF ;

/* calcurate position x and y */
{
int i, x = 0 , y = 0;
for( i = 0; i < 4; i++ )
{
x = ( x << 5 ) + (data[9 - i] & 0x1F) ; /* byte 10 - 7 */
y = ( y << 5 ) + (data[5 - i] & 0x1F) ; /* byte 6 - 3 */
}
fdat_p -> x_pos = x ;
fdat_p -> y_pos = y ;
}
return 0; /* return no error */
}


/*1文字入力(本数を返す)*/
int input_moji(FILE *fp)
{
int a, i, j = 0, nagasa = 0, honsu = 0;
struct fdat fdata ;

while(1){
i = 0;
a = fgetc(fp) ;

/* line配列に1行読み込み */
while( (a != '\n') && i < MAXSIZE - 1 ){
line[i++] = a & 0x7F ; /* skip parity bit */
a = fgetc(fp) ;
}
line[i++] = 0 ;

#ifdef debug
/* print input data */
printf("%s ", line);
#endif

if ( dat2pos(line , &fdata) < 0 )
{
/* print error messsage */
printf(" ----- invalid data ---------\n");
continue;
}

#ifdef debug
printf("Header= %s, SW1= %s, SW2= %s, X= %d, Y= %d\n",
fdata.header==VALID?"VALID ":"INVALID",
fdata.sw1==ON?"ON ":"OFF",
fdata.sw2==ON?"ON ":"OFF",
fdata.x_pos,
fdata.y_pos) ;
#endif

/*INVALID状態の時 nagasa+1 を行わない*/
if(fdata.header == INVALID){
continue;
}

nagasa++;

/*終了*/
if (fdata.x_pos > 20000 && fdata.y_pos < 3200 )
return MAX;

/*1文字認識*/
else if (fdata.x_pos > 20000 && fdata.y_pos > 5000
&& fdata.y_pos < 9300)
return honsu;

/*それ以外の時の処理*/
else if( fdata.sw1 == OFF){
moji[j] = nagasa;
nagasa = 0;
honsu++;
j++;
}
}
}


void get_line(char buffer[])
{
int i, j = 0, k = 0, l;
char temp[MAXSIZE];

for(i = 0; i < MAXSIZE; i++){
temp = '\0';
moji_data = '\0';
}

for(i = 0; ; i++){
if(buffer == '\n')
break;
else if(buffer == ' '){
moji_data[k] = atoi(temp);
k++;
for(l = 0; l < MAXSIZE; l++)
temp[l] = '\0';
j = 0;
continue;
}
else{
temp[j] = buffer;
j++;
}
}
}


void recog(int honsu, FILE *fp)
{
int i;
float t_value;
char buffer[1024];

fgets(buffer, 1024, fp);

while(! feof(fp)){
t_value = 0;
get_line(buffer);

if(moji_data[1] == honsu){
for(i = 0; i < honsu - 1; i++)
t_value += sqrt((moji[i + 1] * 100 / moji[0] - moji_data[i + 3]
* 100 / moji_data[2])
* (moji[i + 1] * 100 / moji[0] - moji_data[i + 3]
* 100 / moji_data[2]));
printf("value = %.3f t_value = %.3f\n", value, t_value);
if(value > t_value){
value = t_value;
word[0] = moji_data[0];
for(i = 0; i < honsu; i++)
word[i + 1] = moji_data[i + 2];
}
}
fgets(buffer, 1024, fp);
}
}


int input_YorN()
{
char a = '\0';

while((a != 'Y') && (a != 'y') && (a != 'N') && (a != 'n')){
printf("(y/n):");
scanf("%c", &a);
}
return a;
}


menu1()
{
int i, j, honsu, a1, a2, flag;
char a;

FILE *fp[2];

while(1){
flag = 1, value = MAX;
printf("\n\nペンで認識したい文字を書いて認識ボタンを押してください\n");
printf("(終了:タブレット上の終了ボタンを押す\n");

for(i = 0; i < MAXSIZE; i++){
moji = '\0';
line = '\0';
word = '\0';
moji_data = '\0';
}

if((fp[0] = fopen("/dev/ttyb", "r")) == NULL){
printf("/dev/ttyb がオープンできません\n");
exit(0);
}

if((fp[1] = fopen("Moji_data", "a+")) == NULL){
printf("Moji_data がオープンできません\n");
exit(0);
}
fclose(fp[1]);

fp[1] = fopen("Moji_data", "r");

honsu = input_moji(fp[0]);

if(honsu == MAX){ /*終了*/
fclose (fp[0]);
fclose (fp[1]);
return;
}

recog(honsu, fp[1]);

fclose(fp[1]);
fp[1] = fopen("Moji_data", "a+");

printf("\n\n入力画数は %d 画\n", honsu);
printf("1画1画の長さの比は : ");
for(i = 0; i < honsu; i++)
printf("%d ", moji);
printf("\n\n");

printf("---------- 認識結果 ----------\n");
if(value == MAX){
printf("\n同一画数の文字がありません\n");
a = 'N';
}
else{
a1 = (word[0] >> 8) | 0x80;
a2 = (word[0] & 0xff) | 0x80;
printf("文字 : %c%c 認識度 : %3f | ", a1, a2, value);
for(i = 0; i < honsu; i++)
printf("%d ", word[i + 1]);

printf("\n\n認識結果は正しいですか? ");
a = input_YorN();
}

switch(a){
case 'N': case 'n':
printf("\n新たな文字として登録します。 \n よろしいですか?");
a = input_YorN();

if(a == 'Y' || a == 'y'){
while(flag){
printf("コードを入力してください。(16進数):");
scanf("%x", &newword);

a1 = (newword >> 8) | 0x80;
a2 = (newword & 0xff) | 0x80;

printf("\n%c%c として登録します。\nよろしいですか?", a1, a2);

a = input_YorN();

if(a == 'Y' || a == 'y'){
fprintf(fp[1], "%d %d ", newword, honsu);
for(i = 0; i < honsu; i++)
fprintf(fp[1], "%d ", moji[i]);
fprintf(fp[1], "\n");

printf("登録しました。\n\n");
flag = 0;
}
}
}
else
printf("登録をとりりやめました\n\n");

break;

case 'Y': case 'y':
printf("\n書く人がいいと、こちらとしても助かります。\n\n");
break;

default:
break;
}

fclose(fp[0]);
fclose(fp[1]);
}
}


void menu2()
{
int i, j = 0, a1, a2;
char buffer[1024];
FILE *fp;

if((fp = fopen("Moji_data", "r")) == NULL){
printf("Moji_data がオープンできません\n");
exit(0);
}

printf("\n ------ 登録内容 ------\n");

fgets(buffer, 1024, fp);

while(! feof(fp)){
j++;
get_line(buffer);

a1 = (moji_data[0] >> 8) | 0x80;
a2 = (moji_data[0] & 0xff) | 0x80;

printf("%c%c %2d 画 ", a1, a2, moji_data[1]);
for(i = 0; i < moji_data[1]; i++)
printf("%d ", moji_data[i + 2]);
printf("\n");

if(j % 10 == 0){
printf("HIT RETURN KEY!!\n");
getchar();
}

fgets(buffer, 1024, fp);
}
printf("\n計%d文字登録されています。\n\n", j);
fclose(fp);
}


main()
{
int num;

while(1){
printf(" ☆☆☆☆ 手書き文字認識ソフト  珠緒ちゃん β ++ ☆☆☆☆\n\n");
printf("----- MENU -----\n");
printf("1. 文字認識\n2. 登録文字情報\n3. 終了\n");
printf("------------------\n");

while(1){
printf("INPUT 1~3: ");
scanf("%d", &num);

if(num == 1){
menu1();
break;
}

if(num == 2){
menu2();
break;
}

else
exit(0);
}
}
}

tomomi

Re: 外部デバイスからの入力

#2

投稿記事 by tomomi » 13年前

コードで囲うのを忘れていました。すみません。

コード:


#include <stdio.h>
#include <stdlib.h>
#include <math.h>

/*
#define debug
*/


#define VALID 1
#define INVALID 0
#define ON 1 
#define OFF 0
#define MAXSIZE 128
#define MAX 2147483647

struct fdat{
char header;
char sw1, sw2;
int x_pos, y_pos;
};

int moji[MAXSIZE], moji_data[MAXSIZE], word[MAXSIZE], newword;
float value = MAX;
char line[MAXSIZE];


/********************************************
dat2pos(char *data, struct fdat *fdat_p)
********************************************/
int dat2pos(data, fdat_p)
char data[];
struct fdat *fdat_p ;
{
/* chack header */
switch ( data[0] ){
case '@':
fdat_p -> header = VALID ;
break ;
case 'A':
fdat_p -> header = INVALID ;
break;
default:
return -1; /* error code */
}

/* set SW1, SW2 data */
if ( (data[1] & 0x1 ) != 0 )
fdat_p -> sw1 = ON ;
else 
fdat_p -> sw1 = OFF ;
if ( (data[1] & 0x2 ) != 0 ) 
fdat_p -> sw2 = ON ;
else 
fdat_p -> sw2 = OFF ;

/* calcurate position x and y */
{
int i, x = 0 , y = 0;
for( i = 0; i < 4; i++ )
{
x = ( x << 5 ) + (data[9 - i] & 0x1F) ; /* byte 10 - 7 */
y = ( y << 5 ) + (data[5 - i] & 0x1F) ; /* byte 6 - 3 */
}
fdat_p -> x_pos = x ;
fdat_p -> y_pos = y ;
}
return 0; /* return no error */
}


/*1文字入力(本数を返す)*/
int input_moji(FILE *fp)
{
int a, i, j = 0, nagasa = 0, honsu = 0;
struct fdat fdata ; 

while(1){
i = 0;
a = fgetc(fp) ;

/* line配列に1行読み込み */
while( (a != '\n') && i < MAXSIZE - 1 ){
line[i++] = a & 0x7F ; /* skip parity bit */
a = fgetc(fp) ;
}
line[i++] = 0 ;

#ifdef debug
/* print input data */
printf("%s ", line);
#endif

if ( dat2pos(line , &fdata) < 0 ) 
{ 
/* print error messsage */
printf(" ----- invalid data ---------\n");
continue;
}

#ifdef debug
printf("Header= %s, SW1= %s, SW2= %s, X= %d, Y= %d\n",
fdata.header==VALID?"VALID ":"INVALID", 
fdata.sw1==ON?"ON ":"OFF", 
fdata.sw2==ON?"ON ":"OFF",
fdata.x_pos, 
fdata.y_pos) ;
#endif

/*INVALID状態の時 nagasa+1 を行わない*/
if(fdata.header == INVALID){
continue;
}

nagasa++;

/*終了*/
if (fdata.x_pos > 20000 && fdata.y_pos < 3200 )
return MAX;

/*1文字認識*/
else if (fdata.x_pos > 20000 && fdata.y_pos > 5000 
&& fdata.y_pos < 9300) 
return honsu; 

/*それ以外の時の処理*/
else if( fdata.sw1 == OFF){
moji[j] = nagasa;
nagasa = 0;
honsu++;
j++;
}
} 
}


void get_line(char buffer[])
{
int i, j = 0, k = 0, l;
char temp[MAXSIZE];

for(i = 0; i < MAXSIZE; i++){
temp[i] = '\0';
moji_data[i] = '\0';
}

for(i = 0; ; i++){
if(buffer[i] == '\n')
break;
else if(buffer[i] == ' '){
moji_data[k] = atoi(temp);
k++;
for(l = 0; l < MAXSIZE; l++)
temp[l] = '\0';
j = 0;
continue;
}
else{
temp[j] = buffer[i];
j++;
}
}
}


void recog(int honsu, FILE *fp)
{
int i;
float t_value;
char buffer[1024];

fgets(buffer, 1024, fp);

while(! feof(fp)){
t_value = 0;
get_line(buffer); 

if(moji_data[1] == honsu){
for(i = 0; i < honsu - 1; i++)
t_value += sqrt((moji[i + 1] * 100 / moji[0] - moji_data[i + 3]
* 100 / moji_data[2])
* (moji[i + 1] * 100 / moji[0] - moji_data[i + 3]
* 100 / moji_data[2]));
printf("value = %.3f t_value = %.3f\n", value, t_value);
if(value > t_value){
value = t_value;
word[0] = moji_data[0];
for(i = 0; i < honsu; i++)
word[i + 1] = moji_data[i + 2];
}
} 
fgets(buffer, 1024, fp);
}
}


int input_YorN()
{
char a = '\0';

while((a != 'Y') && (a != 'y') && (a != 'N') && (a != 'n')){
printf("(y/n):");
scanf("%c", &a);
}
return a;
}


menu1()
{
int i, j, honsu, a1, a2, flag;
char a;

FILE *fp[2];

while(1){
flag = 1, value = MAX;
printf("\n\nペンで認識したい文字を書いて認識ボタンを押してください\n");
printf("(終了:タブレット上の終了ボタンを押す\n");

for(i = 0; i < MAXSIZE; i++){
moji[i] = '\0';
line[i] = '\0';
word[i] = '\0';
moji_data[i] = '\0';
}

if((fp[0] = fopen("/dev/ttyb", "r")) == NULL){
printf("/dev/ttyb がオープンできません\n");
exit(0);
}

if((fp[1] = fopen("Moji_data", "a+")) == NULL){
printf("Moji_data がオープンできません\n");
exit(0);
}
fclose(fp[1]);

fp[1] = fopen("Moji_data", "r");

honsu = input_moji(fp[0]);

if(honsu == MAX){ /*終了*/
fclose (fp[0]);
fclose (fp[1]);
return;
}

recog(honsu, fp[1]);

fclose(fp[1]);
fp[1] = fopen("Moji_data", "a+");

printf("\n\n入力画数は %d 画\n", honsu);
printf("1画1画の長さの比は : ");
for(i = 0; i < honsu; i++)
printf("%d ", moji[i]);
printf("\n\n");

printf("---------- 認識結果 ----------\n");
if(value == MAX){
printf("\n同一画数の文字がありません\n");
a = 'N';
}
else{
a1 = (word[0] >> 8) | 0x80;
a2 = (word[0] & 0xff) | 0x80;
printf("文字 : %c%c 認識度 : %3f | ", a1, a2, value);
for(i = 0; i < honsu; i++)
printf("%d ", word[i + 1]);

printf("\n\n認識結果は正しいですか? ");
a = input_YorN();
}

switch(a){
case 'N': case 'n':
printf("\n新たな文字として登録します。 \n よろしいですか?");
a = input_YorN();

if(a == 'Y' || a == 'y'){
while(flag){
printf("コードを入力してください。(16進数):");
scanf("%x", &newword);

a1 = (newword >> 8) | 0x80;
a2 = (newword & 0xff) | 0x80;

printf("\n%c%c として登録します。\nよろしいですか?", a1, a2);

a = input_YorN();

if(a == 'Y' || a == 'y'){
fprintf(fp[1], "%d %d ", newword, honsu);
for(i = 0; i < honsu; i++)
fprintf(fp[1], "%d ", moji[i]);
fprintf(fp[1], "\n");

printf("登録しました。\n\n");
flag = 0;
}
}
}
else 
printf("登録をとりりやめました\n\n");

break;

case 'Y': case 'y':
printf("\n書く人がいいと、こちらとしても助かります。\n\n");
break;

default:
break;
}

fclose(fp[0]);
fclose(fp[1]);
}
}


void menu2()
{
int i, j = 0, a1, a2;
char buffer[1024];
FILE *fp;

if((fp = fopen("Moji_data", "r")) == NULL){
printf("Moji_data がオープンできません\n");
exit(0);
}

printf("\n ------ 登録内容 ------\n");

fgets(buffer, 1024, fp);

while(! feof(fp)){
j++;
get_line(buffer);

a1 = (moji_data[0] >> 8) | 0x80;
a2 = (moji_data[0] & 0xff) | 0x80;

printf("%c%c %2d 画 ", a1, a2, moji_data[1]);
for(i = 0; i < moji_data[1]; i++)
printf("%d ", moji_data[i + 2]);
printf("\n");

if(j % 10 == 0){
printf("HIT RETURN KEY!!\n");
getchar();
}

fgets(buffer, 1024, fp);
}
printf("\n計%d文字登録されています。\n\n", j);
fclose(fp);
}


main()
{
int num;

while(1){
printf(" ☆☆☆☆ 手書き文字認識ソフト  珠緒ちゃん β ++ ☆☆☆☆\n\n");
printf("----- MENU -----\n");
printf("1. 文字認識\n2. 登録文字情報\n3. 終了\n");
printf("------------------\n");

while(1){
printf("INPUT 1~3: ");
scanf("%d", &num);

if(num == 1){
menu1();
break;
}

if(num == 2){
menu2();
break;
}

else
exit(0);
}
}
}




beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: 外部デバイスからの入力

#3

投稿記事 by beatle » 13年前

tomomiさんのソースコードはインデントされていないのですが、それは貼り付けるときにインデントが消えちゃったのか、最初からインデントしないで書いているのか、どちらでしょうか。

ちなみにインデントとは「字下げ」のことでして、例えばこんな感じ。

コード:

if (1)
{
    // {と}の間は4文字分インデントする
}
バグを発生させにくくするためにも、正しいインデントを心がけましょう。
インデントについてはチェック3 : インデントを揃えよう値を参考にどうぞ。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 外部デバイスからの入力

#4

投稿記事 by softya(ソフト屋) » 13年前

この質問の関連質問ですね?
「CをJAVAに変換してください • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?f=3&t=11697#p94377

この時に、
肝心の手書き入力が/dev/ttybのデバイスで行われていますが、そこの部分は自分で解決出来るのでしょうか?
と書いたのですが、元々のC言語のソースで使われたハードウェアの仕様がわからない以上は答えようがありません。
どこかに解説のURLはありませんか?

それと
ペンの長さはLEGOのマインドストリームのタッチセンサーを使い、センサーがオンの間の時間を長さに置き換えます。
マインドストームのタッチセンサーにも詳しい人がいるかがわかりませんので、詳しい仕様の説明か詳しい説明のあるURLを教えて下さい。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

tomomi

Re: 外部デバイスからの入力

#5

投稿記事 by tomomi » 13年前

インテンドは消えてしまってたようです。すみません。改めて書きましたのでお願いします。

元々の研究の詳細はこちらにあります。
http://www.ml.info.kanagawa-u.ac.jp/pap ... magata.pdf

タッチセンサーについてはこちらにあります。
オレンジ色になっている部分が押されている間がセンサーオンの状態で、その情報はNXTに記録されます。NXTを介してPCへ情報を送るという形です。
http://itlifehack.jp/archives/204856.html

説明不足ですみません。また、不足している点がありましたらご指摘ください。
よろしくお願いいたします。

コード:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
    
/*
#define debug
*/
    
    
#define VALID 1
#define INVALID 0
#define ON 1 
#define OFF 0
#define MAXSIZE 128
#define MAX 2147483647
    
    struct fdat{
    char header;
    char sw1, sw2;
    int x_pos, y_pos;
    };
 
int moji[MAXSIZE], moji_data[MAXSIZE], word[MAXSIZE], newword;
float value = MAX;
char line[MAXSIZE];
 
 
/********************************************
  dat2pos(char *data, struct fdat *fdat_p)
  ********************************************/
int dat2pos(data, fdat_p)
    char data[];
    struct fdat *fdat_p ;
{
    /* chack header */
    switch ( data[0] ){
      case '@':
    fdat_p -> header = VALID ;
    break ;
      case 'A':
    fdat_p -> header = INVALID ;
    break;
      default:
    return -1;     /* error code */
    }
    
    /* set SW1, SW2 data  */
    if ( (data[1] & 0x1 ) != 0 )
    fdat_p -> sw1 = ON ;
    else 
    fdat_p -> sw1 = OFF ;
    if ( (data[1] & 0x2 ) != 0 ) 
    fdat_p -> sw2 = ON ;
    else 
    fdat_p -> sw2 = OFF ;
    
    /* calcurate position x and y */
{
    int i, x = 0 , y = 0;
    for( i = 0; i < 4; i++ )
    {
    x = ( x << 5 ) + (data[9 - i] & 0x1F) ; /* byte 10 - 7 */
    y = ( y << 5 ) + (data[5 - i] & 0x1F) ; /* byte 6 - 3 */
    }
    fdat_p -> x_pos = x ;
    fdat_p -> y_pos = y ;
}
return 0; /* return no error */
}
 
 
/*1文字入力(本数を返す)*/
int input_moji(FILE *fp)
{
    int a, i, j = 0, nagasa = 0, honsu = 0;
    struct fdat fdata ; 
    
    while(1){
    i = 0;
    a = fgetc(fp) ;
    
    /* line配列に1行読み込み */
    while( (a != '\n') && i < MAXSIZE - 1 ){
        line[i++] = a & 0x7F ; /* skip parity bit */
        a = fgetc(fp) ;
    }
    line[i++] = 0 ;
    
#ifdef debug
    /* print input data */
    printf("%s  ", line);
#endif
    
    if ( dat2pos(line , &fdata) < 0  ) 
    { 
        /* print error messsage */
        printf(" ----- invalid data ---------\n");
        continue;
    }
    
#ifdef debug
    printf("Header= %s, SW1= %s, SW2= %s, X= %d, Y= %d\n",
           fdata.header==VALID?"VALID  ":"INVALID", 
           fdata.sw1==ON?"ON ":"OFF", 
           fdata.sw2==ON?"ON ":"OFF",
           fdata.x_pos, 
           fdata.y_pos) ;
#endif
    
    /*INVALID状態の時 nagasa+1 を行わない*/
    if(fdata.header == INVALID){
        continue;
    }
    
    nagasa++;
    
    /*終了*/
    if (fdata.x_pos > 20000 && fdata.y_pos < 3200 )
        return MAX;
    
    /*1文字認識*/
    else if (fdata.x_pos > 20000 && fdata.y_pos > 5000 
         && fdata.y_pos < 9300) 
        return honsu; 
    
    /*それ以外の時の処理*/
    else if( fdata.sw1 == OFF){
        moji[j] = nagasa;
        nagasa = 0;
        honsu++;
        j++;
    }
    }   
}
 
 
void get_line(char buffer[])
{
    int i, j = 0, k = 0, l;
    char temp[MAXSIZE];
    
    for(i = 0; i < MAXSIZE; i++){
    temp[i] = '\0';
    moji_data[i] = '\0';
    }
    
    for(i = 0; ; i++){
    if(buffer[i] == '\n')
        break;
    else if(buffer[i] == ' '){
        moji_data[k] = atoi(temp);
        k++;
        for(l = 0; l < MAXSIZE; l++)
        temp[l] = '\0';
        j = 0;
        continue;
    }
    else{
        temp[j] = buffer[i];
        j++;
    }
    }
}
 
 
void recog(int honsu, FILE *fp)
{
    int i;
    float t_value;
    char buffer[1024];
    
    fgets(buffer, 1024, fp);
    
    while(! feof(fp)){
    t_value = 0;
    get_line(buffer);   
    
    if(moji_data[1] == honsu){
        for(i = 0; i < honsu - 1; i++)
        t_value += sqrt((moji[i + 1] * 100 / moji[0] - moji_data[i + 3]
              * 100 / moji_data[2])
              * (moji[i + 1] * 100 / moji[0] - moji_data[i + 3]
                   * 100 / moji_data[2]));
        printf("value = %.3f  t_value = %.3f\n", value, t_value);
        if(value > t_value){
        value = t_value;
        word[0] = moji_data[0];
        for(i = 0; i < honsu; i++)
            word[i + 1] = moji_data[i + 2];
        }
    }   
    fgets(buffer, 1024, fp);
    }
}
 
 
int input_YorN()
{
    char a = '\0';
    
    while((a != 'Y') && (a != 'y') && (a != 'N') && (a != 'n')){
    printf("(y/n):");
    scanf("%c", &a);
    }
    return a;
}
 
 
menu1()
{
    int i, j, honsu, a1, a2, flag;
    char a;
    
    FILE *fp[2];
    
    while(1){
    flag = 1, value = MAX;
    printf("\n\nペンで認識したい文字を書いて認識ボタンを押してください\n");
    printf("(終了:タブレット上の終了ボタンを押す\n");
    
    for(i = 0; i < MAXSIZE; i++){
        moji[i] = '\0';
        line[i] = '\0';
        word[i] = '\0';
        moji_data[i] = '\0';
    }
    
    if((fp[0] = fopen("/dev/ttyb", "r")) == NULL){
        printf("/dev/ttyb がオープンできません\n");
        exit(0);
    }
    
    if((fp[1] = fopen("Moji_data", "a+")) == NULL){
        printf("Moji_data がオープンできません\n");
        exit(0);
    }
    fclose(fp[1]);
 
    fp[1] = fopen("Moji_data", "r");
 
    honsu = input_moji(fp[0]);
    
    if(honsu == MAX){  /*終了*/
        fclose (fp[0]);
        fclose (fp[1]);
        return;
    }
    
    recog(honsu, fp[1]);
    
    fclose(fp[1]);
    fp[1] = fopen("Moji_data", "a+");
    
        printf("\n\n入力画数は %d 画\n", honsu);
        printf("1画1画の長さの比は : ");
        for(i = 0; i < honsu; i++)
            printf("%d ", moji[i]);
        printf("\n\n");
    
    printf("---------- 認識結果 ----------\n");
    if(value == MAX){
        printf("\n同一画数の文字がありません\n");
        a = 'N';
    }
    else{
        a1 = (word[0] >> 8) | 0x80;
        a2 = (word[0] & 0xff) | 0x80;
        printf("文字 : %c%c  認識度 : %3f | ", a1, a2, value);
        for(i = 0; i < honsu; i++)
        printf("%d ", word[i + 1]);
        
        printf("\n\n認識結果は正しいですか? ");
        a = input_YorN();
    }
    
    switch(a){
      case 'N': case 'n':
        printf("\n新たな文字として登録します。 \n よろしいですか?");
        a = input_YorN();
        
        if(a == 'Y' || a == 'y'){
        while(flag){
            printf("コードを入力してください。(16進数):");
            scanf("%x", &newword);
            
            a1 = (newword >> 8) | 0x80;
            a2 = (newword & 0xff) | 0x80;
            
            printf("\n%c%c として登録します。\nよろしいですか?", a1, a2);
            
            a = input_YorN();
            
            if(a == 'Y' || a == 'y'){
            fprintf(fp[1], "%d %d ", newword, honsu);
            for(i = 0; i < honsu; i++)
                fprintf(fp[1], "%d ", moji[i]);
            fprintf(fp[1], "\n");
            
            printf("登録しました。\n\n");
            flag = 0;
            }
        }
        }
        else 
        printf("登録をとりりやめました\n\n");
        
        break;
        
      case 'Y': case 'y':
        printf("\n書く人がいいと、こちらとしても助かります。\n\n");
        break;
        
      default:
        break;
    }
    
    fclose(fp[0]);
    fclose(fp[1]);
    }
}
 
 
void menu2()
{
    int i, j = 0, a1, a2;
    char buffer[1024];
    FILE *fp;
    
    if((fp = fopen("Moji_data", "r")) == NULL){
    printf("Moji_data がオープンできません\n");
    exit(0);
    }
    
    printf("\n       ------ 登録内容  ------\n");
    
    fgets(buffer, 1024, fp);
    
    while(! feof(fp)){
    j++;
    get_line(buffer);
    
    a1 = (moji_data[0] >> 8) | 0x80;
    a2 = (moji_data[0] & 0xff) | 0x80;
    
    printf("%c%c  %2d 画 ", a1, a2, moji_data[1]);
    for(i = 0; i < moji_data[1]; i++)
        printf("%d ", moji_data[i + 2]);
    printf("\n");
    
    if(j % 10 == 0){
        printf("HIT RETURN KEY!!\n");
        getchar();
    }
    
    fgets(buffer, 1024, fp);
    }
    printf("\n計%d文字登録されています。\n\n", j);
    fclose(fp);
}
 
 
main()
{
    int num;
    
    while(1){
    printf(" ☆☆☆☆ 手書き文字認識ソフト  珠緒ちゃん β ++ ☆☆☆☆\n\n");
    printf("-----  MENU  -----\n");
    printf("1. 文字認識\n2. 登録文字情報\n3. 終了\n");
    printf("------------------\n");
 
    while(1){
        printf("INPUT 1~3:  ");
        scanf("%d", &num);
 
        if(num == 1){
        menu1();
        break;
        }
        
        if(num == 2){
        menu2();
        break;
        }
        
        else
        exit(0);
    }
    }
}

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 外部デバイスからの入力

#6

投稿記事 by softya(ソフト屋) » 13年前

元々の研究論文はかなりしっかりとした内容で過不足なく情報が書かれていると思います。
この研究論文を読んで分からないとすると移植するのはそもそも困難では無いかと思います。
そもそも、移植したものはNXT上で動かすのですか?それともパソコンで動かすのでしょうか?
※ NXTの開発キットのドキュメントが見当たらないので答えようがないんです。

それとタッチセンサーですが、ご自分でも書かれていますが当たったこと認識するだけで長さだけの処理はできますがベクトル法は出来ませんよ。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

tomomi

Re: 外部デバイスからの入力

#7

投稿記事 by tomomi » 13年前

説明不足で本当にすみません。
基本的にパソコン上で動かします。文字を登録する用のプログラムをパソコンに入れておき、文字の登録データをパソコン上のファイルに保存します。データの計測方法は実際にNXTを介してタッチペンで計測し、NXTからパソコンへ送ります。
文字を認識する用のプログラムは、こちらもパソコンに入れておき、NXTで計測したデータと文字登録で登録されたファイルのデータとを照合し、認識結果をパソコン上に表示します。
NXTでは文字登録用に同じく、データをパソコンに送信するプログラムを入れておきます。

下記のページには、私のやりたいことに近い実験をしています。NXTを用いて文字認識を試みた実験が載っていますが、これに加えて、文字を登録させようとしています。私の説明の補足として参考にしてみてください。
http://www.ml.info.kanagawa-u.ac.jp/pap ... ishita.pdf

説明が下手で申し訳ありません。ですが、本当に困っていて手伝っていただきたいのでお願いします。
また、不明な点があれば教えて下さい。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 外部デバイスからの入力

#8

投稿記事 by softya(ソフト屋) » 13年前

NXTと通信しているライブラリがあるようですが論文には掲載されていません。
import lejos.pc.comm.*;
NXTConnector conn = new NXTConnector();
ココらへんはNXT経験者じゃなく実機もない私はアドバイスできないと思います。
あと、それほど論文にも使われているJavaは得意ではありません。

C/C++のリファレンスらしきものを見つけましたが、これを見てんなとか出来ませんかね?
「nxtOSEK: Embedded Coder Robot NXT」
http://lejos-osek.sourceforge.net/jp/api.htm

【補足】
論文を見て初めてBluetooth通信されていることを知りました。
そういう所が分かっていない人がNXTを使うのは時間的に危険な気がします。
他の入力デバイスはないのですか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

tomomi

Re: 外部デバイスからの入力

#9

投稿記事 by tomomi » 13年前

すみません。
いろいろとテンパっていて何も考えられず、まとまらないまま質問してしまいました。
もう一度自分で整理してじっくり考えてから質問させていただきます。
お手数おかけしました。
アドバイスありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る