Opencv截取图片里最大的矩形

Opencv截取图片里最大的矩形

1.代码


#include <opencv2/opencv.hpp>  
#include <iostream>  
#include<time.h>
#include<math.h>
#include <iostream>  
#include <set>
using namespace cv;
using namespace std;

RNG rng(12345);
char strangerName[2000];//截取的四边形矩形图片名字
int main()
{
    
    
    Mat srcImageCopy= imread("D:\\vedio\\1.png", 2|4);
    Mat srcImageCopy1= imread("D:\\vedio\\1.png", 2|4);
    Mat srcImage0 = imread("D:\\vedio\\1.png", 0);  
    Mat srcImage = Mat::zeros(srcImage0.rows,srcImage0.cols, CV_8UC3); 
    resize(srcImage0, srcImage, srcImage.size());
    threshold(srcImage,srcImage,150,255,THRESH_BINARY);
    imshow("二值化", srcImage);
    //getStructuringElement函数会返回指定形状和尺寸的结构元素
    Mat element = getStructuringElement(MORPH_RECT, Size(3, 3));
    //morphologyEx(srcImage, srcImage, MORPH_CLOSE, element);//闭运算滤波
    vector<vector<Point>> contours, RectContours,contoursMax;//轮廓,为点向量,
    findContours(srcImage, contours, RETR_LIST, CHAIN_APPROX_NONE);//找轮廓
    vector<vector<Point>> hull(contours.size());//用于存放凸包
    Mat drawing(srcImage.size(), CV_8UC3, cv::Scalar(0));
    int i = 0;
    int num[100];
    int sum = 0;
    double Length=0;
    vector<float> length(contours.size());//用于保存每个轮廓的长度
    vector<float> Area_contours(contours.size()), Area_hull(contours.size()), Rectangularity(contours.size()), circularity(contours.size());
    for (i = 0; i < contours.size(); i++)
    {
    
    //把所有的轮廓画出来
        Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
        length[i] = arcLength(contours[i], true);//轮廓的长度
        
        if (length[i] > 200)
        {
    
    //通过长度匹配滤除小轮廓
         if (length[i]>=Length)
         {
    
    
            convexHull(Mat(contours[i]), hull[i], false);//把凸包找出来,寻找凸包函数
            Area_contours[i] = contourArea(contours[i]);   //轮廓面积
            Area_hull[i] = contourArea(hull[i]);           //凸包面积
            Rectangularity[i] = Area_contours[i] / Area_hull[i]; //矩形度
            if (Rectangularity[i] > 0.85)
            {
    
    
                //通过矩形度和圆形度滤除数字 
                //Length = arcLength(contours[i], true);
                num [sum]= i;
                if (sum > 0)
                {
    
    
                    if (arcLength(contours[num[sum]], true)> arcLength(contours[num[sum-1]], true))
                    {
    
    
                        Length = arcLength(contours[i], true);
                        sum++;
                    }        
                }
                else 
                {
    
    
                    Length = arcLength(contours[i], true);
                    sum++;
                }           
                drawContours(drawing, hull, i, color, 1);
                drawContours(srcImageCopy, hull, i, color, 1); //得到四边形
            }
        }
        }
    }
    if ((sum - 1 )> 0) 
    {
    
    
     RectContours.push_back(hull[num[sum - 1]]);//把提取出来的方框导入到新的轮廓组
    }
    else 
    {
    
    
        cout << "无匹配";
        return 0;
    }
    imshow("原图",srcImageCopy);
  
    // 多边形逼近轮廓 + 获取矩形和圆形边界框
    vector<vector<Point> > contours_poly(RectContours.size());
    vector<Rect> boundRect(RectContours.size()); //最小矩形
 
    //一个循环,遍历所有部分,进行本程序最核心的操作
    for (unsigned int i = 0; i < RectContours.size(); i++)
    {
    
    
        approxPolyDP(RectContours[i], contours_poly[i], 3, true);//用指定精度逼近多边形曲线 
        boundRect[i] = boundingRect(Mat(contours_poly[i]));//计算点集的最外面(up-right)矩形边界
    }
    // 绘制多边形轮廓 + 包围的矩形框 
    Mat drawing1 = Mat::zeros(srcImage.size(), CV_8UC3);
    Mat image_cut[100];      //从img中按照rect进行切割,此时修改image_cut时image中对应部分也会修改,因此需要copy  
    Mat image_copy[100];   //clone函数创建新的图片 
    int geshu = 0;
    for (int unsigned i = 0; i < RectContours.size(); i++)
    {
    
    
        Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));//随机设置颜色
        Point text_lb;//中点
        geshu++;
        rectangle(drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0);//绘制矩形
        text_lb = Point((boundRect[i].tl().x + boundRect[i].br().x) * 0.5, (boundRect[i].tl().y + boundRect[i].br().y) * 0.5);
        //putTextZH(drawing, "中点", center[i], Scalar(0, 0, 255), 10, "Arial");
        int width = abs(boundRect[i].tl().x - boundRect[i].br().x);
        int height = abs(boundRect[i].tl().y - boundRect[i].br().y);
        Rect rect(boundRect[i].tl().x+35, boundRect[i].tl().y+35, width-70, height-70);   //创建一个Rect框,属于cv中的类,四个参数代表x,y,width,height  
        image_cut[i] = Mat(srcImageCopy1, rect);      //从img中按照rect进行切割,此时修改image_cut时image中对应部分也会修改,因此需要copy  
        image_copy[i] = image_cut[i].clone();   //clone函数创建新的图片  
        sprintf_s(strangerName, "数字%d", geshu);
        namedWindow(strangerName, WINDOW_AUTOSIZE);//参数为零,则可以自由拖动strangerName
        imshow(strangerName, image_copy[i]);
    }
    namedWindow("找到四边形外接矩形", 1);
    imshow("找到四边形外接矩形", drawing);
    waitKey(0);
    return 0;
}


2效果

原图:
原图二值化:
二值化截取图:
截取图完整工程项目代码:https://download.csdn.net/download/m0_45866718/12819697

猜你喜欢

转载自blog.csdn.net/m0_45866718/article/details/108127114
今日推荐