Oculus Rift DK1とOvrvisionカメラでAR電卓を動かす

以前、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;
}



コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

Time limit is exhausted. Please reload CAPTCHA.

3 + 6 =