组合图像中的重叠组
Combining overlapping groups in an image
我正在使用 opencv_contrib 来检测图像中的文本区域。
这是原图
这是找到文本区域后的图像:
可以看出,图像中存在重叠组。例如,Hello World
周围似乎有两组,Some more sample text
周围有两组
问题
在这样的场景中,我如何通过合并两个盒子来保持尽可能宽的盒子。对于这些示例,以 H
开头并以 d
结尾,以便它涵盖 Hello World
。我这样做的原因是我想裁剪部分图像并将其发送到 tesseract。
下面是绘制方框的相关代码。
void groups_draw(Mat &src, vector<Rect> &groups)
{
for (int i=(int)groups.size()-1; i>=0; i--)
{
if (src.type() == CV_8UC3)
rectangle(src,groups.at(i).tl(),groups.at(i).br(),Scalar( 0, 255, 255 ), 2, 8 );
}
}
这是我试过的方法。我的想法在评论中。
void groups_draw(Mat &src, vector<Rect> &groups)
{
int previous_tl_x = 0;
int previous_tl_y = 0;
int prevoius_br_x = 0;
int previous_br_y = 0;
//sort the groups from lowest to largest.
for (int i=(int)groups.size()-1; i>=0; i--)
{
//if previous_tl_x is smaller than current_tl_x then keep the current one.
//if previous_br_x is smaller than current_br_x then keep the current one.
if (src.type() == CV_8UC3) {
//crop the image
Mat cropedImage = src(Rect(Point(groups.at(i).tl().x, groups.at(i).tl().y),Point(groups.at(i).br().x, groups.at(i).br().y)));
imshow("cropped",cropedImage);
waitKey(-1);
}
}
}
更新
我正在尝试使用 [groupRectangles][4]
来完成此操作:
void groups_draw(Mat &src, vector<Rect> &groups)
{
vector<Rect> rects;
for (int i=(int)groups.size()-1; i>=0; i--)
{
rects.push_back(groups.at(i));
}
groupRectangles(rects, 1, 0.2);
}
但是,这给我一个错误:
textdetection.cpp:106:5: error: use of undeclared identifier 'groupRectangles'
groupRectangles(rects, 1, 0.2);
^
1 error generated.
一种方法是将每个矩形与其他每个矩形进行比较,看它们是否重叠或相交。如果它们足够多,您可以将它们组合成一个更大的矩形。
首先,您得到重叠边界框的原因是文本检测器模块在反转通道上工作(例如:灰色和反转灰色),因此某些字符(例如 o 和 g )的内部区域是错误的检测并分组为字符。因此,如果您只想检测一种文本模式(深色背景上的白色文本),只需通过倒置通道即可。
替换:
for (int c = 0; c < cn-1; c++)
channels.push_back(255-channels[c]);
有:
for (int c = 0; c < cn-1; c++)
channels[c] = (255-channels[c]);
现在回答你的问题,矩形已经定义了交集和组合运算符:
rect = rect1 & rect2 (rectangle intersection)
rect = rect1 | rect2 (minimum area rectangle containing rect2 and rect3 )
rect &= rect1, rect |= rect1 (and the corresponding augmenting operations)
您可以在遍历矩形时使用这些运算符来检测相交的矩形并将它们组合起来,如下所示:
if ((rect1 & rect2).area() != 0)
rect1 |= rect2;
编辑:
首先,按面积从大到小对矩形组进行排序:
std::sort(groups.begin(), groups.end(),
[](const cv::Rect &rect1, const cv::Rect &rect2) -> bool {return rect1.area() > rect2.area();});
然后,遍历矩形,当两个矩形相交时,将较小的添加到较大的,然后将其删除:
for (int i = 0; i < groups.size(); i++)
{
for (int j = i + 1; j < groups.size(); j++)
{
if ((groups[i] & groups[j]).area() != 0)
{
groups[i] |= groups[j];
groups.erase(groups.begin() + j--);
}
}
}
我正在使用 opencv_contrib 来检测图像中的文本区域。
这是原图
这是找到文本区域后的图像:
可以看出,图像中存在重叠组。例如,Hello World
周围似乎有两组,Some more sample text
问题
在这样的场景中,我如何通过合并两个盒子来保持尽可能宽的盒子。对于这些示例,以 H
开头并以 d
结尾,以便它涵盖 Hello World
。我这样做的原因是我想裁剪部分图像并将其发送到 tesseract。
下面是绘制方框的相关代码。
void groups_draw(Mat &src, vector<Rect> &groups)
{
for (int i=(int)groups.size()-1; i>=0; i--)
{
if (src.type() == CV_8UC3)
rectangle(src,groups.at(i).tl(),groups.at(i).br(),Scalar( 0, 255, 255 ), 2, 8 );
}
}
这是我试过的方法。我的想法在评论中。
void groups_draw(Mat &src, vector<Rect> &groups)
{
int previous_tl_x = 0;
int previous_tl_y = 0;
int prevoius_br_x = 0;
int previous_br_y = 0;
//sort the groups from lowest to largest.
for (int i=(int)groups.size()-1; i>=0; i--)
{
//if previous_tl_x is smaller than current_tl_x then keep the current one.
//if previous_br_x is smaller than current_br_x then keep the current one.
if (src.type() == CV_8UC3) {
//crop the image
Mat cropedImage = src(Rect(Point(groups.at(i).tl().x, groups.at(i).tl().y),Point(groups.at(i).br().x, groups.at(i).br().y)));
imshow("cropped",cropedImage);
waitKey(-1);
}
}
}
更新
我正在尝试使用 [groupRectangles][4]
来完成此操作:
void groups_draw(Mat &src, vector<Rect> &groups)
{
vector<Rect> rects;
for (int i=(int)groups.size()-1; i>=0; i--)
{
rects.push_back(groups.at(i));
}
groupRectangles(rects, 1, 0.2);
}
但是,这给我一个错误:
textdetection.cpp:106:5: error: use of undeclared identifier 'groupRectangles'
groupRectangles(rects, 1, 0.2);
^
1 error generated.
一种方法是将每个矩形与其他每个矩形进行比较,看它们是否重叠或相交。如果它们足够多,您可以将它们组合成一个更大的矩形。
首先,您得到重叠边界框的原因是文本检测器模块在反转通道上工作(例如:灰色和反转灰色),因此某些字符(例如 o 和 g )的内部区域是错误的检测并分组为字符。因此,如果您只想检测一种文本模式(深色背景上的白色文本),只需通过倒置通道即可。 替换:
for (int c = 0; c < cn-1; c++)
channels.push_back(255-channels[c]);
有:
for (int c = 0; c < cn-1; c++)
channels[c] = (255-channels[c]);
现在回答你的问题,矩形已经定义了交集和组合运算符:
rect = rect1 & rect2 (rectangle intersection)
rect = rect1 | rect2 (minimum area rectangle containing rect2 and rect3 )
rect &= rect1, rect |= rect1 (and the corresponding augmenting operations)
您可以在遍历矩形时使用这些运算符来检测相交的矩形并将它们组合起来,如下所示:
if ((rect1 & rect2).area() != 0)
rect1 |= rect2;
编辑:
首先,按面积从大到小对矩形组进行排序:
std::sort(groups.begin(), groups.end(),
[](const cv::Rect &rect1, const cv::Rect &rect2) -> bool {return rect1.area() > rect2.area();});
然后,遍历矩形,当两个矩形相交时,将较小的添加到较大的,然后将其删除:
for (int i = 0; i < groups.size(); i++)
{
for (int j = i + 1; j < groups.size(); j++)
{
if ((groups[i] & groups[j]).area() != 0)
{
groups[i] |= groups[j];
groups.erase(groups.begin() + j--);
}
}
}