Wednesday, August 8, 2018

pcl - removing outliers using StatisticalOutlierRemoval filter


這是我的input



目標是去除掉圈起來這些渣渣

程式碼來源:

pcl - Removing outliers using a StatisticalOutlierRemoval filter

---


#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/statistical_outlier_removal.h>

int
main(int argc, char** argv)
{
 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);

 // Fill in the cloud data
 pcl::PCDReader reader;
 // Replace the path below with the path where you saved your file
 reader.read<pcl::PointXYZ>("input_hand.pcd", *cloud);

 std::cerr << "Cloud before filtering: " << std::endl;
 std::cerr << *cloud << std::endl;

 // Create the filtering object
 pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
 sor.setInputCloud(cloud);
 sor.setMeanK(100);
 sor.setStddevMulThresh(0.5);
 sor.filter(*cloud_filtered);

 std::cerr << "Cloud after filtering: " << std::endl;
 std::cerr << *cloud_filtered << std::endl;

 pcl::PCDWriter writer;
 writer.write<pcl::PointXYZ>("hand_inliers.pcd", *cloud_filtered, false);

 sor.setNegative(true);
 sor.filter(*cloud_filtered);
 writer.write<pcl::PointXYZ>("hand_outliers.pcd", *cloud_filtered, false);

 return (0);
}

---

結果:

有把渣渣分離出來




Tuesday, June 19, 2018

matlab - comparing of detect feature function

做實驗時比較使用不同的 detect feature function

可以參考 Math Works Document - Local Feature Detection and Extraction

---

使用detectKAZEFeatures

結果


---

使用detectSURFFeatures

結果



---

使用detectHarrisFeatures

結果



--

Tuesday, January 30, 2018

pcl - setup without cmake


如果不想每次都用CMake建立專案的話 (像我就很不喜歡)

自己設定 Properties 當然是最好的囉

可以先下載好PCL裝好 ( 參考前一篇文章做到 Step 04 )



進入PROJECT -> Properties 之後



---

點 [C/C++] -> [General] -> [Additional Include Directories] -> <Edit>

要設定的Additional Include Directories 有以下這些 (一個一個貼進去真的挺麻煩的, 認命吧)

C:\Program Files\PCL 1.8.0\3rdParty\VTK\include\vtk-7.0
C:\Program Files\PCL 1.8.0\include\pcl-1.8
C:\Program Files\PCL 1.8.0\3rdParty\Eigen\eigen3
C:\Program Files\PCL 1.8.0\3rdParty\Boost\include\boost-1_6
C:\Program Files\OpenNI2\Include
C:\Program Files (x86)\Intel\RSSDK\include
C:\Program Files\PCL 1.8.0\3rdParty\FLANN\include
C:\Program Files\PCL 1.8.0\3rdParty\Qhull\include
C:\Program Files\PCL 1.8.0\3rdParty\VTK\include
C:\Program Files\PCL 1.8.0\3rdParty\Boost\include\boost-1_61\boost
C:\Program Files\PCL 1.8.0\3rdParty\Boost\include\boost-1_61



---

點 [Linker] -> [General] -> [Additional Include Directories] -> <Edit>

要設定的Additional Include Directories 有以下這些

C:/Program Files/PCL 1.8.0/lib
C:/Program Files/PCL 1.8.0/lib/$(Configuration)


---

最後 [Linker] -> [Input] -> [Additional Dependencies] -> <Edit>

要設定的Additional Include Directories 有以下這些

C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_system-vc120-mt-1_61.lib
C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_filesystem-vc120-mt-1_61.lib
C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_thread-vc120-mt-1_61.lib
C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_date_time-vc120-mt-1_61.lib
C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_iostreams-vc120-mt-1_61.lib
C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_serialization-vc120-mt-1_61.lib
C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_chrono-vc120-mt-1_61.lib
C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_atomic-vc120-mt-1_61.lib
C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_regex-vc120-mt-1_61.lib
C:\Program Files\PCL 1.8.0\lib\pcl_common_release.lib
C:\Program Files\PCL 1.8.0\lib\pcl_octree_release.lib
C:\Program Files\OpenNI2\Lib\OpenNI2.lib
C:\Program Files (x86)\Intel\RSSDK\lib\x64\libpxc.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkalglib-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkChartsCore-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonColor-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonDataModel-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonMath-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonCore-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtksys-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonMisc-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonSystem-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonTransforms-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkInfovisCore-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersExtraction-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonExecutionModel-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersCore-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersGeneral-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonComputationalGeometry-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersStatistics-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingFourier-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingCore-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingContext2D-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingCore-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersGeometry-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersSources-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingFreeType-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkfreetype-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkzlib-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkDICOMParser-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkDomainsChemistry-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOXML-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOGeometry-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOCore-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOXMLParser-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkexpat-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkexoIIc-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkNetCDF-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkNetCDF_cxx-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkhdf5_hl-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkhdf5-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersAMR-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkParallelCore-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOLegacy-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersFlowPaths-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersGeneric-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersHybrid-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingSources-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersHyperTree-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersImaging-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingGeneral-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersModeling-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersParallel-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersParallelImaging-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersProgrammable-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersSelection-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersSMP-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersTexture-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersVerdict-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkverdict-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkGeovisCore-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkInfovisLayout-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingHybrid-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOImage-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkmetaio-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkjpeg-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkpng-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtktiff-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkInteractionStyle-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkInteractionWidgets-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingAnnotation-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingColor-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingVolume-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkViewsCore-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkproj4-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkgl2ps-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingMath-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingMorphological-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingStatistics-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingStencil-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkInteractionImage-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOAMR-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOEnSight-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOExodus-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOExport-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingGL2PS-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingContextOpenGL-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingOpenGL-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingLabel-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOImport-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOInfovis-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtklibxml2-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOLSDyna-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOMINC-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOMovie-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkoggtheora-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIONetCDF-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOParallel-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkjsoncpp-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOParallelXML-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOPLY-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOSQL-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtksqlite-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOVideo-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingImage-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingLIC-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingLOD-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingVolumeOpenGL-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkViewsContext2D-7.0.lib
C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkViewsInfovis-7.0.lib
C:\Program Files\PCL 1.8.0\lib\pcl_io_release.lib
C:\Program Files\PCL 1.8.0\3rdParty\FLANN\lib\flann_cpp_s.lib
C:\Program Files\PCL 1.8.0\lib\pcl_kdtree_release.lib
C:\Program Files\PCL 1.8.0\lib\pcl_search_release.lib
C:\Program Files\PCL 1.8.0\lib\pcl_sample_consensus_release.lib
C:\Program Files\PCL 1.8.0\lib\pcl_filters_release.lib
C:\Program Files\PCL 1.8.0\lib\pcl_features_release.lib
C:\Program Files\PCL 1.8.0\lib\pcl_ml_release.lib
C:\Program Files\PCL 1.8.0\lib\pcl_segmentation_release.lib
C:\Program Files\PCL 1.8.0\lib\pcl_visualization_release.lib
C:\Program Files\PCL 1.8.0\3rdParty\Qhull\lib\qhullstatic.lib
C:\Program Files\PCL 1.8.0\lib\pcl_surface_release.lib
C:\Program Files\PCL 1.8.0\lib\pcl_registration_release.lib
C:\Program Files\PCL 1.8.0\lib\pcl_keypoints_release.lib
C:\Program Files\PCL 1.8.0\lib\pcl_tracking_release.lib
C:\Program Files\PCL 1.8.0\lib\pcl_recognition_release.lib
C:\Program Files\PCL 1.8.0\lib\pcl_stereo_release.lib
C:\Program Files\PCL 1.8.0\lib\pcl_outofcore_release.lib
C:\Program Files\PCL 1.8.0\lib\pcl_people_release.lib
vfw32.lib
glu32.lib
opengl32.lib
comctl32.lib
wsock32.lib
ws2_32.lib
Psapi.lib
kernel32.lib
user32.lib
gdi32.lib
winspool.lib
shell32.lib
ole32.lib
oleaut32.lib
uuid.lib
comdlg32.lib
advapi32.lib


---

全部都設定完就可以用了




Sunday, January 28, 2018

pcl - setup with cmake and visual studio 2013

---

step 01


先去網站 http://unanancyowen.com/en/pcl18/



找到 PCL 1.8.0 All-in-one Installer MSVC2013 x64

點選之後應該會進入下載的頁面 (我的是自己開始下載了)



---

step 02


在資料夾中找到檔案



雙點擊打開之後照著點 [Next] > [I Agree]



這一步記得要點選加入系統PATH的選項


繼續點選下一步



就會冒出安裝中的畫面了


---

step 03


接著他會提醒你裝OpenNI

按下 [Install]


如果他跳出一些警告訊息按下 [繼續設置]



就只要等他安裝完按下最後的[Finish]就好了



---

step 04


這步可做可不做, 只是要確認要用到的東西都裝好了

可以到移除應用程式的地方確認OpenNI 的SDK 和 PCL 1.8 是不是有在裡面



以及確認以下兩個檔案是否存在

第一個是在 C槽 > Program Files > OpenNI2 > Lib 裡的 [OpenNI2.lib]


第二個是在 C槽 > Program Files > OpenNI2 > Redist 的 [OpenNI2.dll]


---

step 05


http://pointclouds.org/網頁

點選 [Docoumentation] > [Tutorials] > [Visualization] > [The Cloud Viewer]





在要建立Project的資料夾中右鍵新增一個檔案 (我是新增txt檔)


將檔名改為網頁Compiling and running the program 部分

所提供的程式碼倒數第二行的 cloud_viewer.cpp (記得是連副檔名一起改)



再新增一個 txt 檔

檔案命名為 CMakeLists.txt





將改好檔名的CMakeLists.txt打開後

把網頁Compiling and running the program 部分框起來的程式碼複製貼上到檔案內後儲存



---

step 06


打開CMake 設定剛剛放置檔案的資料夾以及你想要將產生出來的檔案放置的資料夾後

按下 [Configure]


設定 [Visual Studio 12 2013 Win 64] 後按下 [Finish]

等他跑完後按下 [Generate]



---

step 07 


產生出來的檔案中的 .sln檔打開


並點開裡面的cloud_viewer.cpp



將網頁中A more complete sample裡的程式碼貼進去



---

step 08


可以去 https://github.com/PointCloudLibrary/data下載 pcd檔案


---

step 09


將檔案解壓縮之後裡面找到 [tutorials] > ism_test_cat.pcd

將檔案複製貼上到剛剛打開專案的位置 (也就是CMake將檔案裝好的位置)


---

step 10


接下來做最後的幾步設置

先將程式碼的pcd檔名稱改成放進資料夾的檔案名稱

(或是把在資料夾內的pcd檔名稱改成跟程式碼一樣也可以)

再將cloud_viewer專案設成起始專案



最後將剛剛裝好的所有會用到的dll檔都丟進該資料夾

(有些人喜歡設定path, 不過我很不喜歡設定path所以都是直接把dll檔丟進去)

然後就可以 run 了



---

運行結果:

剛run下去應該會跑出這個畫面





是正常的

把滑鼠放在視窗中, 滑鼠滾輪往後滾個幾下再稍微用左右鍵拉一下

應該就可以看到你放進去的貓貓了










Friday, January 5, 2018

aruco - put image on marker 在二維碼上放圖片



實作在姿態辨識之後

利用opencv的透視轉換函式把圖片放到二維碼上

---

程式碼:


void putPicture(Mat intrinsic, Mat distortion, Vec3d rvec, Vec3d tvec, Mat _frame)
{
 Mat frame = _frame.clone();

 Mat img_input = imread(".//data//squirrel.jpg");
 Mat img_perspective = Mat::zeros(frame.size(), frame.type());

 float unit = 0.05;

 Point3f pointO = Point3f(-unit, -unit, unit);
 Point3f pointX = Point3f(-unit, unit, unit);
 Point3f pointXY = Point3f(unit, unit, unit);
 Point3f pointY = Point3f(unit, -unit, unit);

 vector<Point3f> Point3D;
 vector<Point2f> Point2D;
 Point3D.push_back(pointO);
 Point3D.push_back(pointX);
 Point3D.push_back(pointXY);
 Point3D.push_back(pointY);

 projectPoints(Point3D, rvec, tvec, intrinsic, distortion, Point2D);

 //求圖片的透視矩陣
 Point2f srcTri[4];
 srcTri[0] = Point2f(0, 0);
 srcTri[1] = Point2f(img_input.cols - 1, 0);
 srcTri[2] = Point2f(img_input.cols - 1, img_input.rows - 1);
 srcTri[3] = Point2f(0, img_input.rows - 1);

 Point2f dstTri[4];
 dstTri[0] = Point2D[0];
 dstTri[1] = Point2D[1];
 dstTri[2] = Point2D[2];
 dstTri[3] = Point2D[3];

 //做圖片的透視轉換
 Mat perspective_matrix = getPerspectiveTransform(srcTri, dstTri);
 warpPerspective(img_input, img_perspective, perspective_matrix, img_perspective.size());

 //把透視轉換後的圖片貼到視訊影像上
 for (int r = 0; r < frame.rows; r++)
 {
  for (int c = 0; c < frame.cols; c++)
  {
   if ((img_perspective.at<Vec3b>(r,c)[0]!=0)&& (img_perspective.at<Vec3b>(r, c)[1] != 0)&& (img_perspective.at<Vec3b>(r, c)[2] != 0))
   {
    frame.at<Vec3b>(r, c)[0] = img_perspective.at<Vec3b>(r, c)[0];
    frame.at<Vec3b>(r, c)[1] = img_perspective.at<Vec3b>(r, c)[1];
    frame.at<Vec3b>(r, c)[2] = img_perspective.at<Vec3b>(r, c)[2];
   }
  }
 }

 imshow("putPicture", frame);
}


---

運行結果:


Thursday, January 4, 2018

aruco - put cube on marker 在二維碼上放立方體


實作在姿態辨識之後

在marker上用線畫出正立方體

---

程式碼:


void drawCube(Mat intrinsic, Mat distortion, Vec3d rvec, Vec3d tvec, Mat _frame)
{
 double unit = 0.05;
 Mat frame = _frame.clone();

 Point3d pointO = Point3d(0, 0, 0);
 Point3d pointX = Point3d(unit, 0, 0);
 Point3d pointXY = Point3d(unit, unit, 0);
 Point3d pointY = Point3d(0, unit, 0);

 Point3d pointZ = Point3d(0, 0, unit);
 Point3d pointXZ = Point3d(unit, 0, unit);
 Point3d pointXYZ = Point3d(unit, unit, unit);
 Point3d pointYZ = Point3d(0, unit, unit);
 

 vector<Point3f> Point3D;
 vector<Point2f> Point2D;

 Point3D.push_back(pointO);
 Point3D.push_back(pointX);
 Point3D.push_back(pointXY);
 Point3D.push_back(pointY);

 Point3D.push_back(pointZ);
 Point3D.push_back(pointXZ);
 Point3D.push_back(pointXYZ);
 Point3D.push_back(pointYZ);


 projectPoints(Point3D, rvec, tvec, intrinsic, distortion, Point2D);

 circle(frame, cv::Point(Point2D[0].x, Point2D[0].y), 3, Scalar(255, 0, 255));
 circle(frame, cv::Point(Point2D[1].x, Point2D[1].y), 3, Scalar(255, 0, 255));
 circle(frame, cv::Point(Point2D[2].x, Point2D[2].y), 3, Scalar(255, 0, 255));
 circle(frame, cv::Point(Point2D[3].x, Point2D[3].y), 3, Scalar(255, 0, 255));

 //底板兒
 line(frame, cv::Point(Point2D[0].x, Point2D[0].y), cv::Point(Point2D[1].x, Point2D[1].y), Scalar(0, 255, 255), 2, 8, 0);
 line(frame, cv::Point(Point2D[1].x, Point2D[1].y), cv::Point(Point2D[2].x, Point2D[2].y), Scalar(0, 255, 255), 2, 8, 0);
 line(frame, cv::Point(Point2D[2].x, Point2D[2].y), cv::Point(Point2D[3].x, Point2D[3].y), Scalar(0, 255, 255), 2, 8, 0);
 line(frame, cv::Point(Point2D[3].x, Point2D[3].y), cv::Point(Point2D[0].x, Point2D[0].y), Scalar(0, 255, 255), 2, 8, 0);

 
 //直立四柱
 line(frame, cv::Point(Point2D[0].x, Point2D[0].y), cv::Point(Point2D[4].x, Point2D[4].y), Scalar(0, 0, 255), 2, 8, 0);
 line(frame, cv::Point(Point2D[1].x, Point2D[1].y), cv::Point(Point2D[5].x, Point2D[5].y), Scalar(0, 0, 255), 2, 8, 0);
 line(frame, cv::Point(Point2D[2].x, Point2D[2].y), cv::Point(Point2D[6].x, Point2D[6].y), Scalar(0, 0, 255), 2, 8, 0);
 line(frame, cv::Point(Point2D[3].x, Point2D[3].y), cv::Point(Point2D[7].x, Point2D[7].y), Scalar(0, 0, 255), 2, 8, 0);

 //蓋子
 line(frame, cv::Point(Point2D[7].x, Point2D[7].y), cv::Point(Point2D[4].x, Point2D[4].y), Scalar(0, 255, 0), 2, 8, 0);
 line(frame, cv::Point(Point2D[4].x, Point2D[4].y), cv::Point(Point2D[5].x, Point2D[5].y), Scalar(0, 255, 0), 2, 8, 0);
 line(frame, cv::Point(Point2D[5].x, Point2D[5].y), cv::Point(Point2D[6].x, Point2D[6].y), Scalar(0, 255, 0), 2, 8, 0);
 line(frame, cv::Point(Point2D[6].x, Point2D[6].y), cv::Point(Point2D[7].x, Point2D[7].y), Scalar(0, 255, 0), 2, 8, 0);

 imshow("Cube", frame);
}


---

運行結果:


Wednesday, January 3, 2018

aruco - pose estimation 姿態辨識


這裡實作使用 Aruco Marker 的姿態辨識

---

 前置作業:

1. 相機校正 opencv - camera calibration 相機校正

2. 印出二維碼 aruco - print out opencv aruco markers 印出二維碼

---

程式碼:

#include <iostream>
#include "opencv2\opencv.hpp"
#include "opencv2\aruco.hpp"
#include <direct.h>
#include <string>

using namespace std;
using namespace cv;

Mat load_distortion(string fileName)
{
 Mat distortion(5, 1, CV_64F);

 ifstream inStream(fileName);
 if (inStream)
 {
  cout << "Load " << fileName << "..." << endl;
  int rows = 5;
  int cols = 1;

  for (int r = 0; r < rows; r++)
  {
   for (int c = 0; c < cols; c++)
   {
    double read = 0.0f;
    inStream >> read;
    distortion.at<double>(r, c) = read;
   }
  }

 }

 return distortion;
}

Mat load_intrinsic(string fileName)
{
 Mat intrinsic(3, 3, CV_64F);

 ifstream inStream(fileName);
 if (inStream)
 {
  cout << "Load " << fileName << "..." << endl;
  int rows = 3;
  int cols = 3;

  for (int r = 0; r < rows; r++)
  {
   for (int c = 0; c < cols; c++)
   {
    double read = 0.0f;
    inStream >> read;
    intrinsic.at<double>(r, c) = read;
   }
  }

 }

 return intrinsic;
}

int startWebcam(Mat intrinsic, Mat distortion)
{
 VideoCapture webcam(2);

 if (!webcam.isOpened())
 {
  cout << "CANNOT open webcam" << endl;
  return 0;
 }

 vector<Vec3d> rvec, tvec; //旋轉矩陣及位移矩陣
 vector<int> marker_ids;    //二維碼的編號
 vector<vector<Point2f>> marker_corners; //二維碼的角點
 vector<vector<Point2f>> rejected_case;  //被拒絕的人

 //把二維碼庫讀進來
 Ptr<aruco::Dictionary> markerDic = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME::DICT_4X4_50);
 
 Mat frame; //視訊鏡頭照到的每張影像
 

 while (true)
 {
  if (!webcam.read(frame)) //讀影像進來
  {
   cout << "CANNOT read webcam" << endl;
   break;
  }

  aruco::detectMarkers(frame, markerDic, marker_corners, marker_ids);
  aruco::estimatePoseSingleMarkers(marker_corners, 0.1016f, intrinsic, distortion, rvec, tvec);
  aruco::drawDetectedMarkers(frame, marker_corners, marker_ids);
  
  for (int index_marker = 0; index_marker < marker_ids.size(); index_marker++)
  {
   aruco::drawAxis(frame, intrinsic, distortion, rvec[index_marker], tvec[index_marker], 0.1);
   cout << index_marker << endl;
  }

  imshow("frame", frame); //顯示原始影像
  waitKey(22);
 }
}

int main()
{
 Mat intrinsic(3, 3, CV_64F);
 Mat distortion(5, 1, CV_64F);
 
 //載入intrinsic和distortion
 intrinsic = load_intrinsic(".//calibration//intrinsic.txt");  
 distortion = load_distortion(".//calibration//distortion.txt");
 
 cout << "intrinsic: " << intrinsic << endl;
 cout << "distortion: " << distortion << endl;
 
 startWebcam(intrinsic, distortion);

 system("pause");
 return 0;
}

---

運行結果:



---

Tuesday, January 2, 2018

aruco - print out opencv aruco markers 印出二維碼

---

使用Aruco Marker的第一步就是先把這些marker印出來

有些人會說他已經設置好了OpenCV的library為什麼沒有aruco的函式庫可以用

這是因為還沒有裝好他的擴充函式庫

這個要另外下載

可以參考我之前寫的這篇 opencv - set up extra module

或是這個影片(聽不懂英文沒關係, 跟著做就對了)





---


#include <iostream>

#include "opencv2\opencv.hpp"

#include "opencv2\aruco.hpp"

#include <direct.h>

#include <string>


using namespace std;

using namespace cv;


int main()

{


    Mat outputImg;


     Ptr <aruco::Dictionary> markerDic = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME::DICT_4X4_50);


     for (int index = 0; index < 50; index++)

     {

         aruco::drawMarker(markerDic, index, 500, outputImg, 1);  //把放在markerDic裡的marker放到輸出圖(outputImg)裡

         string folderName = ".//markers//";                      //設定放置的資料夾名稱

         _mkdir(folderName.c_str());                              //新建資料夾                           

         imwrite(folderName + to_string(index) + ".png", outputImg);     //儲存圖片

     }



    system("pause");

    return 0;

}


---


這是範例程式碼

使用 aruco::getPredefinedDictionary 函式先取得二維標誌的資料

再用 aruco::drawMarker 把二維標誌的圖像畫到 Mat圖像上

run下去之後應該可以在叫做 markers的資料夾找到所有的二維標誌png圖像




其中

aruco::PREDEFINED_DICTIONARY_NAME::DICT_4X4_50

代表這是4x4大小的marker有50張

而幾乘幾的marker是以扣掉外圈的黑色裡面的格子數而定


--

最後選幾張自己想要用來做實驗的印出來就可以囉