如何获得物体的主要方向?
生活随笔
收集整理的這篇文章主要介紹了
如何获得物体的主要方向?
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
問題來源為網友提供的資料,原文地址為:《Object Orientation, Principal Component Analysis & OpenCV》
問題描述: 對于這樣的圖像(2副,采用了背投光),如何獲得上面工件的主要方向 ? 主要思路: 1、分別獲得每個工件的輪廓; 2、處理每個輪廓,采用pca(主成分分析)方法,獲得所有輪廓點的集合的中點,主要方向等信息; 3、繪圖并返回結果。 ? 注:pca相關函數請查看 https://docs.opencv.org/master/d3/d8d/classcv_1_1PCA.html 代碼略解: 1、讀入圖片,尋找輪廓; //讀入圖像,轉換為灰度????Mat?img?=?imread("e:/sandbox/pca1.jpg");
????Mat?bw;
????cvtColor(img,?bw,?COLOR_BGR2GRAY);
????//閾值處理
????threshold(bw,?bw,?150,?255,?CV_THRESH_BINARY);
????//尋找輪廓
????vector<vector<Point>?>?contours;
????vector<Vec4i>?hierarchy;
????findContours(bw,?contours,?hierarchy,?CV_RETR_LIST,?CV_CHAIN_APPROX_NONE); 2、首先以大小篩選輪廓; //輪廓分析,找到工件
????for?(size_t?i?=?0;?i?<?contours.size();?++i)
????{
????????//計算輪廓大小
????????double?area?=?contourArea(contours[i]);
????????//去除過小或者過大的輪廓區域(科學計數法表示)
????????if?(area?<?1e2?||?1e5?<?area)?continue;
????????//繪制輪廓
????????drawContours(img,?contours,?i,?CV_RGB(255,?0,?0),?2,?8,?hierarchy,?0);
????????//尋找每一個輪廓的方向
????????getOrientation(contours[i],?img);
????} 3、單獨處理每個輪廓,分析其主要方向,繪制結果 //獲得構建的主要方向
double?getOrientation(vector<Point>?&pts,?Mat?&img)
{
????//構建pca數據。這里做的是將輪廓點的x和y作為兩個維壓到data_pts中去。
????Mat?data_pts?=?Mat(pts.size(),?2,?CV_64FC1);//使用mat來保存數據,也是為了后面pca處理需要
????for?(int?i?=?0;?i?<?data_pts.rows;?++i)
????{
????????data_pts.at<double>(i,?0)?=?pts[i].x;
????????data_pts.at<double>(i,?1)?=?pts[i].y;
????}
????//執行PCA分析
????PCA?pca_analysis(data_pts,?Mat(),?CV_PCA_DATA_AS_ROW);
????//獲得最主要分量,在本例中,對應的就是輪廓中點,也是圖像中點
????Point?pos?=?Point(pca_analysis.mean.at<double>(0,?0),pca_analysis.mean.at<double>(0,?1));
????//存儲特征向量和特征值
????vector<Point2d>?eigen_vecs(2);
????vector<double>?eigen_val(2);
????for?(int?i?=?0;?i?<?2;?++i)
????{
????????eigen_vecs[i]?=?Point2d(pca_analysis.eigenvectors.at<double>(i,?0),pca_analysis.eigenvectors.at<double>(i,?1));
????????eigen_val[i]?=?pca_analysis.eigenvalues.at<double>(i,0);//注意,這個地方原代碼寫錯了
????}
????//在輪廓/圖像中點繪制小圓
????circle(img,?pos,?3,?CV_RGB(255,?0,?255),?2);
????//計算出直線,在主要方向上繪制直線
????line(img,?pos,?pos?+?0.02?*?Point(eigen_vecs[0].x?*?eigen_val[0],?eigen_vecs[0].y?*?eigen_val[0])?,?CV_RGB(255,?255,?0));
????line(img,?pos,?pos?+?0.02?*?Point(eigen_vecs[1].x?*?eigen_val[1],?eigen_vecs[1].y?*?eigen_val[1])?,?CV_RGB(0,?255,?255));
????//返回角度結果
????return?atan2(eigen_vecs[0].y,?eigen_vecs[0].x);
} 結果展示: 感謝關注,希望有所幫助。 此外,特別感謝:https://github.com/NickeManarin/ScreenToGif/wiki/Help 提供的這個gif錄屏軟件,非常好用。
?
轉載于:https://www.cnblogs.com/jsxyhelu/p/7690699.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的如何获得物体的主要方向?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AWS DevOps – 配合Jenki
- 下一篇: 程序包管理器控制台 Add-Migra