opencv摄像头寻找三角形、正方形等多边形

2 篇文章 0 订阅

在QT中因需要写了这个,QT操作原址为  QT中应用OpenCV查找多边形 ,单独测试代码如下

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <cmath>

/**
* @brief  用向量来做COSα=两向量之积/两向量模的乘积求两条线段夹角
* @param  线段3个点坐标pt1,pt2,pt0,最后一个参数为公共点
* @retval 线段夹角,单位为角度
* @author  BugAngel
* @attention
*/
double angle(cv::Point pt1, cv::Point pt2, cv::Point pt0)
{
    double dx1 = pt1.x - pt0.x;
    double dy1 = pt1.y - pt0.y;
    double dx2 = pt2.x - pt0.x;
    double dy2 = pt2.y - pt0.y;
    double angle_line = (dx1*dx2 + dy1*dy2) / sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);//余弦值
    return acos(angle_line) * 180 / 3.141592653;
}

/**
* @brief  判断角度是否在范围内
* @param  angle为输入角度,rangeMin,rangeMax分别为范围的下限和上限
* @retval 在范围内返回true,不在返回false
* @author  BugAngel
* @attention
*/
bool angleRange(double angle,int rangeMin,int rangeMax)
{
    if(angle > rangeMin && angle < rangeMax)
    {
        return true;
    }
    else
    {
        return false;
    }
}

int main()
{
    cv::VideoCapture capture(0);
    double minArea=1000;//最小面积
    double maxArea=120000;//最大面积
    unsigned int shape;//多边形边数
    cv::RNG g_rng(12345);
    cv::Mat grayImage;
    cv::Mat cannyMat_output;
    std::vector<std::vector<cv::Point>> contours;
    std::vector<cv::Vec4i> hierarchy;
    int thresh = 100;
    cv::Mat srcImage;
    cv::Mat dstImage;
	int shape;

    while(1)
    {
        if(capture.isOpened())
        {
            capture>>srcImage;

            cv::cvtColor(srcImage,grayImage,CV_RGB2GRAY);

            // 用Canny算子检测边缘
            cv::Canny( grayImage, cannyMat_output, thresh, thresh*2, 3 );

            // 寻找轮廓
            cv::findContours( cannyMat_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0) );

            //多边形逼近轮廓
            std::vector<std::vector<cv::Point>> contours_poly(contours.size());

            for(unsigned int i=0;i<contours.size();i++)
            {
                cv::approxPolyDP(contours[i], contours_poly[i], 3, true);//多边形逼近
                double tempArea=cv::contourArea(contours_poly[i]);
                //如果是凸多边形并且面积在范围内,并且是凸的
                if((contours_poly[i].size() == shape &&  tempArea > minArea  && tempArea < maxArea &&  cv::isContourConvex(contours_poly[i])))
                {
                    if(shape==3)
                    {
                        double angel_1 = fabs(angle(contours_poly[i][0], contours_poly[i][1], contours_poly[i][2]));
                        double angel_2 = fabs(angle(contours_poly[i][0], contours_poly[i][2], contours_poly[i][1]));
                        double angel_3 = fabs(angle(contours_poly[i][1], contours_poly[i][2], contours_poly[i][0]));
                        if (angleRange(angel_1,50,70) && angleRange(angel_2,50,70) && angleRange(angel_3,50,70))//判断角度范围
                        {
                            cv::Scalar color = cv::Scalar( g_rng.uniform(0, 255), g_rng.uniform(0,255), g_rng.uniform(0,255) );//随机生成颜色值
                            cv::polylines(dstImage,contours_poly[i],true,color,5, CV_AA, 0);//画出多边形轮廓
                        }
                    }
                    else if(shape==4)
                    {
                        double angel_1 = fabs(angle(contours_poly[i][1], contours_poly[i][3], contours_poly[i][0]));
                        double angel_2 = fabs(angle(contours_poly[i][0], contours_poly[i][2], contours_poly[i][1]));
                        double angel_3 = fabs(angle(contours_poly[i][1], contours_poly[i][3], contours_poly[i][2]));
                        double angel_4 = fabs(angle(contours_poly[i][2], contours_poly[i][0], contours_poly[i][3]));
                        if (angleRange(angel_1,80,100)&&angleRange(angel_2,80,100)&&angleRange(angel_3,80,100)&&angleRange(angel_4,80,100))//判断角度范围
                        {
                            cv::Scalar color = cv::Scalar( g_rng.uniform(0, 255), g_rng.uniform(0,255), g_rng.uniform(0,255) );//随机生成颜色值
                            cv::polylines(dstImage,contours_poly[i],true,color,5, CV_AA, 0);//画出多边形轮廓
                        }
                    }
                }
            }
            cv::imshow("多边形检测",dstImage);
        }
    }
}

 

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值