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(); }
// 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(); } }