zoukankan      html  css  js  c++  java
  • OpenCV 轮廓查找与绘制-最小外接矩形

    一、简介

    二、轮廓最小外接矩形的绘制

     1 #include "opencv2/opencv.hpp"
     2 using namespace cv;
     3 
     4 void main()
     5 {
     6     //轮廓最小外接矩形的绘制
     7     Mat srcImg = imread("E://00.png");
     8     Mat dstImg = srcImg.clone();
     9     cvtColor(srcImg, srcImg, CV_BGR2GRAY);
    10     threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY); //二值化
    11     imshow("threshold", srcImg);
    12 
    13     vector<vector<Point>> contours;
    14     vector<Vec4i> hierarcy;
    15     findContours(srcImg, contours, hierarcy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
    16     vector<Rect> boundRect(contours.size());  //定义外接矩形集合
    17     vector<RotatedRect> box(contours.size()); //定义最小外接矩形集合
    18     Point2f rect[4];
    19     for(int i=0; i<contours.size(); i++)
    20     {
    21         box[i] = minAreaRect(Mat(contours[i]));  //计算每个轮廓最小外接矩形
    22         boundRect[i] = boundingRect(Mat(contours[i]));
    23         circle(dstImg, Point(box[i].center.x, box[i].center.y), 5, Scalar(0, 255, 0), -1, 8);  //绘制最小外接矩形的中心点
    24         box[i].points(rect);  //把最小外接矩形四个端点复制给rect数组
    25         rectangle(dstImg, Point(boundRect[i].x, boundRect[i].y), Point(boundRect[i].x + boundRect[i].width, boundRect[i].y + boundRect[i].height), Scalar(0, 255, 0), 2, 8);
    26         for(int j=0; j<4; j++)
    27         {
    28             line(dstImg, rect[j], rect[(j+1)%4], Scalar(0, 0, 255), 2, 8);  //绘制最小外接矩形每条边
    29         }
    30     }
    31     imshow("dst", dstImg);
    32     waitKey(0);
    33 }

    三、粗略计算物体像素长宽

     1 #include "opencv2/opencv.hpp"
     2 #include<iostream>
     3 using namespace std;
     4 using namespace cv;
     5 
     6 void main()
     7 {
     8     Mat srcImg = imread("E://cup.jpg");
     9     imshow("src", srcImg);
    10     Mat dstImg = srcImg.clone();
    11     medianBlur(srcImg, srcImg, 5);
    12     GaussianBlur(srcImg, srcImg, Size(3, 3), 0, 0);
    13     cvtColor(srcImg, srcImg, CV_BGR2GRAY);
    14     threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY_INV); //INV是因为背景白色,物体黑色,需要反转一下
    15     imshow("threshold", srcImg);
    16 
    17     vector<vector<Point>> contours;
    18     vector<Vec4i> hierarcy;
    19 
    20     findContours(srcImg, contours, hierarcy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
    21     cout<<"num="<<contours.size()<<endl;
    22     vector<Rect> boundRect(contours.size());
    23     vector<RotatedRect> box(contours.size());
    24     Point2f rect[4];
    25     for(int i=0; i<contours.size(); i++)
    26     {
    27         box[i] = minAreaRect(Mat(contours[i]));
    28         boundRect[i] = boundingRect(Mat(contours[i]));
    29         cout<<box[i].angle<<endl;
    30         cout<<box[i].center<<endl;
    31         cout<<box[i].size.width<<endl;
    32         cout<<box[i].size.height<<endl;
    33         circle(dstImg, Point(box[i].center.x, box[i].center.y), 5, Scalar(0, 255, 0), -1, 8);
    34 
    35         //绘制外接矩形和    最小外接矩形(for循环)
    36         rectangle(dstImg, Point(boundRect[i].x, boundRect[i].y), Point(boundRect[i].x + boundRect[i].width, boundRect[i].y + boundRect[i].height), Scalar(0, 255, 0), 2, 8);
    37         box[i].points(rect);//把最小外接矩形四个端点复制给rect数组
    38         for(int j=0; j<4; j++)
    39         {
    40             line(dstImg, rect[j], rect[(j+1)%4], Scalar(0, 0, 255), 2, 8);
    41         }
    42 
    43         char width[20], height[20];
    44         sprintf(width, "width=%0.2f", box[i].size.width);
    45         sprintf(height, "height=%0.2f", box[i].size.height);
    46         putText(dstImg, width, Point(235, 260), CV_FONT_HERSHEY_COMPLEX_SMALL, 0.85, Scalar(0, 255, 0));
    47         putText(dstImg, height, Point(235, 285), CV_FONT_HERSHEY_COMPLEX_SMALL, 0.85, Scalar(0, 255, 0));
    48 
    49     }
    50     imshow("dst", dstImg);
    51     waitKey(0);
    52 }

    四、倾斜物体矫正提取

     1 #include "opencv2/opencv.hpp"
     2 #include<iostream>
     3 using namespace std;
     4 using namespace cv;
     5 
     6 void main()
     7 {
     8     Mat srcImg = imread("E://qrcode.jpg");
     9     imshow("src", srcImg);
    10     Mat dstImg = srcImg.clone();
    11     GaussianBlur(srcImg, srcImg, Size(3, 3), 0, 0);
    12     cvtColor(srcImg, srcImg, CV_BGR2GRAY);
    13     Canny(srcImg, srcImg, 100, 200);//因为原图比较复杂,所以需要将canny的值调大,去除不想要的成分
    14     //threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY_INV); //二值化也可以实现canny效果,不过在本例中杂絮较多
    15     imshow("canny", srcImg);
    16     Mat element = getStructuringElement(MORPH_RECT, Size(11, 11), Point(-1, -1)); //定义结构元素
    17     dilate(srcImg, srcImg, element); //膨胀
    18     imshow("dilate", srcImg);
    19     erode(srcImg, srcImg, element);
    20     imshow("erode", srcImg);
    21 
    22     vector<vector<Point>> contours;
    23     vector<Vec4i> hierarcy;
    24     findContours(srcImg, contours, hierarcy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
    25     vector<Rect> boundRect(contours.size());
    26     vector<RotatedRect> box(contours.size());
    27     Point2f rect[4];
    28     for(int i=0; i<contours.size(); i++)
    29     {
    30         box[i] = minAreaRect(Mat(contours[i]));
    31         boundRect[i] = boundingRect(Mat(contours[i]));
    32 
    33         if(box[i].size.width < 100 || box[i].size.height<100)//筛选
    34             continue;
    35         rectangle(dstImg, Point(boundRect[i].x, boundRect[i].y), Point(boundRect[i].x + boundRect[i].width, boundRect[i].y + boundRect[i].height), Scalar(0, 255, 0), 2, 8);
    36         circle(dstImg, Point(box[i].center.x, box[i].center.y), 5, Scalar(0, 255, 0), -1, 8);
    37         box[i].points(rect);
    38         for(int j=0; j<4; j++)
    39         {
    40             line(dstImg, rect[j], rect[(j+1)%4], Scalar(0, 0, 255), 2, 8);
    41         }
    42 
    43         float angle;
    44         cout<<"angle="<<box[i].angle<<endl;
    45         angle = box[i].angle;
    46         char width[20], height[20];
    47         sprintf(width, "width=%0.2f", box[i].size.width);
    48         sprintf(height, "height=%0.2f", box[i].size.height);
    49         putText(dstImg, width, Point(195, 260), CV_FONT_HERSHEY_COMPLEX_SMALL, 0.85, Scalar(0, 255, 0));
    50         putText(dstImg, height, Point(190, 285), CV_FONT_HERSHEY_COMPLEX_SMALL, 0.85, Scalar(0, 255, 0));
    51         imshow("temp", dstImg);
    52 
    53         //利用仿射变换进行旋转        另一种方法,透视变换
    54         if (0< abs(angle) && abs(angle)<=45)
    55             angle = angle;//负数,顺时针旋转
    56         else if (45< abs(angle) && abs(angle)<90)
    57             angle = 90 -  abs(angle);//正数,逆时针旋转
    58         Point2f center = box[i].center;  //定义旋转中心坐标
    59         double angle0 = angle;
    60         double scale = 1;
    61         Mat roateM = getRotationMatrix2D(center, angle0, scale);  //获得旋转矩阵,顺时针为负,逆时针为正
    62         warpAffine(dstImg, dstImg, roateM, dstImg.size()); //仿射变换
    63 
    64         //保存二维码
    65         int x0=0, y0=0, w0=0, h0=0;
    66         x0 = boundRect[i].x;
    67         y0 = boundRect[i].y;
    68         w0 = boundRect[i].width;
    69         h0 = boundRect[i].height;
    70         Mat ROI = dstImg(Rect(x0, y0, w0, h0));
    71         imwrite("F://1.jpg", ROI);
    72     }
    73     imshow("dst", dstImg);
    74     waitKey(0);
    75 }

     

  • 相关阅读:
    gRPC错误码 http状态码 provide your APIs in both gRPC and RESTful style at the same time
    rust
    lz4 1
    剖析美团内部所采用的网站压力测试方案
    【NOIP2002提高组T4】矩形覆盖-DFS剪枝
    【NOIP2002提高组T4】矩形覆盖-DFS剪枝
    【POJ2777】Count Color-线段树区间更新
    【POJ2777】Count Color-线段树区间更新
    【NOIP2005提高组T3】篝火晚会-置换群
    【NOIP2005提高组T3】篝火晚会-置换群
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/14334242.html
Copyright © 2011-2022 走看看