zoukankan      html  css  js  c++  java
  • OpenCV (C++) 几何形状识别(面积过滤、横纵比过滤等等)

     1 #include <opencv2/opencv.hpp>
     2 #include <iostream>
     3 #include <math.h>
     4 
     5 using namespace cv;
     6 using namespace std;
     7 
     8 
     9 int main(int argc, char** argv)
    10 {
    11     Mat src = imread("3 input.bmp", IMREAD_GRAYSCALE);
    12     Mat binary, dst = Mat::zeros(src.size(), CV_8UC3);
    13     Mat Triangle = dst.clone(), Rect1 = dst.clone(), BigCircle = dst.clone(), SmallCircle = dst.clone();
    14 
    15     if (src.empty()) {
    16         printf("Could not load image...");
    17         return -1;
    18     }
    19     src = ~src;//取反
    20     imshow("原图", src);
    21     //二值化
    22     threshold(src, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
    23 
    24     //发现轮廓
    25     vector<vector<Point>> contours;
    26     vector<Vec4i> hireachy;
    27     findContours(binary, contours, hireachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());
    28 
    29     //面积删选
    30     for (size_t t = 0; t < contours.size(); t++)
    31     {
    32         double area = contourArea(contours[t]);
    33         if (area < 40000) continue;//将面积小于40000的去掉
    34         drawContours(Triangle, contours, t, Scalar(0, 0, 255), 2, 8, Mat(), 0, Point());
    35     }
    36 
    37     for (size_t t = 0; t < contours.size(); t++)
    38     {
    39         double area = contourArea(contours[t]);
    40         if (area > 40000 || area<20000) continue;//将面积小于40000的去掉
    41         drawContours(BigCircle, contours, t, Scalar(0, 0, 255), 2, 8, Mat(), 0, Point());
    42     }
    43 
    44     for (size_t t = 0; t < contours.size(); t++)
    45     {
    46         double area = contourArea(contours[t]);
    47         if (area > 20000 || area<15000) continue;//将面积小于40000的去掉
    48         drawContours(Rect, contours, t, Scalar(0, 0, 255), 2, 8, Mat(), 0, Point());
    49     }
    50 
    51     for (size_t t = 0; t < contours.size(); t++)
    52     {
    53         double area = contourArea(contours[t]);
    54         if (area > 15000) continue;//将面积小于40000的去掉
    55         //其他过滤方法
    56 
    57         /*//横纵比过滤
    58         Rect rect= boundingRect(contours[t]);//返回最小外接矩形
    59         float ratio = float(rect.width) / float(rect.height);//计算横纵比
    60         if (ratio<1.1&&ratio>0.9) {}
    61         
    62         //周长过滤
    63         float length = arcLength(contours[t], true);//计算轮廓长度
    64         
    65         */
    66 
    67         
    68         drawContours(SmallCircle, contours, t, Scalar(0, 0, 255), 2, 8, Mat(), 0, Point());
    69     }
    70     imshow("Triangle", Triangle);
    71     imshow("BigCircle", BigCircle);
    72     imshow("Rect", Rect1);
    73     imshow("SmallCircle", SmallCircle);
    74 
    75     waitKey(0);
    76     return 0;
    77 }

     方法二:多边形逼近:

    void approxPolyDP(InputArray curve, OutputArray approxCurve, double epsilon, bool closed);

    参数说明:

    InputArray curve:输入的点集
    OutputArray approxCurve:输出的点集,当前点集是能最小包容指定点集的。draw出来即是一个多边形;
    double epsilon:指定的精度,也即是原始曲线与近似曲线之间的最大距离。
    bool closed:若为true,则说明近似曲线是闭合的,它的首位都是相连,反之,若为false,则断开。

     1 #include <opencv2/opencv.hpp>
     2 #include <iostream>
     3 
     4 #define MATCHMETHOD TM_SQDIFF_NORMED//宏定义匹配模式
     5 using namespace cv;
     6 using namespace std;
     7 
     8 
     9 int main(int argc, char** argv)
    10 { 
    11     Mat src = imread("F:/2019视觉培训内容/2019视觉培训内容/3 input.bmp");
    12     Mat src_gray,binary ;
    13     Mat Triangle = src.clone(), Rect = src.clone(), BigCircle = src.clone(), SmallCircle = src.clone();
    14     if (src.empty()) {
    15         printf("Could not load image...");
    16         return -1;
    17     }
    18     imshow("Input Image",src);
    19       
    20     //二值化
    21     cvtColor(src, src_gray, COLOR_BGR2GRAY);
    22     threshold(src_gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
    23     binary = ~binary;
    24     imshow("binary", binary);
    25 
    26     //发现轮廓
    27     vector<vector<Point>> contours;
    28     vector<Point> point;
    29     vector<Vec4i> hireachy;
    30     findContours(binary, contours, hireachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());
    31     
    32     //绘制出所有轮廓
    33     for (size_t t = 0; t < contours.size(); t++)
    34     {
    35                 
    36         int epsilon = 0.01*arcLength(contours[t], true);
    37         approxPolyDP(contours[t], point, epsilon, true);
    38         if(point.size()==3)
    39         {
    40             drawContours(Triangle, contours, t, Scalar(0, 0, 255), 2, 8, Mat(), 0, Point());//dst必须先初始化 
    41         }
    42         else if (point.size() == 4)
    43         {
    44             drawContours(Rect, contours, t, Scalar(0, 0, 255), 2, 8, Mat(), 0, Point());//dst必须先初始化
    45         }
    46 
    47         else 
    48         {
    49             double area = contourArea(contours[t]);
    50             if (area < 15000)
    51             {
    52                 drawContours(SmallCircle, contours, t, Scalar(0, 0, 255), 2, 8, Mat(), 0, Point());//dst必须先初始化
    53             }
    54             else
    55             {
    56                 drawContours(BigCircle, contours, t, Scalar(0, 0, 255), 2, 8, Mat(), 0, Point());//dst必须先初始化
    57             }
    58         }
    59         
    60         cout << "边的数目:" << point.size() << endl;
    61     }
    62 
    63     imshow("Triangle", Triangle);
    64     imshow("BigCircle", BigCircle);
    65     imshow("Rect", Rect);
    66     imshow("SmallCircle", SmallCircle);
    67 
    68     waitKey(0);
    69 
    70     return 0;
    71 }
  • 相关阅读:
    [JZOJ4648] 【NOIP2016提高A组模拟7.17】锦标赛
    [JZOJ4684] 【GDOI2017模拟8.11】卡牌游戏
    [JZOJ4649] 【NOIP2016提高A组模拟7.17】项链
    [JZOJ4682] 【GDOI2017模拟8.11】生物学家
    [JZOJ4639] 【NOIP2016提高组A组7.16】Angel Beats!
    收藏一个bit模板使用实例
    51 Nod 1627瞬间移动(插板法!)
    收藏一个有效的求组合数的模板
    51 Nod 1486 大大走格子
    51nod 1120 机器人走方格V3
  • 原文地址:https://www.cnblogs.com/long5683/p/9694983.html
Copyright © 2011-2022 走看看