OpenCV开发笔记(五十八):红胖子8分钟带你深入了解图像的矩(图文并茂+浅显易懂+程序源码)

若该文为原创文章,未经允许不得转载

原博主博客地址:https://blog.csdn.net/qq21497936

原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062

本文章博客地址:https://blog.csdn.net/qq21497936/article/details/106257036

各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究

红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…(点击传送门)

OpenCV开发专栏(点击传送门)

上一篇:《OpenCV开发笔记(五十七):红胖子8分钟带你深入了解直方图反向投影(图文并茂+浅显易懂+程序源码)》

下一篇:持续补充中…

前言

红胖子,来也!

做识别,有时候需求要识别面积、距离能,若双瞳之间的距离,手机的宽高等等,图像的矩就是为这些需要识别具体标量的基础之一。

Demo

图像的矩

概述

  矩函数在图像分析中是必备的方法之一,应用广泛,如模式识别、目标分类、目标识别与方位估计、图像编码与重构等。一天个从一副数字图形中计算出来的矩集,通常描述了该图形形状的全局特征,并提供了大量的关于该图像不同类型的集合特性信息,比如大小、方向及形状等。

一阶矩:与形状有关;

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

三阶矩:关于平均值的对称性的测量;

寻找轮廓

请参照博文《OpenCV开发笔记(四十九):红胖子8分钟带你深入了解轮廓识别(图文并茂+浅显易懂+程序源码)》

计算图像所有的矩(最高到三阶)

  计算多边形和光山形状的最高达三阶的所有矩,可用来计算形状的中心、面积、主轴和其他形状特征。

Moments moments( InputArray array, bool binaryImage = false );

参数一:InputArray类型的array,输入参数可以是光栅图像(单通道、8位或浮点的二维数组)或二维数组(lN或NI);

参数二:bool类型的binaryImage,默认值false。若此参数取true,则所有非零像素为1。此参数仅对于图像使用;

注意:此参数的返回值是返回运行后的结果。

计算轮廓面积函数原型

  用于计算部分轮廓的面积或者整个轮廓。

doube contourArea (InputArray contour , bool oriented=false );

参数一:InputArray类型的contour,输入的向量,二维点(轮廓顶点),可以为std::vector或Mat类型;

参数二:bool类型的oriented,面向区域标识符。若其为true,该函数返回一个带符号的面积值,其正负取决于轮廓的方向(顺时针还是逆时针)。根据这个特性我们可以根据面积的符号来确定轮廓的位置。需要注意的是,这个参数有默认值false,表示以绝对值返回,不带符号;

用于计算封闭轮廓的周长或曲线的长度。

double arcLength (InputArray curve , boo1 c1osed);

参数一:InputArray类型的curve,输入的二维点集,可以为std::vector或Mat类型;

参数二:bool类型的closed,一个用于指示曲线是否封闭的标识符,有默认值closed,表示曲线封闭;

Demo源码

void OpenCVManager::testMoments()

{

    QString fileName1 =

            "E:/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/15.jpg";

    int width = 400;

    int height = 300;

    cv::Mat srcMat = cv::imread(fileName1.toStdString());

    cv::resize(srcMat, srcMat, cv::Size(width, height));

    cv::String windowName = _windowTitle.toStdString();

    cvui::init(windowName);

    cv::Mat windowMat = cv::Mat(cv::Size(srcMat.cols * 2, srcMat.rows * 3),

                                srcMat.type());

    int threshold1 = 200;

    int threshold2 = 100;

    while(true)

    {

        windowMat = cv::Scalar(0, 0, 0);

        cv::Mat mat;

        cv::Mat dstMat;

        cv::Mat grayMat;

        cv::Mat tempMat;

        cv::Mat hullMat;

        hullMat = srcMat.clone();

        // 原图先copy到左边

        mat = windowMat(cv::Range(srcMat.rows * 0, srcMat.rows * 1),

                        cv::Range(srcMat.cols * 0, srcMat.cols * 1));

        cv::addWeighted(mat, 0.0f, srcMat, 1.0f, 0.0f, mat);

        {

            // 灰度图

            cv::cvtColor(srcMat, grayMat, CV_BGR2GRAY);

            cv::cvtColor(grayMat, tempMat, CV_GRAY2BGR);

            // copy

            mat = windowMat(cv::Range(srcMat.rows * 1, srcMat.rows * 2),

                            cv::Range(srcMat.cols * 0, srcMat.cols * 1));

            cv::addWeighted(mat, 0.0f, tempMat, 1.0f, 0.0f, mat);

            cvui::printf(windowMat,

                        srcMat.rows * 1 + 100,

                        srcMat.cols * 0 + 20,

                        "threshold1");

            cvui::trackbar(windowMat,

                          srcMat.rows * 1 + 100,

                          srcMat.cols * 0 + 50,

                          200,

                          &threshold1,

                          0,

                          255);

            cvui::printf(windowMat,

                        srcMat.rows * 1 + 100,

                        srcMat.cols * 0 + 100, "threshold2");

            cvui::trackbar(windowMat,

                          srcMat.rows * 1 + 100,

                          srcMat.cols * 0 + 130,

                          200,

                          &threshold2,

                          0,

                          255);

            // 使用边缘检测

            cv::Canny(grayMat, dstMat, threshold1, threshold2, 3);

            // copy

            mat = windowMat(cv::Range(srcMat.rows * 1, srcMat.rows * 2),

                            cv::Range(srcMat.cols * 1, srcMat.cols * 2));

            cv::Mat rgbMat;

            cv::cvtColor(dstMat, rgbMat, CV_GRAY2BGR);

            cv::addWeighted(mat, 0.0f, rgbMat, 1.0f, 0.0f, mat);

            // 寻找轮廓

            std::vector> contours;

            cv::findContours(dstMat, contours, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);

            // 绘制轮廓

            for(int index = 0; index < contours.size(); index++)

            {

                cv::drawContours(hullMat, contours, index, cv::Scalar(0, 0, 255), 2);

            }

            // copy

            mat = windowMat(cv::Range(srcMat.rows * 2, srcMat.rows * 3),

                            cv::Range(srcMat.cols * 0, srcMat.cols * 1));

            cv::addWeighted(mat, 0.0f, hullMat, 1.0f, 0.0f, mat);

            // 计算图像所有的矩

            std::vector mu(contours.size());

            for(int index = 0; index < contours.size(); index++)

            {

                mu[index] = cv::moments(contours[index], false);

            }

            // 计算轮廓的面积

            for(int index = 0; index < contours.size(); index++)

            {

                double area = cv::contourArea(contours[index]);

                cvui::printf(windowMat,

                            srcMat.cols * 1,

                            srcMat.rows * 2 + 15 * index,

                            "%d/%d: contorsArea = %f",

                            index,

                            contours.size(),

                            area);

                double length = cv::arcLength(contours[index], true);

                cvui::printf(windowMat,

                            srcMat.cols * 1 + width / 2 + 30,

                            srcMat.rows * 2 + 15 * index,

                            "arcLength = %f",

                            length);

            }

        }

        // 更新

        cvui::update();

        // 显示

        cv::imshow(windowName, windowMat);

        // esc键退出

        if(cv::waitKey(25) == 27)

        {

            break;

        }

    }

}

工程模板:对应版本号v1.52.0

  对应版本号v1.52.0

原博主博客地址:https://blog.csdn.net/qq21497936

原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062

本文章博客地址:https://blog.csdn.net/qq21497936/article/details/106257036

你可能感兴趣的:(OpenCV开发笔记(五十八):红胖子8分钟带你深入了解图像的矩(图文并茂+浅显易懂+程序源码))