1. 程式人生 > >VTK(2)—— 雙view,顯示並聯動操作

VTK(2)—— 雙view,顯示並聯動操作

前言:接到一個新的需求

window單視窗程式,雙view,顯示並聯動操作,做了兩種方式進行實現,程式碼思路和原始碼如下:

(一)程式碼思路

一、判定誰動了?

方法1:通過當前事件的視窗位置與視窗大小中心軸進行比對

方法2:通過移動後的相機位置與兩個view中相機的位置進行比對

方法3:獲取當前renderer, 與兩個renderer 做對比

二、如何捕獲事件?
方法1:繼承自vtkCommand重寫回調
         Step1: 定義回撥函式,繼承自vtkCommand
         Step2: 設定回撥函式
         Step3: 為兩個view的相機新增觀察者,通過AddObserver(vtkCommand::ModifiedEvent,callback)
         (其中ModifiedEvent可以接收任意發生事件,
         當有事件產生時,interactor底層會呼叫ModifiedEvent事件,callback為step1自定義的回撥函式)

方法2:vtkInteractorStyleTrackballCamera 重寫響應事件
         Step1: 自定義互動型別,繼承自vtkInteractorStyleTrackballCamera
         Step2: 重寫OnMouseMove()等方法

三、如何根據一個view變化設定另一個view?
方法1:將要設定的view中的相機的狀態設定為變化的相機狀態
           (因為在vtk中影象變化預設採用的是相機移動方式,在此先不討論actor變化方式)
           (注:vtk中的相機,主要由三個因素決定:1.焦點 2.相機位置 3.向上方向)(另外也可以通過直接獲取相機來設定想讓變化的相機狀態)
         Step1: 獲取改變的相機的狀態,通過GetPosition(), GetFocalPoint(), GetViewUp() 進行獲得
         Step2: 設定要改變的相機的狀態,通過SetPosition(), SetFocalPoint(), SetViewUp() 進行設定

         Step3: 使用vtkRenderer的ResetCameraClippingRange()方法重置影象的法向量
         Step4: 如果訊號沒有進行同步,需要手動呼叫vtkRendererWindow的Render()方法

方法2:建立一個相機物件,給左右兩個renderer新增同一個相機物件

方法3:通過獲取當前相機,將兩個renderer的相機設定為當前相機

四、同類型問題思考?

一個view中,兩個actor,根據滑鼠指向不同,可挪動不同的物體。(這個實現起來相對簡單一點,vtk有現成的函式)

方法:使用 vtkInteractorStyleTrackballActor 的互動模式即可實現

(二)Demo原始碼

第1種實現方式:

方法說明:

  • 實現方式:繼承自vtkCommand重寫回調
  • 相機設定:兩個 renderer 公用一個相機(注:當不使用一個 camera 設定兩個 renderer 的時候,如果viewsation不是對稱的 會出現互動最開始兩個相機相對物體的位置進行同步)
  • 聯動函式:通過判斷當前相機 與左右兩個相機比對判定哪邊動了,包含兩種判斷方法
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkProperty.h>
#include <vtkCallbackCommand.h>
#include <vtkTransform.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkCamera.h>
#include <QDateTime>


class myCallbackFunc:public vtkCommand
{
public:
    static  myCallbackFunc *New()
    {
        return new myCallbackFunc;
    }
    
    void SetLeftRender(vtkRenderer *leftRender)
    {
        this->m_leftRender = leftRender;
    }
    void SetRightRender(vtkRenderer *rightRender)
    {
        this->m_rightRender = rightRender;
    }
    
  
    virtual void Execute(vtkObject *caller, unsigned long eventId, void* callData)
    {
        vtkCamera *camera = reinterpret_cast<vtkCamera*>(caller);
        vtkCamera *leftCamera = m_leftRender->GetActiveCamera();
        vtkCamera *rightCamera = m_rightRender->GetActiveCamera();
 
        double *act_position     = camera->GetPosition();
        double *act_FocalPoint   = camera->GetFocalPoint();
        double *act_ViewUp       = camera->GetViewUp();
      
        //方法一:指標判斷
        if (leftCamera == camera)
        {
            if (rightCamera->GetPosition() != act_position)
            {
                rightCamera->SetPosition(act_position);
            }
            if (rightCamera->GetViewUp() != act_ViewUp)
            {
                rightCamera->SetFocalPoint(act_FocalPoint);
            }
            if (rightCamera->GetViewUp() != act_ViewUp)
            {
                rightCamera->SetViewUp(act_ViewUp);
            }
        }
        else if (rightCamera == camera)
        {
            if (leftCamera->GetPosition() != act_position)
            {
                leftCamera->SetPosition(act_position);
            }
            if (leftCamera->GetViewUp() != act_ViewUp)
            {
                leftCamera->SetFocalPoint(act_FocalPoint);
            }
            if (leftCamera->GetViewUp() != act_ViewUp)
            {
                leftCamera->SetViewUp(act_ViewUp);
            }
        }
        
        //方法二:camera具體細節判斷
        
//        if (    (isSame(act_position, leftCamera->GetPosition()))
//              &&(isSame(act_FocalPoint, leftCamera->GetFocalPoint()))
//              &&(isSame(act_ViewUp,leftCamera->GetViewUp())))
//        {
//            rightCamera->SetPosition(act_position);
//            rightCamera->SetFocalPoint(act_FocalPoint);
//            rightCamera->SetViewUp(act_ViewUp);
//            this->m_rightRender->ResetCameraClippingRange();
//        }
//        else
//        {
//            leftCamera->SetPosition(act_position);
//            leftCamera->SetFocalPoint(act_FocalPoint);
//            leftCamera->SetViewUp(act_ViewUp);
//            this->m_leftRender->ResetCameraClippingRange();
//        }
                               
    }
    
//private:
    
//    //計算獲取到的相機是否為leftRender或rightRender的相機
//    static bool isSame(double *value0, double *value1) {
//        bool result = true;
//        for (int idx = 0; idx != 3; ++idx) {
//            result = result && qFuzzyCompare(value0[idx], value1[idx]);
//        }
//        return result;
//    }
    
private:
    //此處為雙view,若為多view,可設定陣列,通過提供引數進行設定
    vtkRenderer     *m_leftRender;
    vtkRenderer     *m_rightRender;
    
};


int main(int, char *[])
{

    vtkSmartPointer<vtkCubeSource>                      cube        = vtkSmartPointer<vtkCubeSource>::New();
    vtkSmartPointer<vtkPolyDataMapper>                  mapper      = vtkSmartPointer<vtkPolyDataMapper>::New();
    vtkSmartPointer<vtkActor>                           actor1      = vtkSmartPointer<vtkActor>::New();
    vtkSmartPointer<vtkActor>                           actor2      = vtkSmartPointer<vtkActor>::New();
    vtkSmartPointer<vtkRenderer>                        leftRender  = vtkSmartPointer<vtkRenderer>::New();
    vtkSmartPointer<vtkRenderer>                        rightRender = vtkSmartPointer<vtkRenderer>::New();
    vtkSmartPointer<vtkRenderWindow>                    renwindow   = vtkSmartPointer<vtkRenderWindow>::New();
    vtkSmartPointer<vtkCamera>                          camera      = vtkSmartPointer<vtkCamera>::New();
    vtkSmartPointer<vtkRenderWindowInteractor>          interactor  = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    vtkSmartPointer<myCallbackFunc>                     callback    = vtkSmartPointer<myCallbackFunc>::New();
    vtkSmartPointer<vtkInteractorStyleTrackballCamera>  style       = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
    
    
    cube->SetCenter(1, 1, 1);
    cube->Update();

    mapper->SetInputConnection(cube->GetOutputPort());
    
    actor1->SetMapper(mapper);
    actor1->GetProperty()->SetColor(.2, .3, .4);
    actor2->SetMapper(mapper);
    actor2->GetProperty()->SetColor(.4, .5, .6);

    double leftViewStation[4] = {0.0, 0.0, 0.4, 1.0};
    double rightViewStation[4] = {0.4, 0.0, 1.0, 1.0};
    
    leftRender->AddActor(actor1);
    leftRender->SetBackground(.6, .5, .4);
    leftRender->SetViewport(leftViewStation);

    rightRender->AddActor(actor2);
    rightRender->SetBackground(.2, .4, .6);
    rightRender->SetViewport(rightViewStation);
    
    camera->SetPosition(4, 4, 4);
    rightRender->SetActiveCamera(camera);
    leftRender->SetActiveCamera(camera);
    
    renwindow->AddRenderer(leftRender);
    renwindow->AddRenderer(rightRender);
    renwindow->SetSize(600, 300);
    renwindow->Render();
    
    callback->SetLeftRender(leftRender);
    callback->SetRightRender(rightRender);

    leftRender->GetActiveCamera()->AddObserver(vtkCommand::ModifiedEvent,callback);
    rightRender->GetActiveCamera()->AddObserver(vtkCommand::ModifiedEvent,callback);
    
    interactor->SetInteractorStyle(style);//使用者通過控制相機對物體旋轉、放大、縮小等操作。 
    
    renwindow->SetInteractor(interactor);
    
    interactor->Initialize();
    interactor->Start();
    
    
    return EXIT_SUCCESS;
}

(棧溢位問題已解決)

第2種實現方式:

方法說明:

  • 實現方式:繼承自:vtkInteractorStyleTrackballCamera,過載 Rotate()
  • 相機設定:兩個 renderer 公用一個相機(注:當不使用一個 camera 設定兩個 renderer 的時候,如果viewsation不是對稱的 會出現互動最開始兩個相機相對物體的位置進行同步)
  • 聯動函式:包含兩種方法 ①通過事件所在視窗位置判斷哪個 render 動 ②獲取當前相機,將兩個相機重置為這個相機的狀態
#include <vtkSmartPointer.h>
#include <vtkCubeSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkProperty.h>
#include <vtkCallbackCommand.h>
#include <vtkTransform.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkCamera.h>
#include <QDateTime>

class myInteractorStyle:public vtkInteractorStyleTrackballCamera
{
public:

    static myInteractorStyle* New()
    {
        return new myInteractorStyle;
    }
    
    void    SetLeftRender(vtkRenderer *render)
    {
        this->m_leftRender = render;
    }
    
    void    SetRightRender(vtkRenderer *render)
    {
        this->m_rightRender = render;
    }

    void Rotate()
    {
        vtkInteractorStyleTrackballCamera::Rotate();
        this->CameraSynchronous();
    }

//****************    方法一: 通過事件所在視窗位置判斷哪個 render 動   ************//
    void    CameraSynchronous()
    {
        vtkCamera *leftCamera = m_leftRender->GetActiveCamera();
        vtkCamera *rightCamera = m_rightRender->GetActiveCamera();
        
        //獲取視窗大小
        int *winSize = this->GetInteractor()->GetRenderWindow()->GetSize();
        
        //獲取事件視窗位置
        int eventStation[3];
        this->GetInteractor()->GetEventPosition(eventStation);
        
        if (eventStation[0] < winSize[0]/2)
        {
            rightCamera->SetPosition(leftCamera->GetPosition());
            rightCamera->SetFocalPoint(leftCamera->GetFocalPoint());
            rightCamera->SetViewUp(leftCamera->GetViewUp());
            m_rightRender->ResetCameraClippingRange();
        
        }
        else
        {
            leftCamera->SetPosition(rightCamera->GetPosition());
            leftCamera->SetViewUp(rightCamera->GetViewUp());
            leftCamera->SetFocalPoint(rightCamera->GetFocalPoint());
            m_leftRender->ResetCameraClippingRange();
                       
        }
        
        
        this->GetInteractor()->GetRenderWindow()->Render();
    }
    
    //****************    方法二: 獲取當前相機,將兩個相機重置為這個相機的狀態   ************//
    //    void    CameraSynchronous()
    //    {
    //        vtkCamera *camera = this->GetCurrentRenderer()->GetActiveCamera();
    //        this->m_leftRender->SetActiveCamera(camera);
    //        this->m_rightRender->SetActiveCamera(camera);
    //    }
    
private:
    vtkRenderer     *m_leftRender;
    vtkRenderer     *m_rightRender;



};


int main(int, char *[])
{

    vtkSmartPointer<vtkCubeSource>              cube        = vtkSmartPointer<vtkCubeSource>::New();
    vtkSmartPointer<vtkPolyDataMapper>          mapper      = vtkSmartPointer<vtkPolyDataMapper>::New();
    vtkSmartPointer<vtkActor>                   actor1      = vtkSmartPointer<vtkActor>::New();
    vtkSmartPointer<vtkActor>                   actor2      = vtkSmartPointer<vtkActor>::New();
    vtkSmartPointer<vtkRenderer>                leftRender  = vtkSmartPointer<vtkRenderer>::New();
    vtkSmartPointer<vtkRenderer>                rightRender = vtkSmartPointer<vtkRenderer>::New();
    vtkSmartPointer<vtkCamera>                  camera      = vtkSmartPointer<vtkCamera>::New();
    vtkSmartPointer<vtkRenderWindow>            renwindow   = vtkSmartPointer<vtkRenderWindow>::New();
    vtkSmartPointer<vtkRenderWindowInteractor>  interactor  = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    vtkSmartPointer<myInteractorStyle>          style       = vtkSmartPointer<myInteractorStyle>::New();
    
    cube->SetXLength(1);
    cube->SetYLength(1);
    cube->SetZLength(1);
    cube->Update();
    
    
    mapper->SetInputConnection(cube->GetOutputPort());
    
    
    actor1->SetMapper(mapper);
    actor1->GetProperty()->SetColor(.2, .3, .4);
    
    actor2->SetMapper(mapper);
    actor2->GetProperty()->SetColor(.4, .5, .6);

    double leftViewStation[4] = {0.0, 0.0, 0.4, 1.0};
    double rightViewStation[4] = {0.4, 0.0, 1.0, 1.0};
    
    leftRender->AddActor(actor1);
    leftRender->SetBackground(.6, .5, .4);
    leftRender->SetViewport(leftViewStation);

    rightRender->AddActor(actor2);
    rightRender->SetBackground(.2, .4, .6);
    rightRender->SetViewport(rightViewStation);

    
    camera->SetPosition(4, 4, 4);
    rightRender->SetActiveCamera(camera);
    leftRender->SetActiveCamera(camera);
    
    
    renwindow->AddRenderer(leftRender);
    renwindow->AddRenderer(rightRender);
    renwindow->SetSize(600, 300);
    renwindow->Render();
    
    style->SetLeftRender(leftRender);
    style->SetRightRender(rightRender);
    
    interactor->SetInteractorStyle(style);
    
    renwindow->SetInteractor(interactor);
    
    interactor->Initialize();
    interactor->Start();
    
    
    return EXIT_SUCCESS;
}

(三)完整原始碼(工程中使用)

功能說明:

1. 一個視窗中有4個view,實現兩兩聯動

2. 繼承自 vtkInteractorStyleTrackballCamera , 重寫了 Rotate() 方法

3. 作為介面,提供了增加聯動,刪除聯動的功能

4. 注:下面兩個不聯動是通過刪除方法,刪掉了聯動

原始碼如下:

#include <vtkSmartPointer.h>
#include <vtkCubeSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkProperty.h>
#include <vtkCallbackCommand.h>
#include <vtkTransform.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkCamera.h>
#include <vector>

#include <QMap>



#define vSP vtkSmartPointer

typedef QMap<vSP<vtkRenderer>, vSP<vtkRenderer>> RenderMap;

class myInteractorStyle:public vtkInteractorStyleTrackballCamera
{
public:
    static myInteractorStyle* New()
    {
        return new myInteractorStyle;
    }
    
    void    SetRenderPair(vSP<vtkRenderer> render1, vSP<vtkRenderer> render2)
    {
        do
        {
            if (render1 == nullptr)
            {
                break;
            }
            if (render2 == nullptr)
            {
                break;
            }
            
            this->m_renderMap[render1] = render2;
            this->m_renderMap[render2] = render1;
   
        }while(false);
        
    }
    void    RemoveRenderPair(vSP<vtkRenderer> render1, vSP<vtkRenderer> render2)
    {
        do
        {
            if (!this->m_renderMap.contains(render1))
            {
                break;
            }
            if (!this->m_renderMap.contains(render2))
            {
                break;
            }
            if (render1 != this->m_renderMap.value(render2, nullptr))
            {
                break;
            }
            if (render1 == nullptr)
            {
                break;
            }
            if (render2 == nullptr)
            {
                break;
            }
            
            this->m_renderMap.remove(render1);
            this->m_renderMap.remove(render2);
            
        }while(false);
        
    }
    

    void Rotate()
    {
        vtkInteractorStyleTrackballCamera::Rotate();
        this->CameraSynchronous();
    }
        
public:
    void    CameraSynchronous()
    {
        vSP<vtkRenderer> curRender    = this->GetCurrentRenderer();
        vSP<vtkCamera>   curCamera    = curRender->GetActiveCamera();
        
        if (this->m_renderMap.contains(curRender))
        {
            vSP<vtkRenderer> linkRender = this->m_renderMap.value(curRender, nullptr);
            if (linkRender != nullptr)
            {
                linkRender->SetActiveCamera(curCamera);
            }
            
        }
    }
            
private:
    RenderMap         m_renderMap;

};

class Client
{
public:
    Client()
    {
        this->Init();
        this->setCube();
        this->setMapper();
        this->setActor();
        this->setRender();
        this->setRenderWindow();
        this->setStyle();
        this->setInteractor();
        this->start();
    }
    
    void    Init()
    {
        this->m_cube            = vtkSmartPointer<vtkCubeSource>::New();
        this->m_mapper          = vtkSmartPointer<vtkPolyDataMapper>::New();
        this->m_actor1          = vtkSmartPointer<vtkActor>::New();
        this->m_actor2          = vtkSmartPointer<vtkActor>::New();
        this->m_leftRender      = vtkSmartPointer<vtkRenderer>::New();
        this->m_rightRender     = vtkSmartPointer<vtkRenderer>::New();
        this->m_leftRender2     = vtkSmartPointer<vtkRenderer>::New();
        this->m_rightRender2    = vtkSmartPointer<vtkRenderer>::New();
        this->m_renwindow       = vtkSmartPointer<vtkRenderWindow>::New();
        this->m_interactor      = vtkSmartPointer<vtkRenderWindowInteractor>::New();
        this->m_style           = vtkSmartPointer<myInteractorStyle>::New();
    }
    
    void    setCube()
    {
        m_cube->SetXLength(1);
        m_cube->SetYLength(1);
        m_cube->SetZLength(1);
        m_cube->Update();
    }
    void    setMapper()
    {
        m_mapper->SetInputConnection(m_cube->GetOutputPort());
    }
    void    setActor()
    {
        m_actor1->SetMapper(m_mapper);
        m_actor1->GetProperty()->SetColor(.2, .3, .4);
        m_actor2->SetMapper(m_mapper);
        m_actor2->GetProperty()->SetColor(.4, .5, .6);
    }
    void    setRender()
    {
        m_leftRender->AddActor(m_actor1);
        m_leftRender->SetBackground(.6, .5, .4);
        m_leftRender->SetViewport(0.0, 0.5, 0.5, 1.0);
        
        m_leftRender2->AddActor(m_actor1);
        m_leftRender2->SetBackground(.6, .5, .4);
        m_leftRender2->SetViewport(0.0, 0.0, 0.5, 0.5);
        
        m_rightRender->AddActor(m_actor2);
        m_rightRender->SetBackground(.2, .4, .6);
        m_rightRender->SetViewport(0.5, 0.5, 1.0, 1.0);
        
        m_rightRender2->AddActor(m_actor2);
        m_rightRender2->SetBackground(.2, .4, .6);
        m_rightRender2->SetViewport(0.5, 0.0, 1.0, 0.5);
    }
    void    setRenderWindow()
    {       
        m_renwindow->AddRenderer(m_leftRender);
        m_renwindow->AddRenderer(m_rightRender);
        
        m_renwindow->AddRenderer(m_leftRender2);
        m_renwindow->AddRenderer(m_rightRender2);
        
        m_renwindow->SetSize(600, 600);
        m_renwindow->Render();
    }
    void    setStyle()
    {
        m_style->SetRenderPair(m_leftRender, m_rightRender);
        m_style->SetRenderPair(m_leftRender2, m_rightRender2);
        m_style->RemoveRenderPair(m_leftRender2, m_rightRender2);
    }
    void    setInteractor()
    {
        m_interactor->SetInteractorStyle(m_style);
    }
    void    start()
    {
        m_renwindow->SetInteractor(m_interactor);
        m_interactor->Initialize();
        m_interactor->Start();
    }
    
    
private:
    vtkSmartPointer<vtkCubeSource>              m_cube;
    vtkSmartPointer<vtkPolyDataMapper>          m_mapper;
    vtkSmartPointer<vtkActor>                   m_actor1;
    vtkSmartPointer<vtkActor>                   m_actor2;
    vtkSmartPointer<vtkRenderer>                m_leftRender;
    vtkSmartPointer<vtkRenderer>                m_rightRender;
    vtkSmartPointer<vtkRenderer>                m_leftRender2;
    vtkSmartPointer<vtkRenderer>                m_rightRender2;
    vtkSmartPointer<vtkRenderWindow>            m_renwindow;
    vtkSmartPointer<vtkRenderWindowInteractor>  m_interactor;
    vtkSmartPointer<myInteractorStyle>          m_style;
    
};


int main(int, char *[])
{
    Client client;
    client.start();

    
    return EXIT_SUCCESS;
}

(其他實現方法與思路歡迎補充)

相關推薦

VTK2—— view顯示聯動操作

前言:接到一個新的需求 window單視窗程式,雙view,顯示並聯動操作,做了兩種方式進行實現,程式碼思路和原始碼如下: (一)程式碼思路 一、判定誰動了? 方法1:通過當前事件的視窗位置與視窗大小中心軸進行比對 方法2:通過移動後的相機位置與兩個view中相機的

vs2013+qt5.51+vtk 實現的 view顯示聯動操作

1.首先我們必須將QVTKWidget加入到Qt Designer,只需找到編譯好的vtk的release版本下的QVTKWidgetPlugin.dll,QVTKWidgetPlugin.exp,QVTKWidgetPlugin.lib放入到自己QT下的designer

形態學濾波:1腐蝕與膨脹 2開運算閉運算形態學梯度頂帽黑帽

來講 極小值 -h 明顯 基本 極限 元素 腐蝕 黑帽 一、形態學概述   圖像處理中的形態學一般指的是數學形態學。   數學形態學是一門建立在格論和拓撲學基礎之上的圖像分析學科,是數學形態學圖像處理的基本理論。其基本運算包括:二值腐蝕和膨脹,二值開閉運算,骨架抽取,極限腐

Linux日常管理技巧2:freepsnetstat命令和抓包工具

情況下 路由器配置 傳輸協議 method ups lis red field 保存 一、free命令 free命令可以顯示當前系統未使用的和已使用的內存數目,還可以顯示被內核使用的內存緩沖區。用法: free [選項] 選項: -b:以Byte為單位顯示內存使用情況;-

《Linux學習不難》Linux網絡命令2:ifconfig命令顯示和配置網絡接口

Linux ifconfig 27.2 《Linux學習並不難》Linux網絡命令(2):ifconfig命令顯示和配置網絡接口使用ifconfig命令可以顯示和配置網絡接口,比如設置IP地址、MAC地址、激活或關閉網絡接口。命令語法:ifconfig [接口] [選項| IP地址]命令中各選項的含

伺服器實時通知客戶端方案伺服器傳送/推送事件方案2server event典型例子可以用作股票、新聞資訊推送

server event是html5規範的一部分,它相比websocket使用起來更簡單,對伺服器的改動也最小 前端html部分 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"&

簡單NLP分析套路2----分詞詞頻命名實體識別與關鍵詞抽取

文章大綱 中文分詞技術 評測參考 雲服務 哈工大語言云 ltp 基於深度學習方法的中文分詞 資訊檢索與關鍵詞提取 tf-idf TEXTRANK word2vector

WPF進階之介面2:IDisposableICollectionView

原始碼地址:https://www.xuebuyuan.com/892590.html 廢話不多說,進入正題,先來說說IDisposable,看例子(來自MSDN): using System;using System.ComponentModel; // 下面的例子

微信小程式入門2:web-view的使用

上一篇:簡單介面的實現 web-view是最近微信推出的元件,最開始用的時候對於我來說,就是一個內嵌網頁,相當於HTML裡的a標籤。然而這個元件卻不像想象中的那麼好用,不過困擾我十多天後,終於找到一個小方法來“解決”了,看完勿噴。 首先,你得是用企業賬戶或其它賬戶申請註冊的

資料結構與演算法2排序演算法用Python實現插入選擇堆排冒泡快排和歸併排序

前段時間鼓起勇氣和老闆說了一下以後想從事機器學習方向的工作,所以最好能有一份不錯的實習,希望如果我有好的機會他可以讓我去,沒想到老闆非常通情達理,說人還是要追尋自己感興趣的東西,忙完這陣你就去吧。所以最

安卓使用記錄筆記2UI介面按鈕響應事件

首先需要知道的是,在UI介面中新增好對應的button元件後,裡面會有對應id名稱,我們就是根據這個id名稱來查詢到對應的元件機器屬性。 private Button loadFile; private Button startFunc; 然後在init函式中:(init根據不同工程具體分析

Knockout學習2之observableArray監控陣列展示下拉框

ko對於陣列下拉框,監控跟蹤屬性值關鍵字為:observableArray,繫結值關鍵字為:options例子如下:@{ ViewBag.Title = "Index2"; } <h2>Index2</h2> <head>

MySQL 筆記整理2 --日誌系統一條SQL查詢語句如何執行

發生 重要 表示 優勢 兩層 一秒 正在 引擎 http 筆記記錄自林曉斌(丁奇)老師的《MySQL實戰45講》 2) --日誌系統,一條SQL查詢語句如何執行   MySQL可以恢復到半個月內任意一秒的狀態,它的實現和日誌系統有關。上一篇中記錄了一條查詢語句是如何執行

MySQL 筆記整理2 --事務隔離為什麽你改了我還看不見?

ble 優勢 控制 nod 讀寫 為什麽 數據操作 src 保持 筆記記錄自林曉斌(丁奇)老師的《MySQL實戰45講》 3) --事務隔離,為什麽你改了我還看不見?   簡單來說,事務就是要保證一組數據操作,要麽全部成功,要麽全部失敗。在MySQL中,事務支持是在引擎

Python 影象處理 OpenCV 2:畫素處理與 Numpy 操作以及 Matplotlib 顯示影象

![](https://cdn.geekdigging.com/opencv/opencv_header.png) 前文傳送門: [「Python 影象處理 OpenCV (1):入門」](https://www.geekdigging.com/2020/05/17/5513454552/) ## 普通

ESP8266 WIFI模組學習之路2——模組與微控制器連線進行遠端操作

上一個部落格:ESP8266 WIFI模組學習之路(1)是關於對串列埠連線的,簡單驗證ESP8266是怎麼樣連線及其功能驗證,下面將通過微控制器連線,和手機進行遠端操作。 ESP8266和微控制器的連線,我這裡的微控制器型號為:STC12C5A60S2 ESP8266

OpenStack Neutron2:建立私有網路與公網相連

在OpenStack中,建立instance之前必須建立網路。這裡通過Dashbord建立私有網路並且通過虛擬路由器與公網相連。私有網路即Tenant network。1. 建立私有網路及其子網登入Dashbord->Project->Network->Ne

redis進化五2:redis槽道與補充操作

一、redis的叢集槽道       槽道原理丟擲2個問題:             1、節點接收資料計算槽道號後,如何判斷當前槽道號是否歸我管?             2、判斷不歸本節點管時,如何獲取正確管理者的資訊?       槽道邏輯結構        

新手學python2:C語言呼叫完成資料庫操作

繼續介紹本人的python學習過程。本節介紹如何利用python呼叫c程式碼。內容還是基於音樂資訊提取的過程,架構如圖一。Python呼叫c實現的功能是利用python訪問c語言完成mysql資料庫操作。 在利用python呼叫c語言之前,我們需要首先完成c語言功能程式

MVVM Light 新手入門2 :ViewModel / Model 中定義屬性 View中呼叫 利刃 MVVMLight

今天學習MVVM架構中“屬性”的新增並呼叫,特記錄如下,學習資料均來自於網路,特別感謝翁智華的利刃 MVVMLight系列。   一個視窗的基本模型如下: View(檢視) -> ViewModel (檢視模型)-> 多個Model(模型) 注: 檢視是使用者在螢幕上看到