以前、AR電卓というソフトを思いついて作っている。
それをOculus Rift DK1+Ovrvisionカメラ用に移植してみている。
Ovrvision用キャプチャーソフトと元のソースコードを合体させてとりあえず動かしてみたというレベルで、開発の初期段階だったりする。
ソースコードはこんな感じになっている。
OCRライブラリTesseractの処理がちょっと負荷があってフレームレートを落としている気がするので、OCR処理の部分だけマルチスレッドにして、フレームを飛ばして処理する形にしたほうがよさそうだ。
//-----------------------------------------------------------------------------------
// AR-Calc (Augmented Reality Calculator) ver 0.1 by E.Kako @kako.com (c)2012-2015
//-----------------------------------------------------------------------------------
// Standard header
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ovrvision.h"
#pragma comment( lib, "ovrvision.lib")
// tesseract Lib header
#include "baseapi.h"
#include "strngs.h"
//OpenCV Lib header
#include "opencv2/opencv.hpp"
//OpenCV Libs
#pragma comment( lib, "lib/opencv_core242.lib")
#pragma comment( lib, "lib/opencv_highgui242.lib")
#pragma comment( lib, "lib/opencv_imgproc242.lib")
int parse_expression(char *text,int pos,char *text2);
OVR::Ovrvision* g_pOvrvision;
//------------------------------------------------------------------------------
// Main program
//------------------------------------------------------------------------------
int main()
{
tesseract::TessBaseAPI tessBaseApi;
tessBaseApi.Init(".","eng");
tessBaseApi.SetVariable("tessedit_char_whitelist", "0123456789+-xX="); // limit char
IplImage *image,*frame1,*frame2,*frame1_copy,*frame2_copy;
IplImage *gray;
CvRect rect1s,rect2s,rect1d,rect2d;
int w,h,adj;
CvFont fnt;
char buf[256];
int y=0;
int pos;
g_pOvrvision = new OVR::Ovrvision();
if (g_pOvrvision->Open(0,OVR::OV_CAMVGA_FULL)!=OV_RESULT_OK) {
printf("Ovrvision camera not found.\n"); getchar();
return -1;
}
w = g_pOvrvision->GetImageWidth();
h = g_pOvrvision->GetImageHeight();
frame1 = cvCreateImage(cvSize(w,h), 8, 3);
frame2 = cvCreateImage(cvSize(w,h), 8, 3);
frame1_copy = cvCreateImage(cvSize(w,h), 8, 3);
frame2_copy = cvCreateImage(cvSize(w,h), 8, 3);
image = cvCreateImage(cvSize(w,h), 8, 3);
gray = cvCreateImage(cvSize(w,h), 8, 1);
// font init
cvInitFont (&fnt, CV_FONT_HERSHEY_SIMPLEX,1,1,0,2,CV_AA);
adj = w/32;
rect1s = cvRect(w/4+adj,0, w/2,h);
rect2s = cvRect(w/4-adj,0, w/2,h);
rect1d = cvRect(w/2,0, w/2,h);
rect2d = cvRect(0 ,0, w/2,h);
cvNamedWindow("image", 0);
cvSetWindowProperty("image",CV_WND_PROP_FULLSCREEN,CV_WINDOW_FULLSCREEN); // fullscreen
// main loop
while(1) {
if(cvWaitKey( 1 ) >= 0) { break; } // any key to quit
// get image
g_pOvrvision->PreStoreCamData();
g_pOvrvision->GetCamImage((unsigned char *)frame1->imageData,OVR::OV_CAMEYE_LEFT);
g_pOvrvision->GetCamImage((unsigned char *)frame2->imageData,OVR::OV_CAMEYE_RIGHT);
cvCvtColor(frame1,frame1_copy,CV_RGB2BGR);
cvCvtColor(frame2,frame2_copy,CV_RGB2BGR);
cvFlip(frame1_copy,NULL, -1); // flip
cvFlip(frame2_copy,NULL, -1); // flip
cvSetImageROI(frame1_copy,rect1s);
cvSetImageROI(image,rect1d);
cvCopy(frame1_copy, image);
cvSetImageROI(frame2_copy,rect2s);
cvSetImageROI(image,rect2d);
cvCopy(frame2_copy, image);
cvResetImageROI(image);
cvResetImageROI(frame1_copy);
cvResetImageROI(frame2_copy);
cvCvtColor( frame1_copy, gray, CV_RGB2GRAY); // convert to grayscale
// OCR Tesseract
{
char *text = tessBaseApi.TesseractRect(
(unsigned char *)gray->imageData, gray->nChannels, gray->widthStep,
0, 0, gray->width, gray->height);
pos=0; y=0;
while (1) {
int ret;
ret = parse_expression(text,pos,buf);
if ((ret== -1)||(buf[0]=='\0')||(buf==NULL)) { break; }
pos=ret;
cvPutText(image, buf , cvPoint(50, 50+y), &fnt, CV_RGB(255,0,0));
y+=50;
}
}
cvShowImage("image", image); // display
}
// close
g_pOvrvision->Close();
cvDestroyAllWindows();
// release
cvReleaseImage(&gray);
cvReleaseImage(&image);
cvReleaseImage(&frame1);
cvReleaseImage(&frame2);
cvReleaseImage(&frame1_copy);
cvReleaseImage(&frame2_copy);
return 0;
}
int parse_expression(char *text,int pos,char *text2)
{
int len,n,f;
int i,j,k;
int a,b,op,result;
char c;
static char buf[256];
len=strlen(text);
while (pos<len) {
n=0;
f=0;
for (i=pos;i<len;i++) {
c=text[i];
if ((c=='\r')||(c=='\n')) { break; }
if (c=='=') { f=1; } // found (=)
n++;
if (i>254) { break; }
}
text2[0]='\0';
if (f==1) {
j=0;
k=0;
for (i=0;i<n;i++) {
c=text[pos+i];
if ((i==0)&&(c=='+')) { continue; }
if ((i==0)&&(c=='-')) { continue; }
if ((i==0)&&(c=='x')) { continue; }
if ((i==0)&&(c=='X')) { continue; }
if ((i==0)&&(c=='=')) { continue; }
if (c=='=') { break; }
if (c=='+') { op=1; k=j; }
if (c=='-') { op=2; k=j; }
if (c=='x') { op=3; k=j; }
if (c=='X') { op=3; k=j; }
if (c==' ') { continue; }
buf[j++]=c;
}
buf[j]='\0';
if (k==0) {
sscanf(buf,"%d",&result);
} else {
sscanf(buf,"%d",&a);
sscanf(buf+k+1,"%d",&b);
if (op==1) { result = a+b; }
if (op==2) { result = a-b; }
if (op==3) { result = a*b; }
}
sprintf(buf,"%s = %d",buf, result);
strcpy(text2,buf);
}
pos += (n+1);
return pos;
}
return -1;
}