Recently in the construction of point cloud system, the main combination of Point Cloud Library PCL, Visual library VTK and image processing open Source Library OpenCV to combine image and point cloud data collaboration of rock mass analysis system. Here I would like to share with you the overall construction process, the shortage of places I hope you can help to point out in order to improve. Because it is still in the construction process, so the update time of the article is not necessarily, but the key progress will certainly be written to discuss, thank you.
The analysis process of the whole system construction includes module division, coupling between modules, database construction, creation of related classes, inheritance and other theoretical details are not discussed here. This article begins with the system's Interface framework:
menu bar about the system menu due to the previous discussion, mainly divided into related data loading, data editing, three-dimensional visualization, point cloud processing, image processing and other modules. After building a dialog-based MFC application in the Resource view, right-click on "Add Resources", in the popup dialog we choose to create a new Meun, OK, then we will create a idr_menu1 menu resource, keep the default setting, the ID number is unchanged, We edit our menu items as shown in:
Other details, such as the icon before the menu item, are not set and will be supplemented later. After we have set up the resources, we need to load this resource. Open XXXDlg.h, create a member variable
CMenu M_menu;
Then find Xxxdlg::oninitdialog () {} in the XXXDlg.cpp file and write the code under//tode:
M_menu.loadmenu (IDR_MENU1); Setment (&m_menu);
So our menu resources are loaded;
Second, the toolbar has a menu bar next is the toolbar, here is just a simple set up the next toolbar, about the toolbar detailed operation can refer to this article. The creation of the toolbar can be created in the Resource window, which is not used in this way. Also create toolbar member variables and CImageList in XXXDlg.h:
CToolBar M_toolbar; CImageList m_toolbarimg;
Then write the code in OnInitDialog () {} under XXXDlg.cpp:
Since we need to set a custom picture for the buttons on our toolbar, we want to use CImageList here:
/* Specify button icon picture */m_toolbarimg.create (16,16,ilc_color16,3,3); M_toolbarimg.add (AfxGetApp ()->loadicon (IDI_ICON1)); m _toolbarimg.add (AfxGetApp ()->loadicon (Idi_icon2)); M_toolbarimg.add (AfxGetApp ()->loadicon (IDI_ICON3)); m_ Toolbar. GetToolBarCtrl (). SetImageList (&M_TOOLBARIMG);
Since the image size used here is 16*16, it needs to be set in the Crete method, and the last two parameters of the Create method can be set arbitrarily. The next three lines of code are loaded with our custom icon, before we need to copy the icon file we need to the Res folder of the project file, and then in the icon folder under the Resource view to import the icon we want, here I temporarily loaded 3 icons: The change ID is idi_ Icon1,idi_icon2,idi_icon3. Then use the CImageList Add method to load three icons. The last line of code is to get the CToolBarCtrl variable and set the icon, here to mention, SetImageList is the default way to display pictures, and sethotimagelist is the mouse after the highlight, the two are not the same. You can then add the button tool buttons specifically for the toolbar.
M_toolbar. SetButtons (null,3); M_toolbar. SetButtonInfo (0,idi_icon1,tbstyle_button,0); M_toolbar. SetButtonText (0, "function 1"); M_toolbar. SetButtonInfo (1,idi_icon2,tbstyle_check,1); M_toolbar. SetButtonText (1, "function 2"); M_toolbar. SetButtonInfo (2,idi_icon3,tbstyle_button,2); M_toolbar. SetButtonText (2, "function 3"); M_toolbar. SetSizes (CSize (24,24), CSize (16,16)); RepositionBars (afx_idw_controlbar_first,afx_idw_controlbar_last,0); M_imagelist.detach ();
We temporarily add 3 buttons, so the first behavior 3, the second line of SetButtonInfo means to start adding tools, there are 4 parameters, the first parameter represents the tool button ID number, 0 means the first, the second parameter is the ID number of the icon, the third parameter is the tool's style, This is the button so set to Tbstyle_button, of course, can also be set to Tbstyle_check to represent the radio check control; the last one is the corresponding image ID number in CImageList, the first one starting from 0. Then set the mouse tip text for the button. After setting three buttons in such a way, we need to set the button size. Using the SetSizes method, the first parameter is the size of the button, the second parameter is the size of the icon picture in the button, note that the size of the icon image before we load the image needs to be consistent, the same as 16*16. Finally, don't forget the last two lines of RepositionBars and CImageList's Detach (), the former used to display the toolbar, which releases the picture resources.
Third, the content tree chart when we open the file, usually the left side of the software will show a tree of content, which is to use Ctreecontrol. We open the project's main dialog, add a tree Control to the left, set the size and layout, modify the ID number, and use the right mouse button for its associated member variables, such as:
The variable can be found in XXXDlg.h after it is complete, and then we can initialize the control. We know that there are usually icons to beautify the content tree, so here we also need to use CImageList to save our node's icon file:
Hicon[0] = Theapp.loadicon (Idi_icon1); hicon[1] = Theapp.loadicon (Idi_icon2); hicon[2] = Theapp.loadicon (IDI_ICON3); m_ Imagelist.create (16,16,ilc_color16,3,3); for (int i = 0; i < 3;i++) {M_imagelist.add (hicon[i]);} M_tree.setimagelist (&m_imagelist,tvsil_normal);
Then we build the tree node:
/* Establish the first node tree */hroot = M_tree.insertitem (_t ("root node 1"), 0,0), Hcataitem = M_tree.insertitem (_t ("Node 1"), 1,1,hroot,tvi_last); M_tree.setitemdata (hcataitem,1); Hartitem = M_tree.insertitem (_t ("Sub-node 1"), 2,2,hcataitem,tvi_last); HArtItem = m_ Tree.insertitem (_t ("Child Node 2"), 2,2,hcataitem,tvi_last); * Establish a second node tree */hroot = M_tree.insertitem (_t ("root Node 2"), 0,0); Hcataitem = M_tree.insertitem (_t ("Node 1"), 1,1,hroot,tvi_last); M_tree.setitemdata (hcataitem,1); HArtItem = m_ Tree.insertitem (_t ("Child Node 1"), 2,2,hcataitem,tvi_last), Hartitem = M_tree.insertitem (_t ("Child Node 2"), 2,2,hcataitem,tvi_ last);
Establish the root node, the node and the child node, and set the node corresponding to the parent node and the node corresponding to the child node. This initializes the node tree diagram. Of course, in the specific system, we should be for the specific data opened and then display the content tree, then the node corresponding to the text should be the root directory, path name and file name, the node's series is also dynamic changes, such as according to the specific file path to set.
Iv. attribute forms because the system involves the image data and the point cloud data, we need to be able to display the information about the data in the system interface while loading the data, so the property sheet is set on the right side of the interface. How do we build our own property sheets? First, find the dialog folder in the Resource view, right-click Add Resource, select Expand dialog in the Popup Resource dialog box, select the Idd_property_large inside, select New. Second, hold down CTRL and drag the mouse to create 2 copies, this time there are 3 resources, respectively, is idd_property_large,idd_property_large1,idd_property_large2. (This is just a temporary creation of 3 property sheets, which can be changed as needed) third, add CPropertyPage member variables and CPropertySheet member variables in the XXXDlg.h file:
CPropertyPage M_page1; CPropertyPage M_page2; CPropertyPage M_page3; CPropertySheet M_pagesheet;
The OnCreate () and OnSize () events of the main dialog box are then added. (I wanted to set it up in the OnInitDialog, but either it went wrong or it didn't show up.) ) Add code to OnCreate:
M_page1. Construct (Idd_proppage_large); M_page2. Construct (idd_proppage_large1); M_page3. Construct (idd_proppage_large2); M_pagesheet. Construct ("Property Pages", this); M_pagesheet. AddPage (&m_page1); M_pagesheet. AddPage (&m_page2); M_pagesheet. AddPage (&m_page3); M_pagesheet. Create (this,ws_child| ws_visible);
To facilitate the layout, we first add a static control where the property sheet is placed in the main dialog box, set the layout and the Visial property to False so that we can get its rect to lay out our form. Five, add the variable in OnSize ():
CRect RC; GetDlgItem (Idc_static_property)->getwindowrect (&RC); M_pagesheet. SetWindowPos (&wndtop,rc.left-10,rc.top-25,rc.right,rc.bottom,null);
Here is a problem, I directly get RC left and top, why not completely superimposed on the static control, there will always be offset, so here I set the offset to fit up, but this good trouble ... Solution.
Above we set up the form and layout, specifically to add what content on the form, and then design.
The main workspace View main area is a major part of the system, where the main views are divided into two, the tab control is used for switching, mainly point cloud 3D display area and image display area. First, we add a tab control to the reserved main view area, right-click its associated member variable M_tab, and second, because we need to put 2 display methods in the Tab control, we first add two dialog resources in the dialog of the resource view, modify its Bord property to none, The Style property is child, and then the dialog box that is displayed for 3D modifies the ID of Idd_dialog_view, and the picture displays a dialog box that is idd_dialog_picture. You add a static control to the View dialog box to lay out the VTK window, add a picture control to the PIC dialog box to display the image image, and generate classes Cpageview and cpagepic for each. Third, add member variables in XXXDlg.h
Cpagepic m_pagepicture; Cpageview M_pageviewer;
Add the code in the OnInitDialog in the XXXDlg.cpp file;
CRect R;m_tab. InsertItem (1,_t ("visualization")); M_tab. InsertItem (2,_t ("image")); M_pageviewer. Create (Idd_dialog_view,&m_tab);//Load dialog box and manage M_pagepicture to tab control. Create (Idd_dialog_picture,&m_tab); M_tab. GetClientRect (&r); M_pageviewer. SetWindowPos (Null,r.left+1,r.top+1,r.right-1,r.bottom-25,swp_showwindow);//Set display position m_pagepicture. SetWindowPos (Null,r.left+1,r.top+1,r.right-1,r.bottom-25,swp_hidewindow);
Five, respond to the tab control's ONTCNSELCHANGETAB1 () message, double-click on the line. and add code to it:
CRect Rect;m_tab. GetClientRect (&rect); switch (m_tab. GetCurSel ()) {case 0:m_pageviewer. SetWindowPos (Null,rect.left+1,rect.top+1,rect.right-1,rect.bottom-25,swp_showwindow); m_pagepicture. SetWindowPos (Null,rect.left+1,rect.top+1,rect.right-1,rect.bottom-25,swp_hidewindow); Break;case 1:m_pageviewer. SetWindowPos (Null,rect.left+1,rect.top+1,rect.right-1,rect.bottom-25,swp_hidewindow); m_pagepicture. SetWindowPos (Null,rect.left+1,rect.top+1,rect.right-1,rect.bottom-25,swp_showwindow); break;} *presult = 0;
What should we do if we want to set the display of VTK? We can call VTK's Vtkrenderwindow object's Setparetid method to set it, get the Pageviewer object under the tab control, and get a handle to the static control inside it.
Renwin->setparentid (M_pageviewer. GetDlgItem (IDC_STATIC_VTK)->m_hwnd); CRect Rect;m_pageviewer. GetDlgItem (IDC_STATIC_VTK)->getwindowrect (&rect); Renwin->setsize (rect. Width (), Rect. Height ()); Iren->setrenderwindow (Renwin); Iren->initialize (); Renwin->render (); Iren->start ();
Please include all relevant header files as required.
All the layout is set up so that we can now look at the effect, I have added a part of the PCL file Open code, in the form of txt text is VTK read and display.
Construction of the PCL, VTK and OpenCV rock body recognition system based on MFC dialog box (1)