您的位置:首页 > 运维架构

OpenCV学习笔记】二十七、轮廓特征属性及应用(四)——正外接矩形

2017-10-25 20:49 531 查看
 


【OpenCV学习笔记】二十七、轮廓特征属性及应用(四)——正外接矩形

标签: OpenCV图像处理
2017-04-01 14:35 945人阅读 评论(2) 收藏 举报


 分类:

OpenCV学习笔记(41) 


版权声明:本文为博主原创文章,未经博主允许不得转载。

轮廓特征属性及应用(四)——正外接矩形

1.轮廓正外接矩形——boundingRect()

2.完成了三个小应用:正外接矩形的查找绘制、分割硬币轮廓、简单车牌字符分割

先上ppt:









代码:

正外接矩形的查找绘制:

[cpp] view
plain copy

///正外接矩形的查找绘制  

#include "opencv2/opencv.hpp"  

using namespace cv;  

#include <iostream>  

using namespace std;  

int main()  

{  

    //1.查找轮廓  

    //1.1查找轮廓前的预处理(灰度图,阈值化)  

    Mat srcImg = imread("12.jpg",CV_LOAD_IMAGE_COLOR);  

    imshow("srcImg", srcImg);  

    Mat copyImg = srcImg.clone();  

    cvtColor(srcImg,srcImg,CV_BGR2GRAY);  

    threshold(srcImg,srcImg,100,255,CV_THRESH_BINARY);  

    imshow("threshold",srcImg);  

    vector <vector<Point>> contours;  

    vector<Vec4i> hierarcy;//没用到  

    //1.2查找轮廓  

    findContours(srcImg,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);//最外层轮廓  

    //1.3绘制所有轮廓  

    drawContours(copyImg,contours,-1,Scalar(0,255,0),1,8);  

    //2.由轮廓确定正外接矩形  

    int width = 0;  

    int height = 0;  

    int x = 0;  

    int y = 0;  

    //2.1 定义Rect类型的vector容器boundRect存放正外接矩形,初始化大小为contours.size()即轮廓个数  

    vector<Rect> boundRect(contours.size());  

    //2.2 遍历每个轮廓  

    for (int i = 0; i < contours.size(); i++)  

    {  

        //2.3由轮廓(点集)确定出正外接矩形  

        boundRect[i] = boundingRect(Mat(contours[i]));  

        //2.4获得正外接矩形的左上角坐标及宽高  

        width = boundRect[i].width;  

        height = boundRect[i].height;  

        x = boundRect[i].x;  

        y = boundRect[i].y;  

        //2.5用画矩形方法绘制正外接矩形  

        rectangle(copyImg,Rect(x,y,width,height),Scalar(0,0,255),1,8);  

    }  

    imshow("轮廓和正外接矩形", copyImg);  

    waitKey(0);  

    return 0;  

}  

运行结果:



分割硬币轮廓:

[cpp] view
plain copy

///分割硬币轮廓  

#include "opencv2/opencv.hpp"  

using namespace cv;  

#include <iostream>  

using namespace std;  

int main()  

{  

    //1.查找轮廓  

    //1.1查找轮廓前的预处理(灰度图,阈值化)  

    Mat srcImg = imread("33.png",CV_LOAD_IMAGE_COLOR);  

    imshow("srcImg", srcImg);  

    Mat copyImg = srcImg.clone();  

    cvtColor(srcImg,srcImg,CV_BGR2GRAY);  

    threshold(srcImg,srcImg,100,255,CV_THRESH_BINARY);  

    imshow("threshold",srcImg);  

    //*1.2增加了膨胀和腐蚀  

    //因为有一个轮廓有断点,导致外接矩形是两个小的而不是一个整的,故要膨胀,将断点连起来  

    //1.2.1定义kernel  

    Mat kernel = getStructuringElement(MORPH_RECT,Size(5,5),Point(-1,-1));  

    //1.2.2膨胀  

    dilate(srcImg,srcImg,kernel,Point(-1,-1));  

    //1.2.3腐蚀  

    erode(srcImg,srcImg,kernel,Point(-1,-1));  

    imshow("膨胀和腐蚀", srcImg);  

    //1.3查找轮廓  

    vector <vector<Point>> contours;  

    vector<Vec4i> hierarcy;//没用到  

    findContours(srcImg,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);//最外层轮廓  

    //1.4绘制所有轮廓  

    drawContours(copyImg,contours,-1,Scalar(0,255,0),1,8);  

    //2.由轮廓确定正外接矩形  

    int width = 0;  

    int height = 0;  

    int x = 0;  

    int y = 0;  

    //2.1 定义Rect类型的vector容器boundRect存放正外接矩形,初始化大小为contours.size()即轮廓个数  

    vector<Rect> boundRect(contours.size());  

    //2.2 遍历每个轮廓  

    for (int i = 0; i < contours.size(); i++)  

    {  

        //2.3由轮廓(点集)确定出正外接矩形  

        boundRect[i] = boundingRect(Mat(contours[i]));  

        //2.4获得正外接矩形的左上角坐标及宽高  

        width = boundRect[i].width;  

        height = boundRect[i].height;  

        x = boundRect[i].x;  

        y = boundRect[i].y;  

        //*2.5 对正外接矩形进行筛选(过滤掉小的)  

        if (width>40 && height > 40)  

        {  

            //2.6用画矩形方法绘制正外接矩形  

            rectangle(copyImg, Rect(x, y, width, height), Scalar(0, 0, 255), 1, 8);  

        }  

    }  

    imshow("轮廓和正外接矩形", copyImg);  

    waitKey(0);  

    return 0;  

}  

运行结果:



简单车牌字符分割:

[cpp] view
plain copy

///简单车牌字符分割  

#include "opencv2/opencv.hpp"  

using namespace cv;  

#include <iostream>  

using namespace std;  

int main()  

{  

    //1.查找轮廓  

    //1.1查找轮廓前的预处理(灰度图,阈值化)  

    Mat srcImg = imread("Car.jpg", CV_LOAD_IMAGE_COLOR);  

    imshow("srcImg", srcImg);  

    Mat copyImg = srcImg.clone();  

    cvtColor(srcImg, srcImg, CV_BGR2GRAY);  

    threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY);  

    imshow("threshold", srcImg);  

    //1.2查找轮廓  

    vector <vector<Point>> contours;  

    vector<Vec4i> hierarcy;//没用到  

    findContours(srcImg, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);//所有轮廓  

    //1.3绘制所有轮廓  

    drawContours(copyImg, contours, -1, Scalar(0, 255, 0), 1, 8);  

    //2.由轮廓确定正外接矩形  

    int width = 0;  

    int height = 0;  

    int x = 0;  

    int y = 0;  

    //2.1 定义Rect类型的vector容器boundRect存放正外接矩形,初始化大小为contours.size()即轮廓个数  

    vector<Rect> boundRect(contours.size());  

    //2.2 遍历每个轮廓  

    for (int i = 0; i < contours.size(); i++)  

    {  

        //2.3由轮廓(点集)确定出正外接矩形  

        boundRect[i] = boundingRect(Mat(contours[i]));  

        //2.4获得正外接矩形的左上角坐标及宽高  

        width = boundRect[i].width;  

        height = boundRect[i].height;  

        x = boundRect[i].x;  

        y = boundRect[i].y;  

        //*2.5 对正外接矩形进行筛选(过滤掉过小及过大的)  

        if (width>(1.0 / 12)*srcImg.cols && width<(1.0 / 7)*srcImg.cols   

             &&height >(1.0 / 6)*srcImg.rows&& height < (5.0 / 6)*srcImg.rows)  

        {  

            //2.6用画矩形方法绘制正外接矩形  

            rectangle(copyImg, Rect(x, y, width, height), Scalar(0, 0, 255), 1, 8);  

            //*2.7 通过ROI保存分割出的车牌字符  

            //2.7.1 定义ROI  

            Mat ROI = copyImg(Rect(x,y,width,height));  

            //2.7.2 通过sprintf格式化文件存储名name  

            char name[20] = {0};  

            sprintf(name,"E:\\temp\\%d.jpg",i);  

            //2.7.3 写ROI到本地  

            imwrite(name,ROI);  

        }  

    }  

    imshow("轮廓和正外接矩形", copyImg);  

    waitKey(0);  

    return 0;  

}  

运行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: