Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 删除带有区域的边界矩形<;n OpenCV_C++_Opencv_Bounding Box - Fatal编程技术网

C++ 删除带有区域的边界矩形<;n OpenCV

C++ 删除带有区域的边界矩形<;n OpenCV,c++,opencv,bounding-box,C++,Opencv,Bounding Box,我正在腐蚀一个带有文本块的图像,然后使用findContours()查找所有文本块,然后绘制它们的边界矩形。然而,有时图像中的噪声会产生非常小的矩形,它们要么位于较大的矩形中,要么位于没有文本的位置 我正在使用这段代码找到轮廓并绘制它们 double element_size = 20; RNG rng(12345); Mat element = getStructuringElement( cv::MORPH_ELLIPSE,cv::Size( 2*element_size + 1, 2*el

我正在腐蚀一个带有文本块的图像,然后使用
findContours()
查找所有文本块,然后绘制它们的边界矩形。然而,有时图像中的噪声会产生非常小的矩形,它们要么位于较大的矩形中,要么位于没有文本的位置

我正在使用这段代码找到轮廓并绘制它们

double element_size = 20;
RNG rng(12345);
Mat element = getStructuringElement( cv::MORPH_ELLIPSE,cv::Size( 2*element_size + 1, 2*element_size+1 ),cv::Point( element_size, element_size ) );
erode(quad, quad, element);
vector<vector<cv::Point> > contours;
vector<Vec4i> hierarchy;
quad.convertTo(quad, CV_8UC1);
findContours( quad, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0) );

vector<vector<cv::Point> > contours_poly( contours.size() );
vector<cv::Rect> boundRect( 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]) );
}

Mat drawing = Mat::zeros( quad.size(), CV_8UC3 );
for( int i = 0; i< contours.size(); i++ )
{
    Scalar color = Scalar(0,255, 0 );
    rectangle( drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0 );
}
double-element\u size=20;
RNG RNG(12345);
Mat元素=getStructuringElement(cv::变形椭圆,cv::大小(2*元素大小+1,2*元素大小+1),cv::点(元素大小,元素大小));
侵蚀(四边形、四边形、元素);
矢量等值线;
向量层次;
四路转换器(四路,CV_8UC1);
findContours(四边形、等高线、层次、CV_RETR_树、CV_链_近似_简单、CV::Point(0,0));
向量等高线_多边形(等高线.size());
向量boundRect(contours.size());
对于(int i=0;i
运行示例后,我得到的结果如下:

如何修改我的代码,以便删除任何不大于
n
的矩形,这样我只能保留完整的文本块,我还需要删除包围整个卡片的最大轮廓。

Yo可以用来消除轮廓,在找到边界矩形之前使用下面的代码,这将删除面积小于阈值的所有轮廓

double min_area=100; // area threshold

 for( int i = 0; i< contours.size(); i++ ) // iterate through each contour.
 {
   double area=contourArea( contours[i],false);  //  Find the area of contour
   if(area<min_area)
    contours.erase(contours.begin() + i);
 }
双最小面积=100;//面积阈值
对于(int i=0;i
double min_area=100; // area threshold

 for( int i = 0; i< contours.size(); i++ ) // iterate through each contour.
 {
   double area=contourArea( contours[i],false);  //  Find the area of contour
   if(area<min_area)
    contours.erase(contours.begin() + i);
 }
double min\u area=100;//面积阈值
对于(int i=0;i如果(area要获得从
向量
中删除
cv::Rect
元素的更安全方法,您可以使用删除低于某个区域阈值的元素。此方法比按索引逐个删除元素(如Haris的回答)安全得多,因为您不会冒着离开向量末尾的风险

boundRect.erase(std::remove_if(boundRect.begin(), boundRect.end(),
                               [] (cv::Rect r)
                               {
                                   const int min_area = 100;
                                   return r.area() < min_area;
                               }), boundRect.end());
boundRect.erase(std::remove_if(boundRect.begin(),boundRect.end(),
[](cv::Rect r)
{
最小面积常数=100;
返回右面积()<最小面积;
}),boundRect.end());
这里我使用C++11 lambda进行比较。如果没有C++11,那么创建一个函子类就足够简单了

至于删除最大轮廓,您可以使用标准库中的另一个函数(再次使用lambda进行比较):

boundRect.erase(std::max_元素(boundRect.begin(),boundRect.end(),
[](cv::Rect left,cv::Rect right)
{
返回left.area()
要获得从
向量
中删除
cv::Rect
元素的更安全方法,您可以使用删除低于某个区域阈值的元素。此方法比按索引逐个删除元素(如Haris的回答)安全得多,因为您不会冒着离开向量末尾的风险

boundRect.erase(std::remove_if(boundRect.begin(), boundRect.end(),
                               [] (cv::Rect r)
                               {
                                   const int min_area = 100;
                                   return r.area() < min_area;
                               }), boundRect.end());
boundRect.erase(std::remove_if(boundRect.begin(),boundRect.end(),
[](cv::Rect r)
{
最小面积常数=100;
返回右面积()<最小面积;
}),boundRect.end());
这里我使用C++11 lambda进行比较。如果没有C++11,那么创建一个函子类就足够简单了

至于删除最大轮廓,您可以使用标准库中的另一个函数(再次使用lambda进行比较):

boundRect.erase(std::max_元素(boundRect.begin(),boundRect.end(),
[](cv::Rect left,cv::Rect right)
{
返回left.area()<代码>在C++中,将项目删除或插入到C++<代码> STD::vector < /代码>中是不安全的。在代码中,您有三种选择:(1)向后迭代,这样,删除项不会导致尚未处理的项的索引移位;(2)将要保留的项目复制到新的
向量中,或(3)将布尔结果存储在一个单独的标志向量中,这样下次你就可以使用两个向量来过滤项目。@ Rang.感谢信息。在代码中完成的循环中,将项目擦除或插入到C++ +代码> STD::向量< /代码>中是不安全的。你有三个选择:(1)向后迭代,以便删除项不会导致尚未处理项的索引移动;(2)将要保留的项复制到新的
向量中,或(3)将布尔结果存储在一个单独的标志向量中,以便下次您可以使用这两个向量来筛选项目。@rwong感谢您提供的信息。那么第一个代码段是否会删除
min_区域
下方的所有矩形?我对C++11的这些功能不是很熟悉。在
for loo之后使用代码段时包含