Exemplo n.º 1
0
void IIBackgroundSubtractor::setROI(cv::Mat& oROI) {
    validateROI(oROI);
    CV_Assert(cv::countNonZero(oROI)>0);
    if(m_bInitialized) {
        cv::Mat oLatestBackgroundImage;
        getBackgroundImage(oLatestBackgroundImage);
        initialize(oLatestBackgroundImage,oROI);
    }
    else
        m_oROI = oROI.clone();
}
Exemplo n.º 2
0
// Do recursive ray tracing!  You'll want to insert a lot of code here
// (or places called from here) to handle reflection, refraction, etc etc.
vec3f RayTracer::traceRay( Scene *scene, const ray& r, 
	const vec3f& thresh, int depth )
{
	isect i;

	if( scene->intersectMode( r, i ) ) {
		// YOUR CODE HERE

		// An intersection occured!  We've got work to do.  For now,
		// this code gets the material for the surface that was intersected,
		// and asks that material to provide a color for the ray.  



		// This is a great place to insert code for recursive ray tracing.
		// Instead of just returning the result of shade(), add some
		// more steps: add in the contributions from reflected and refracted
		// rays.

		const Material& m = i.getMaterial();
		vec3f I = m.shade(scene, r, i);
		if (depth >= maxDepth)return I;
		if (thresh.length() < maxThresh-RAY_EPSILON)return I;

		vec3f conPoint = r.at(i.t);
		vec3f normal;
		vec3f Rdir = 2 * (i.N*-r.getDirection()) * i.N - (-r.getDirection());
		//reflection
		ray R = ray(conPoint, Rdir);
		vec3f newThres = prod(thresh, i.getMaterial().kr);
		if (!i.getMaterial().kr.iszero())I += prod(i.getMaterial().kr, traceRay(scene, R, newThres, depth + 1));

		//if not opaque
		if (!i.getMaterial().kt.iszero()){

			bool TIR = false;

			//refraction
			ray T(conPoint, r.getDirection());//without refraction

			bool toAdd = false, toErase = false;
			//if not surface
			if (i.obj->hasInterior()){
				//calculate angle
				//in or out
				double indexA, indexB;
				if (i.N*r.getDirection() > RAY_EPSILON){//out
					if (mediaHistory.empty())indexA = 1.0;
					else indexA = mediaHistory.rbegin()->second.index;

					mediaHistory.erase(i.obj->getOrder());
					toAdd = true;
					if (mediaHistory.empty())indexB = 1.0;
					else {
						indexB = mediaHistory.rbegin()->second.index;
					}
					normal = -i.N;
				}
				else {//in
					if (mediaHistory.empty())indexA = 1.0;
					else indexA = mediaHistory.rbegin()->second.index;
					
					mediaHistory.insert(make_pair(i.obj->getOrder(),i.getMaterial()));
					toErase = true;
					indexB = mediaHistory.rbegin()->second.index;
					normal = i.N;
				}
				double indexRatio = indexA / indexB;
				double cdi = normal*-r.getDirection();
				double sdi = 1 - cdi*cdi;
				double sdt = sdi * indexRatio; //sin delta t
				//TIR
				if (sdt > 1.0 + RAY_EPSILON){
					TIR = true;
				}
				else {
					TIR = false;
					double cdt = sqrt(1 - sdt*sdt);
					vec3f Tdir = (indexRatio*cdi - cdt)*normal - indexRatio*-r.getDirection();
					T = ray(conPoint, Tdir);
				}
			}
			newThres = prod(thresh, i.getMaterial().kt);
			if(!TIR)I += prod(i.getMaterial().kt, traceRay(scene, T, newThres, depth + 1));
			if (toAdd)mediaHistory.insert(make_pair(i.obj->getOrder(), i.getMaterial()));
			if (toErase)mediaHistory.erase(i.obj->getOrder());
		}
		I = I.clamp();

		return I;
	
	} else {
		// No intersection.  This ray travels to infinity, so we color
		// it according to the background color, which in this (simple) case
		// is just black.
		if (!useBackground)return vec3f(0.0, 0.0, 0.0);
		else {
			vec3f axis_x = scene->getCamera()->getU();
			vec3f S = r.getDirection();
			S -= (S*axis_x)*axis_x;
			vec3f axis_z = scene->getCamera()->getLook();
			vec3f sz = (S*axis_z) *axis_z;
			S -= sz;
			vec3f axis_v = scene->getCamera()->getV();
			vec3f axis_y = axis_x.cross(axis_z);
			double dis_v = (S*axis_y);
			S = r.getDirection() - dis_v * axis_v;
			double dis_x = S * axis_x;
			double dis_z = S * axis_z;
			vec3f res = dis_x * axis_x + dis_v * axis_v + dis_z * axis_z;
			return getBackgroundImage(dis_x / dis_z + 0.5, dis_v / dis_z + 0.5);
		}
		
	}
}
void FkMainWorker::run(){
	IplImage* frame;
	IplImage* bgImage = cvCreateImage(camera.getResolution(), IPL_DEPTH_8U, 3);
#ifndef WIN32
	CvRect piCamResolution = cvRect(100, 100, 440, 330); 
#endif
	setWindow();	//cvNamedWindow() Method must be called in run() method of thread
	while(1){
		key->lock();
		timer->signal();
		timer->await();
		key->unlock();
		frame = this->camera.getQueryFrame();
		if(!frame)
			continue;
		if(preProcessor.cameraCalibrator.isCamCalibrated()){
#ifdef WIN32
			cvFlip(frame, dstImage, 1);
#else
			cvFlip(frame, frame, 1);
			cvSetImageROI(frame, piCamResolution);
			cvResize(frame, dstImage);

#endif	

		}
		else{
#ifdef WIN32
			cvFlip(frame, dstImage, 1);
#else
			cvFlip(frame, frame, 1);
			cvSetImageROI(frame, piCamResolution);
			cvResize(frame, dstImage);
#endif	
		}
		if(mouseListener.isSettingROI())
			imageProcessor.paperAreaDraggingImage(dstImage, mouseListener);
		if(FkCurrentMode::state){
			if(FkCurrentMode::state  == CONFIRM_KB_REGION){
				preProcessor.paperKeyboardRecognizer.setSelectedPaperKeyboard(mouseListener.getMouseDragArea());
				mouseListener.setBenchmarkPoint();
				imageProcessor.drawSelectedArea(dstImage, preProcessor.paperKeyboardRecognizer.getSelectedPaperKeyboard());
			}
			else if(FkCurrentMode::state == SET_KB_CORNER){
				if(preProcessor.paperKeyboardRecognizer.setPaperKeyboardCorner(dstImage, mouseListener) == -1){
					FkCurrentMode::state = SET_KB_REGION;
					mouseListener.resetMouseDragArea();
					message->showMessage("MESSAGE : 종이 키보드 선택이 정확하지 않습니다");  
				}
				else
					FkCurrentMode::state = CONFIRM_KB_CORNER;
			}
			else if(FkCurrentMode::state == CONFIRM_KB_CORNER || FkCurrentMode::state == ADJUST_KB_CORNER){
				cvSetImageROI(dstImage, preProcessor.paperKeyboardRecognizer.getSelectedPaperKeyboard());
				imageProcessor.drawPaperKeyboardCorner(dstImage);
				cvResetImageROI(dstImage);
				if(mouseListener.isAdjustCorner())
					imageProcessor.paperAreaDraggingImage(dstImage, this->mouseListener);
			}
			else if(FkCurrentMode::state == CATCH_KB_CORNER){
				cvSetImageROI(dstImage, preProcessor.paperKeyboardRecognizer.getSelectedPaperKeyboard());
				imageProcessor.drawPaperKeyboardCorner(dstImage);
				cvResetImageROI(dstImage);
				imageProcessor.drawSelectedArea(dstImage, mouseListener.getMouseDragArea());
			}
			else if(FkCurrentMode::state == MOVE_KB_CORNER){
				cvSetImageROI(dstImage, preProcessor.paperKeyboardRecognizer.getSelectedPaperKeyboard());
				imageProcessor.drawPaperKeyboardCorner(dstImage);
				cvResetImageROI(dstImage);
			}
			else if(FkCurrentMode::state == SET_KB_BUTTON){
				preProcessor.paperKeyboardRecognizer.setKeyButton(dstImage);
				preProcessor.paperKeyboardRecognizer.setKeyButtonImage(dstImage);
				getBackgroundImage(dstImage, bgImage);
				if(preProcessor.cameraCalibrator.isCamCalibrated())
					FkCurrentMode::state = WAIT_HAND;
				else
					FkCurrentMode::state = SET_CAM_CALIB;
			}
			else if(FkCurrentMode::state == SET_CAM_CALIB){
				//preProcessor.cameraCalibrator.cameraCalibration(dstImage, this->paperKeyboard);
				FkCurrentMode::state = SET_KB_REGION;
			}
			else if(FkCurrentMode::state == WAIT_HAND){
				imageProcessor.drawHandInputCircle(dstImage);
			}
			else if(FkCurrentMode::state == SET_HIST){
				preProcessor.skinColorDetector.createSkinColorHistogram(dstImage);
				FkCurrentMode::state = INPUT_AVAILABLE;
			}
			else if(FkCurrentMode::state == INPUT_AVAILABLE){
				//method.1  손가락 검출 1번 방법을 사용하기 위해선 getBackgroundImage()에서 dstImage의 Color Model을 HSV로 변경
			/*	postProcessor.fingerTipDetector.getHandBinaryImage(dstImage, bgImage, preProcessor.skinColorDetector.skinColorHistogram, 1);
				postProcessor.fingerTipDetector.detectHandContour(preProcessor.paperKeyboardRecognizer.getSelectedPaperKeyboard());
				postProcessor.fingerTipDetector.detectFingerTip(dstImage);*/
				
				//method.2	손가락 검출 2번 방법을 사용하기 위해선 getBackgroundImage()에서 dstImage의 Color Model을 YCrCb로 변경
				postProcessor.fingerTipDetector.getHandBinaryImage(dstImage, bgImage, preProcessor.skinColorDetector.skinColorHistogram);
				postProcessor.fingerTipDetector.detectHandContour(preProcessor.paperKeyboardRecognizer.getSelectedPaperKeyboard());
				postProcessor.fingerTipDetector.detectFingerTip();

				postProcessor.fingerTipDetector.calcMotionProperty();

				motionLogger->writeMotion();
				imageProcessor.drawFingerTip(dstImage,postProcessor.fingerTipDetector.detectHandCount, postProcessor.fingerTipDetector.userHand);
				postProcessor.keyButtonEventListener.keyEventProcessing();
				postProcessor.keyButtonEventListener.setInputAvailable();
				postProcessor.fingerTipDetector.resetData();
				cvWriteFrame(vout, dstImage);
			}
		}
		if(FkCurrentMode::state > CONFIRM_KB_REGION && FkCurrentMode::state < WAIT_HAND)
			imageProcessor.drawDetermineArea(dstImage, preProcessor.paperKeyboardRecognizer.getSelectedPaperKeyboard());
		cvShowImage(WINDOW_NAME, dstImage);
		exitKey->lock();
#ifndef _WINDOWS
		if((cvWaitKey(1)) == 27){
			exitKey->unlock();
			break;
		}
#else
		cvWaitKey(1);
#endif
		exitKey->unlock();
	}
}