如何获得物体的主要方向?

简介: 问题来源为网友提供的资料,原文地址为:《Object Orientation, Principal Component Analysis & OpenCV》问题描述:对于这样的图像(2副,采用了背投光),如何获得上面工件的主要方向  主要思路:1、分别获得每个工件的轮廓;2、处理每个轮廓,采用pca(主成分分析)方法,获得所有轮廓点的集合的中点,主要方向等信息;3、绘图并返回结果。

问题来源为网友提供的资料,原文地址为:《Object Orientation, Principal Component Analysis & OpenCV》

问题描述:
对于这样的图像(2副,采用了背投光),如何获得上面工件的主要方向
pca_test1  
pca_test2
 
主要思路:
1、分别获得每个工件的轮廓;
2、处理每个轮廓, 采用pca(主成分分析)方法,获得所有轮廓点的集合的中点,主要方向等信息;
3、绘图并返回结果。
 
注:pca相关函数请查看
 
代码略解:
1、读入图片,寻找轮廓;
//读入图像,转换为灰度
    Mat img  = imread( "e:/sandbox/pca1.jpg");
    Mat bw;
    cvtColor(img, bw, COLOR_BGR2GRAY);
     //阈值处理
    threshold(bw, bw,  150255, 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( 25500),  28, 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 >( 00),pca_analysis.mean.at < double >( 01));
     //存储特征向量和特征值
    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( 2550255),  2);
     //计算出直线,在主要方向上绘制直线
    line(img, pos, pos  +  0. 02  * Point(eigen_vecs[ 0].x  * eigen_val[ 0], eigen_vecs[ 0].y  * eigen_val[ 0]) , CV_RGB( 2552550));
    line(img, pos, pos  +  0. 02  * Point(eigen_vecs[ 1].x  * eigen_val[ 1], eigen_vecs[ 1].y  * eigen_val[ 1]) , CV_RGB( 0255255));
     //返回角度结果
     return atan2(eigen_vecs[ 0].y, eigen_vecs[ 0].x);
}
结果展示:
感谢关注,希望有所帮助。
提供的这个gif录屏软件,非常好用。

 

目前方向:图像拼接融合、图像识别 联系方式:jsxyhelu@foxmail.com
目录
相关文章
|
7月前
三维手部关键点
三维手部关键点
|
5月前
|
机器学习/深度学习 自动驾驶 算法
深度学习之旋转包围盒检测
旋转包围盒检测是一种高级目标检测方法,旨在识别图像中目标的精确位置和方向。与传统的轴对齐矩形框(水平包围盒)不同,旋转包围盒(Rotated Bounding Box, RBB)允许检测框随目标旋转,从而更紧密地包围目标,尤其适用于长条形、倾斜或旋转的物体。深度学习在旋转包围盒检测中展现了强大的能力,通过训练神经网络模型,能够有效检测和回归旋转包围盒。
80 2
|
7月前
|
前端开发 JavaScript Java
B/S方向
B/S方向
43 4
|
7月前
|
文字识别 Python
Halcon 学习笔记五:几何定位+仿射变换+测量
Halcon 学习笔记五:几何定位+仿射变换+测量
663 0
|
机器学习/深度学习 算法
【目标识别】检测具有相同背景的不同图像并找到图像中的红色圆圈目标(Matlab代码实现)
【目标识别】检测具有相同背景的不同图像并找到图像中的红色圆圈目标(Matlab代码实现)
|
定位技术 异构计算
|
算法
通过光流法检测运动物体,得到图像运动场
通过光流法检测运动物体,得到图像运动场
393 0
通过光流法检测运动物体,得到图像运动场
|
传感器 JSON 数据可视化
【视觉高级篇】22 # 如何用仿射变换来移动和旋转3D物体?
【视觉高级篇】22 # 如何用仿射变换来移动和旋转3D物体?
202 0
【视觉高级篇】22 # 如何用仿射变换来移动和旋转3D物体?
MOOG G123-825-001 将旋转电机的旋转力转化为线性运动
MOOG G123-825-001 将旋转电机的旋转力转化为线性运动
149 0
MOOG G123-825-001 将旋转电机的旋转力转化为线性运动
|
算法 图形学
【计算机图形学】实验四:线段裁剪
【计算机图形学】实验四:线段裁剪
128 0
【计算机图形学】实验四:线段裁剪