opencv学习——Moments()函数,计算物体形状方向

opencv中的矩主要包括以下几种:空间矩,中心矩和中心归一化矩。
class Moments { public: …

// 空间矩

double m00, m10, m01, m20, m11, m02, m30, m21, m12, m03;

// 中心矩

double mu20, mu11, mu02, mu30, mu21, mu12, mu03;

// 中心归一化矩 double nu20, nu11, nu02, nu30, nu21, nu12, nu03;

}
**针对一幅图像,我们把像素的坐标看成是一个二维随机变量(X, Y),那么一副灰度图可以用二维灰度图密度函数来表示,因此可以用矩来描述灰度图像的特征。**图像可以看成是一个平板的物体,其一阶矩和零阶矩就可以拿来计算某个形状的重心,而二阶矩就可以拿来计算形状的方向。
在这里插入图片描述
其中M00即零阶矩,M20和M02为二阶矩,接下来计算物体形状的方向
在这里插入图片描述
在这里插入图片描述

#region 三角函数和反三角函数
 
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Messaging;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace test
{
    class Program
    {
        static void Main(string[] args)
        {
            #region 正弦、反正弦
            //正弦
            double sinAngleValue1 = 30;//角度值:30度。
            double sinRadianValue1 = Math.PI * sinAngleValue1 / 180;//求弧度值
            double sinValue1 = Math.Sin(sinRadianValue1);//求sin30度,其实sin30度 = sin(PI/6),但是,数学上或代码上,常常用弧度PI/6,来计算sin(PI/6),其他函数同理。
            Console.WriteLine(sinValue1);
            //反正弦
            double sinValue2 = 0.5;//正弦值 = 0.5。
            double sinRadianValue2 = Math.Asin(sinValue2);//求弧度值
            double sinAngleValue2 = sinRadianValue2 / Math.PI * 180;//根据弧度值,来求角度值。
            Console.WriteLine(sinAngleValue2);
            Console.WriteLine();
            #endregion
 
            #region 正切、反正切
            Console.WriteLine();
            Console.WriteLine();
            //正切
            double tanAngleValue1 = 15;//角度值
            double tanRadianValue1 = Math.PI * tanAngleValue1 / 180;//求弧度值
            double tanValue1 = Math.Tan(tanRadianValue1);//tan值
            Console.WriteLine(tanValue1);//tan值
 
            double tanValue2 = 1;//正切值
            double tanRadianValue2 = Math.Atan(tanValue2);//求弧度值
            double tanAngleValue2 = tanRadianValue2 / Math.PI *180;//求角度
            Console.WriteLine(tanAngleValue2);
            #endregion
            Console.ReadLine();
        }
    }
}
#endregion

在这里插入图片描述
在这里插入图片描述

### 使用OpenCV进行多种形状物体的检测与识别 #### 图像预处理 为了有效地区分不同的几何形状,在开始之前通常需要对输入图像执行一系列预处理操作。这包括但不限于灰度化转换、噪声去除以及边缘增强等步骤,以便后续能够更清晰地提取目标特征[^2]。 ```python import cv2 import numpy as np # 加载原始彩色图片并转成灰度图 image = cv2.imread('shapes.png') gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 应用高斯模糊减少噪音干扰 blurred = cv2.GaussianBlur(gray, (5, 5), 0) ``` #### 边缘检测 采用Canny算子或其他方法可以有效地找到图像中的边界线段,这对于定位封闭区域内的特定图形至关重要。经过此阶段后得到的结果将是二值化的边框表示形式,其中白色像素代表可能存在的轮廓位置。 ```python # Canny Edge Detection edges = cv2.Canny(blurred, 50, 150) ``` #### 轮廓发现 利用`findContours()`函数可以从上述获得的边缘映射里检索到所有的连通域,并返回它们各自的坐标集合。对于每一个这样的闭合路径而言,还可以进一步计算其近似多边形以简化描述方式,从而便于之后判断具体属于哪种标准形态。 ```python contours, _ = cv2.findContours(edges.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for cnt in contours: perimeter = cv2.arcLength(cnt, True) approx = cv2.approxPolyDP(cnt, 0.04 * perimeter, True) if len(approx) == 3: shape_name = "Triangle" elif len(approx) == 4: x,y,w,h = cv2.boundingRect(cnt) aspect_ratio = float(w)/h if 0.95 <= aspect_ratio <= 1.05: shape_name = "Square" else: shape_name = "Rectangle" elif len(approxx) >= 5 and len(approx)<=7 : shape_name="Pentagon" #五角星的情况较为复杂,这里简单假设为五边形 elif len(approx)>8: shape_name = "Circle" # 绘制轮廓及其标签 M = cv2.moments(cnt) cX = int(M["m10"] / M["m00"]) cY = int(M["m01"] / M["m00"]) cv2.drawContours(image,[cnt],-1,(0,255,0),2) cv2.putText(image,shape_name,(cX,cY),cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,255,255),2) ``` #### 形状分类 基于前面获取的信息——即每条轮廓所对应的顶点数量,就可以轻松判定当前对象最接近于哪一类已知的标准模型(如三角形、正方形/矩形、圆圈)。值得注意的是,实际应用场景下可能会遇到更多种类或者不规则的对象,因此还需要考虑额外的因素来进行更为精确的区别对待。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值