Opencv学习笔记 - MatchShapes函数

        矩的概念

        矩函数在图像分析中有着广泛的应用,如模式识别、目标分类、目标识别与方位估计、图像的编码与重构等。从一幅图像计算出来的矩集,不仅可以描述图像形状的全局特征,而且可以提供大量关于该图像不同的几何特征信息,如大小,位置、方向和形状等。图像矩这种描述能力广泛应用于各种图像处理、计算机视觉和机器人技术领域的目标识别与方位估计中。

        一阶矩:与形状有关;

        二阶矩:显示曲线围绕直线平均值的扩展程度;

        三阶矩:关于平均值的对称性测量;由二阶矩和三阶矩可以导出7个不变矩。而不变矩是图像的统计特性,满足平移、伸缩、旋转均不变的不变性、在图像识别领域得到广泛的应用。

        在OpenCV中,可以很方便的计算多边形区域的3阶特征矩,opencv中的矩主要包括以下几种:空间矩,中心矩和中心归一化矩。

        函数的作用是用来比较两个形状的相似度,根据计算比较两张图像Hu不变距(函数返回值代表相似度大小,完全相同的图像返回值是0,返回值最大是1)。几何矩是由Hu(Visual pattern recognition by moment invariants)在1962年提出的,具有平移、旋转和尺度不变性。由Hu矩组成的特征量对图片进行识别,优点就是速度很快,缺点是识别率比较低。这一部分原因是由于Hu不变矩只用到低阶矩(最多也就用到三阶矩),对于图像的细节未能很好的描述出来,导致对图像的描述不够完整。Hu不变矩一般用来识别图像中大的物体,对于物体的形状描述得比较好,图像的纹理特征不能太复杂,像识别水果的形状,或者对于车牌中的简单字符的识别效果会相对好一些。

double cvMatchShapes(const void* object1, const void* object2, int method, double parameter = 0);
/*
第一个参数是待匹配的物体1,第二个是待匹配的物体2
第三个参数method有三种输入:
CV_CONTOURS_MATCH_I1
CV_CONTOURS_MATCH_I2
CV_CONTOURS_MATCH_I3
即三种不同的判定物体相似的方法
*/

        简单应用测试,在图像中寻找轮廓,并寻找所有相似的标记出来。

//打开图像
Mat src = new Mat(@"C:/Users/zyh/Desktop/123.jpg", ImreadModes.LoadGdal);
            
Mat src_gray = new Mat();
Mat dst = new Mat();
if(src.Channels() == 1)
{
    src_gray = src;
}
else
{
    //将原图像转换为灰度图像
    Cv2.CvtColor(src, src_gray, ColorConversionCodes.BGR2GRAY);
}

//这里的阈值是用其他方式获取的  
Cv2.Threshold(src_gray, dst, 235, 255, ThresholdTypes.Binary);
Cv2.ImShow("ssdd", dst);

//寻找轮廓
OpenCvSharp.Point[][] contours;
HierarchyIndex[] hierachy;
Cv2.FindContours(dst, out contours, out hierachy, RetrievalModes.CComp, ContourApproximationModes.ApproxNone);

//找所有相似的轮廓
foreach (OpenCvSharp.Point[] ko in contours)
{
    List<OpenCvSharp.Point[]> a = new List<OpenCvSharp.Point[]>();

    foreach (OpenCvSharp.Point[] co in contours)
    {
        double ret =  Cv2.MatchShapes(ko, co, OpenCvSharp.ShapeMatchModes.I2, 0.0);
        //修改参数范围,可以看到不同的识别结果
        if (0.02 < ret && ret < 0.15) {
            a.Add(co);
        }
    }

    if (a.Count() > 0) {
        OpenCvSharp.Point[][] c = new OpenCvSharp.Point[a.Count()][];
        int i = 0;
        foreach (OpenCvSharp.Point[] b in a) {
            c[i] = b;
            i++;
        }
        Cv2.DrawContours(src, c, -1, Scalar.Red, 2);
    }
}
Cv2.ImShow("ss1", src);
原图
二值图
标记出来相似的轮廓

猜你喜欢

转载自blog.csdn.net/bashendixie5/article/details/113441671
今日推荐