【问题标题】:How to filter contours by bounding rect size using OpenCV and C++?如何通过使用 OpenCV 和 C++ 限制矩形大小来过滤轮廓?
【发布时间】:2015-12-13 22:36:26
【问题描述】:

我尝试使用 OpenCV 和 C++ 从图像中检测车牌。我可以找到车牌的轮廓。但我只想放弃车牌。我有一个想法通过限制矩形大小来过滤轮廓。

这是我的代码:

#include <opencv\cv.h>
#include <opencv\highgui.h>
#include <opencv\ml.h>
#include <opencv\cxcore.h>

#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include <stdio.h>
#include <stdlib.h>
#include<iostream>
using namespace cv;
using namespace std;
cv::Mat _img;       
cv::Mat _imgGray;       
int main()
{
    _img = cv::imread("bs9.jpg");           
    if (_img.empty()) {                                 
    std::cout << "error: image not read from file\n\n";     
    return(0);                                              
}
cv::Mat src;
medianBlur(_img, src, 9);

// chuyển ảnh gốc sang ảnh xám
cv::cvtColor(src, _imgGray, CV_BGR2GRAY);
cv::Mat _imgGray2;
medianBlur(_imgGray, _imgGray2, 7);
blur(_imgGray2, _imgGray2, Size(3, 3));
//Canny
cv::Mat edges;
//dalation

//cv::Canny(_imgGray, edges, 100, 250);
cv::Canny(_imgGray2, edges, 100, 200, 3);
//contour
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
//
//vector<Rect> boundRect(contours.size());
//CvMemStorage* stor = cvCreateMemStorage(1000);
findContours(edges, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
// vẽ đường bao các cạnh

Mat drawing = Mat::zeros(edges.size(), CV_8UC3);
for (int i = 0; i < contours.size(); i++)
{
    Scalar color = Scalar(0,255,0);
    drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point());     
}
//filter contour
????
/// show image
cv::imshow("Goc", _img);        // show ảnh gốc
//
//cv::namedWindow("Anh xam", CV_WINDOW_AUTOSIZE);
cv::imshow("Xam", _imgGray);        // show ảnh xám
cv::imshow("edges", edges);     // show ảnh Canny
cv::imshow("contours", drawing);
cv::waitKey(0);                 
return(0);
}

【问题讨论】:

    标签: c++ opencv


    【解决方案1】:

    您可以使用opencv中的boundingRect(或某些版本的boundingBox)函数来提取轮廓的边界框。

       int w_threshold = 100;
        int h_threshold = 100;
        vector<int> selected;
        for (int i = 0; i < contours.size(); i++)
        {
            Scalar color = Scalar(0, 255, 0);
            Rect R = boundingRect(contours[i]);
            // filter contours according to their bounding box
            if (R.width > w_threshold && R.height > h_threshold)
            {
                selected.push_back(i);
                drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point());
            }
        }
        //filter contour
            /// show image
            cv::imshow("Goc", _img);        // show ảnh gốc
            for (size_t i = 0; i < selected.size(); i++)
            {
                rectangle(_img, boundingRect(contours[selected[i]]), Scalar(0, 0, 255), 5);
            }
            cv::imshow("license candidates", _img);        // show ảnh xám
    

    这是我的输出:

    您也可以使用 cvBlobLibs 库。它具有简单的功能,可以像您想要的那样操作 blob。

    【讨论】:

    • 感谢您的帮助。但是如果我想过滤车牌的宽度和高度(宽度/高度)的基本比例。我想会有更准确的。请帮我解决一下这个。 @阿里米尔扎伊
    【解决方案2】:

    这是我的更新代码。我想用宽高比过滤轮廓。

    #include <opencv\cv.h>
    #include <opencv\highgui.h>
    #include <opencv\ml.h>
    #include <opencv\cxcore.h>
    #include<opencv2/core/core.hpp>
    #include<opencv2/highgui/highgui.hpp>
    #include<opencv2/imgproc/imgproc.hpp>
    #include <opencv2\imgcodecs.hpp>
    #include <stdio.h>
    #include <stdlib.h>
    #include<iostream>
    using namespace cv;
    using namespace std;
    //khai báo biến
    cv::Mat _img;       // ảnh gốc
    cv::Mat _imgGray;       // ảnh xám
    //hàm main
    int main()
    {
       _img = cv::imread("bs9.jpg");            
       if (_img.empty()) {                                  
       std::cout << "error: image not read from file\n\n";      
       return(0);                                               
    }
    cv::Mat src;
    medianBlur(_img, src, 9);
    
    // chuyển ảnh gốc sang ảnh xám
    cv::cvtColor(src, _imgGray, CV_BGR2GRAY);
    cv::Mat _imgGray2;
    medianBlur(_imgGray, _imgGray2, 7);
    blur(_imgGray2, _imgGray2, Size(3, 3));
    //Canny
    cv::Mat edges;
    //dalation
    
    //cv::Canny(_imgGray, edges, 100, 250);
    cv::Canny(_imgGray2, edges, 100, 200, 3);
    //contour
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    findContours(edges, contours, hierarchy, CV_RETR_TREE,  CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
    //mới
    vector<vector<Point> > contours_poly(contours.size());
    vector<Rect> boundRect(contours.size());
    vector<Point2f> ContArea(contours.size());
    for (int i = 0; i < contours.size(); i++)
    {
            approxPolyDP(Mat(contours[i]), contours_poly[i], 3, true);
            boundRect[i] = boundingRect(Mat(contours_poly[i]));
    
    }
    //mới
    // vẽ đường bao các cạnh
    Mat drawing = Mat::zeros(edges.size(), CV_8UC3);
    //vector<Rect> boundRect(contours.size());
    for (int i = 0; i < contours.size(); i++)
    {
        Scalar color = Scalar(0,255,0);
        //drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point());   
        drawContours(drawing, contours_poly, (int)i, color, 1, 8, vector<Vec4i>(), 0, Point());
        rectangle(drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0);
    }
    //filter contour
    
    /// show image
    cv::imshow("Goc", _img);        // show ảnh gốc
    //
    cv::imshow("Xam", _imgGray);        // show ảnh xám
    cv::imshow("edges", edges);     // show ảnh Canny
    cv::imshow("contours", drawing);
    cv::waitKey(0);                 
    return(0);
    

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-22
      • 2021-09-01
      • 2018-02-13
      • 2017-04-27
      • 2021-11-19
      • 2019-12-03
      • 1970-01-01
      相关资源
      最近更新 更多