• 计算物体的凸包


            凸包跟多边形逼近很像,只不过它是物体最外层的"凸"多边形:集合A内连接任意两个点的直线都在A的内部,则称集合A是凸形的。如下图,红色的部分为手掌的凸包,双箭头部分表示凸缺陷(Convexity Defects),凸缺陷常用来进行手势识别等;

    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    using namespace cv;
    using namespace std;
    //设置全局参数
    Mat srcImage, srcGray;
    int thresh = 100;
    int max_thresh = 255;
    RNG rng(12345);
    void thresh_callback(int, void*)
    {
        Mat srcTemp = srcImage.clone();
        Mat threMat;
        //轮廓检测参数
        vector<vector<Point> > contours;
        vector<Vec4i> hierarchy;
        //阈值化操作
        threshold(srcGray, threMat, thresh, 255, THRESH_BINARY);
        //轮廓检测
        findContours(threMat, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
        //凸包及缺陷检测参数
        vector<vector<Point> > pointHull(contours.size());
        vector<vector<int> > intHull(contours.size());
        vector<vector<Vec4i> > hullDefect(contours.size());
        for (size_t i = 0; i < contours.size(); i++)
        {
            //Point类型凸包检测
            convexHull(Mat(contours[i]), pointHull[i], false);
            //int 类型凸包检测
            convexHull(Mat(contours[i]), intHull[i], false);
            //凸包缺陷检测
            convexityDefects(Mat(contours[i]), intHull[i], hullDefect[i]);
        }
        //绘制凸包及缺陷检测
        Mat drawing = Mat::zeros(threMat.size(), CV_8UC3);
        for (size_t 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, 1, 8, vector<Vec4i>(), 0, Point());
            drawContours(drawing, pointHull, i, color, 1, 8, vector<Vec4i>(), 0, Point());
            //绘制缺陷
            size_t count = contours[i].size();
            if (count < 300)
                continue;
            //设置凸包缺陷迭代器
            vector<Vec4i>::iterator iterDefects = hullDefect[i].begin();
            //遍历得到4个特征量
            while (iterDefects != hullDefect[i].end())
            {
                Vec4i& v = (*iterDefects);
                //起始位置
                int startidx = v[0];
                Point ptStart(contours[i][startidx]);
                //终止位置
                int endidx = v[1];
                Point ptEnd(contours[i][endidx]);
                //内凸壳最远的点缺陷
                int faridx = v[2];
                Point ptFar(contours[i][faridx]);
                //凸点之间的最远点
                int depth = v[3] / 256;
                //绘制相应的线与圆检测结果
                if (depth > 20 && depth < 80)
                {
                    line(drawing, ptStart, ptFar, CV_RGB(0, 255, 0), 2);
                    line(drawing, ptEnd, ptFar, CV_RGB(0, 255, 0), 2);
                    circle(drawing, ptStart, 4, Scalar(255, 0, 100), 2);
                    circle(drawing, ptEnd, 4, Scalar(255, 0, 100), 2);
                    circle(drawing, ptFar, 4, Scalar(100, 0, 255), 2);
                }
                iterDefects++;
            }
        }
        imshow("result", drawing);
    }
    int main()
    {
        srcImage = imread("E:\VS2015Opencv\vs2015\project\picture\01.jpg");
        if (!srcImage.data)
            return -1;
        cvtColor(srcImage, srcGray, CV_BGR2GRAY);
        blur(srcGray, srcGray, Size(3, 3));
    
        char* sour_window = "Sourse";
        namedWindow(sour_window, CV_WINDOW_AUTOSIZE);
        imshow(sour_window, srcImage);
        createTrackbar("Thewshold:", sour_window, &thresh, max_thresh, thresh_callback);
        thresh_callback(0, 0);
        waitKey(0);
        return 0;
    }

  • 相关阅读:
    Jquery ajax异步传值的两个实用的方法,你看后肯定会用第二个
    C# ASP.NET 转换为int型的方法 很实用
    NetCore 发送邮件
    解决Visual Studio For Mac Restore失败的问题
    (转)JSONObject的toBean 和 fromObject
    javax.servlet不存在的问题
    关于范式的解说
    在远程连接mysql数据库出现问题怎么办
    (二)SpringCloud学习系列-SpringCloud
    (一)SpringCloud学习系列-微服务
  • 原文地址:https://www.cnblogs.com/fcfc940503/p/11315222.html
Copyright © 2020-2023  润新知