如何使用OpenCV和C ++通过绑定rect大小来过滤轮廓?

时间:2015-09-17 06:33:25

标签: c++ opencv

我尝试使用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);
}

original

gray

cany_egdes

contours

2 个答案:

答案 0 :(得分:1)

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

   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

这是我的输出: enter image description here

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

答案 1 :(得分:0)

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

#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);

} boundingRect_image