1. 程式人生 > >基於OpenCV的視訊影象組態 (2) :動畫總體

基於OpenCV的視訊影象組態 (2) :動畫總體

複製程式碼
/**

 *@class TCbwAnimationEffect

 *@brief 動畫基類

 *

 * 處理動畫基本內容

 *@author DrGraph

 *@version 1.0

 *@date 2017-10-07

 *@QQ: 282397369

 */

class TCbwAnimationEffect {

         bool__fastcall IsAtEnd();

         CbwObjectsFAnimationObjects; // 相關物件

   

         cv::Mat__fastcall Object2Mat(TCbwObject 
* object, double ratio = 1); int__fastcall GetRepeateTime(); protected: vector<OBJECTMAT>FDestMats; intFCurrentIndex; // 當前幀索引 intFPeriodLength; // 週期長度,指動畫一個週期內的幀數 intFPosition; // 當前位置,指動畫累加索引位置 intFWidth, FHeight; // 長寬尺寸,指顯示限制 public
: CbwEffectTypeEffectType; ENHANCE_INFOEnhanceOption; // 增強選項 TIMER_INFOTimerOption; // 計時選項 __fastcallTCbwAnimationEffect(); staticTCbwAnimationEffect * Build(); void__fastcall Assign(TCbwAnimationEffect * other); void__fastcall AddToXmlNode(CbwXmlNode
* node); void__fastcall GetFromXmlNode(CbwXmlNode * node); void__fastcall First(); void__fastcall Next(); void__fastcall SetRelativeObject(CbwObjects relativeObjects, TPaintBox* pb, TScrollBox * scrollBox); void__fastcall SetBounds(int width, int height); void__fastcall Draw(HWND wnd, BYTE * backData, int width, int height); cv::MatCurrentMat; __propertybool Eof = {read = IsAtEnd}; protected: virtualTRect __fastcall BuildDisplayRect(OBJECTMAT * m); virtualvoid __fastcall BuildDisplayMat(cv::Mat& destMat, cv::Mat& srcMat); virtualvoid __fastcall BuildMaskMat(cv::Mat& destMat, cv::Mat& srcMat); }; 核心實現程式碼為: __fastcallTCbwAnimationEffect::TCbwAnimationEffect() { TimerOption.StartMode= ttsClick; TimerOption.Delay= 0; TimerOption.PeriodMode= ttpNormal; TimerOption.RepeatMode= ttrNone; TimerOption.QuickBackAfterPlay= false; EffectType= cetBase; } TCbwAnimationEffect *TCbwAnimationEffect::Build() { returnnew TCbwAnimationEffect; } TRect __fastcallTCbwAnimationEffect::BuildDisplayRect(OBJECTMAT * m) { TRectresult(m->LeftTopPosition.x, m->LeftTopPosition.y, m->LeftTopPosition.x+ m->Mat.cols, m->LeftTopPosition.y + m->Mat.rows); returnresult; } void __fastcall TCbwAnimationEffect::BuildDisplayMat(cv::Mat&destMat, cv::Mat&srcMat) { destMat= srcMat.clone(); } void __fastcallTCbwAnimationEffect::BuildMaskMat(cv::Mat& destMat, cv::Mat&srcMat) { destMat= srcMat.clone(); } void __fastcallTCbwAnimationEffect::Draw(HWND wnd, BYTE * backData, int width, intheight) { cv::MatbackGndMat(height, width, CV_8UC3); // 背景 GlobalOpenCVObject->CopyRGBDatasToMat(backGndMat,backData, width, height,true); CBW_ITERATOR(vector<OBJECTMAT>,FDestMats) { OBJECTMAT* animationObject = &(*it); //以下取得待顯示的區域、內容 TRectanimationDisplayRect = BuildDisplayRect(animationObject); // 目標區域 cv::MatanimationDisplayMat = cv::Mat::zeros(animationDisplayRect.Height(), animationDisplayRect.Width(),animationObject->Mat.type()); BuildDisplayMat(animationDisplayMat,animationObject->Mat); // 待顯示內容 cv::MatmaskMat = cv::Mat::zeros(animationObject->Mask.rows, animationObject->Mask.cols,animationObject->Mask.type()); BuildMaskMat(maskMat,animationObject->Mask); // Mask內容 TRectsuitableDisplayRect; // 真正的目標顯示區域 suitableDisplayRect.left= max(0, int(animationDisplayRect.left)); suitableDisplayRect.top= max(0, int(animationDisplayRect.top)); suitableDisplayRect.right= min(int(animationDisplayRect.right), width); suitableDisplayRect.bottom= min(int(animationDisplayRect.bottom), height); TRectsuitableRectInMat(0, 0, suitableDisplayRect.Width(), suitableDisplayRect.Height()); intdeltaL = max(0,int(suitableDisplayRect.left - animationDisplayRect.left)); if(suitableDisplayRect.left != animationDisplayRect.left) { suitableRectInMat.left+= deltaL; suitableRectInMat.right+= deltaL; } intdeltaT = max(0,int(suitableDisplayRect.top - animationDisplayRect.top)); if(suitableDisplayRect.top != animationDisplayRect.top) { suitableRectInMat.top+= deltaT; suitableRectInMat.bottom+= deltaT; } cv::MatdestPartMat = animationDisplayMat(cv::Rect(suitableRectInMat.left, suitableRectInMat.top,suitableRectInMat.Width(), suitableRectInMat.Height())); cv::MatbackgndPartMat = // 目標背景區域相應矩陣 backGndMat(cv::Rect(suitableDisplayRect.left, suitableDisplayRect.top,suitableDisplayRect.Width(), suitableDisplayRect.Height())); cv::MatmaskPartMat = maskMat(cv::Rect(deltaL,deltaT, suitableDisplayRect.Width(), suitableDisplayRect.Height())); destPartMat.copyTo(backgndPartMat,maskPartMat); } GlobalOpenCVObject->PreviewMat(wnd,backGndMat, width, height); } void __fastcallTCbwAnimationEffect::Assign(TCbwAnimationEffect * other) { TimerOption.StartMode= other->TimerOption.StartMode; TimerOption.Delay= other->TimerOption.Delay; TimerOption.PeriodMode= other->TimerOption.PeriodMode; TimerOption.RepeatMode= other->TimerOption.RepeatMode; TimerOption.QuickBackAfterPlay= other->TimerOption.QuickBackAfterPlay; } bool __fastcallTCbwAnimationEffect::IsAtEnd() { boolresult = (FPosition >= FPeriodLength * GetRepeateTime()); returnresult; } void __fastcall TCbwAnimationEffect::First(){ FPosition= 0; FCurrentIndex= 0; } void __fastcall TCbwAnimationEffect::Next(){ ++FPosition; FCurrentIndex= FPosition % FPeriodLength; } cv::Mat __fastcallTCbwAnimationEffect::Object2Mat(TCbwObject * object, doubleratio) { TCanvas* oldCanvas = object->Canvas; Graphics::TBitmap* bitmap = new Graphics::TBitmap; bitmap->PixelFormat= pf24bit; bitmap->Width= object->Width; bitmap->Height= object->Height; TCanvas* canvas = bitmap->Canvas; boolallowDraw = object->AllowDraw; boololdDrawBorderFlag = object->DrawBorderFlag; object->AllowDraw= false; { TRestoreleft(object, "Left", 0); TRestoretop(object, "Top", 0); object->Canvas= canvas; object->AllowDraw= allowDraw; object->DrawBorderFlag= false; object->Draw(); object->AllowDraw= false; }object->Canvas = oldCanvas; object->AllowDraw= allowDraw; object->DrawBorderFlag= oldDrawBorderFlag; BYTE* backData = THelper::Graphics::GetBitmapData(bitmap); cv::Matresult; GlobalOpenCVObject->CopyRGBDatasToMat(result,backData, bitmap->Width, bitmap->Height,true); deletebitmap; deletebackData; returnresult; } void __fastcallTCbwAnimationEffect::OBJECTMAT::BuildMask(int height, int width) { Mask= cv::Mat(height, width, CV_8UC1); BYTE* pSrc = Mat.data; BYTE* pDst = Mask.data; for(int i = height * width - 1; i >= 0; --i) { BYTEB = *pSrc++; BYTEG = *pSrc++; BYTER = *pSrc++; *pDst++= (B == 0xFF && G == 0xFF && R == 0xFF) ? 0 : 255; } } void __fastcallTCbwAnimationEffect::SetRelativeObject (CbwObjectsrelativeObjects, TPaintBox * pb, TScrollBox * scrollBox) { CBW_ITERATOR(CbwObjects,relativeObjects) { cv::Matmat = Object2Mat(*it); TPointlt = TPoint((*it)->Left, (*it)->Top); lt= pb->ClientToScreen(lt); lt= scrollBox->ScreenToClient(lt); OBJECTMATm; m.Mat= mat; m.LeftTopPosition= lt; m.Object= *it; m.BuildMask((*it)->Height,(*it)->Width); FDestMats.push_back(m); } FPeriodLength= 50; FCurrentIndex= 0; FPosition= 0; } void __fastcallTCbwAnimationEffect::SetBounds(int width, int height) { FWidth= width; FHeight= height; }
複製程式碼