请选择 进入手机版 | 继续访问电脑版

雨滴科技技术论坛

 找回密码
 立即注册
查看: 315|回复: 2

简单工件识别的方式:特征矩

[复制链接]

259

主题

1617

帖子

6701

积分

版主

Rank: 7Rank: 7Rank: 7

积分
6701
扫一扫,手机访问本帖
发表于 2018-8-10 21:09:53 | 显示全部楼层 |阅读模式
      特征矩的知识在概率论和数理统计中有介绍,空间矩的方法在图像应用中比较广泛,包括零阶矩求面积、一阶矩确定重心、
二阶矩确定主方向、二阶矩和三阶矩可以推导出七个不变矩Hu不变矩,不变矩具有旋转,平移、缩放等不变性,因此在工业
应用和模式识别中得到广泛的应用。
      

     对于二值化的图像:
   

#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
Mat src; Mat src_gray;
int thresh = 30;
int max_thresh = 255;
RNG rng(12345);
int main(){
src = imread( "opencv-logo.png" ,CV_LOAD_IMAGE_COLOR );
cvtColor( src, src_gray, CV_BGR2GRAY );//灰度化
GaussianBlur( src, src, Size(3,3), 0.1, 0, BORDER_DEFAULT );
blur( src_gray, src_gray, Size(3,3) ); //滤波
namedWindow( "image", CV_WINDOW_AUTOSIZE );
imshow( "image", src );
moveWindow("image",20,20);
//定义Canny边缘检测图像
Mat canny_output;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
//利用canny算法检测边缘
Canny( src_gray, canny_output, thresh, thresh*3, 3 );
namedWindow( "canny", CV_WINDOW_AUTOSIZE );
imshow( "canny", canny_output );
moveWindow("canny",550,20);
//查找轮廓
findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
//计算轮廓矩
vector<Moments> mu(contours.size() );
for( int i = 0; i < contours.size(); i++ )
{ mu = moments( contours, false ); }
//计算轮廓的质心
vector<Point2f> mc( contours.size() );
for( int i = 0; i < contours.size(); i++ )
{ mc = Point2d( mu.m10/mu.m00 , mu.m01/mu.m00 ); }

//画轮廓及其质心并显示
Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
printf("\t\t 几何特性\n");
for( int i = 0; i< contours.size(); i++ )
{
  Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
  drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );
  circle( drawing, mc, 4, color, -1, 8, 0 );  
  rectangle(drawing, boundingRect(contours.at(i)), cvScalar(0,255,0));
  printf("目标%d - 面积:%.2f - 周长: %.2f ", i, mu.m00, contourArea(contours), arcLength( contours, true ) );
  RotatedRect r = fitEllipse(contours.at(i));
  double majorAxis = r.size.height > r.size.width ? r.size.height : r.size.width;//长轴大小
  double minorAxis = r.size.height > r.size.width ? r.size.width : r.size.height;//短轴大小
  double area = mu.m00;//面积
  int perimeter = arcLength(contours.at(i), true);
  double orientation = r.angle;
  double orientation_rads = orientation*3.1416/180;
  printf("- 偏移角度: %.1f\n\n", orientation);
  double diameter = sqrt((4*area)/3.1416);//直径
  double eccentricity = sqrt(1-pow(minorAxis/majorAxis,2));//离心率
  double roundness = pow(perimeter, 2)/(2*3.1416*area);//圆滑度
  line(drawing, Point(mc.x, mc.y), Point(mc.x+30*cos(orientation_rads), mc.y+30*sin(orientation_rads)), cvScalar(0,0,200), 3);
  char tam[100];
  sprintf(tam, "%.2f", orientation);
  putText(drawing, tam, Point(mc.x, mc.y), FONT_HERSHEY_SIMPLEX, 0.5, cvScalar(0,220,120),1.5);
}
namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
imshow( "Contours", drawing );
moveWindow("Contours",1100,20);
waitKey(0);
src.release();
src_gray.release();
return 0;
}
   特征矩样本.png

特征矩结果.png




回复

使用道具 举报

308

主题

1609

帖子

7575

积分

版主

Rank: 7Rank: 7Rank: 7

积分
7575
发表于 2018-8-12 21:12:29 | 显示全部楼层
怪不得你最近问三个点的问题。
回复 支持 反对

使用道具 举报

173

主题

769

帖子

3589

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3589
发表于 2018-8-13 10:44:47 | 显示全部楼层
太复杂        
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

在线客服
在线咨询
咨询热线
0755-26787502-8006/8016
扫一扫二维码
直接访问本站

QQ|Archiver|手机版|小黑屋|雨滴科技  

GMT+8, 2018-12-19 21:20 , Processed in 0.072005 second(s), 12 queries , Gzip On, Memcache On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表