【转载】项目实战—文档区域MSER检测实战(十)

article/2025/9/13 1:35:50

上次已经讨论过相关的理论,这次我们来进行相关的实战。

OCR相关工作都有一个第一步,那就是检测图像中的文本区域,只有找到了文本区域,才能对其内容进行识别,也只有找到了文本区域,才能更有针对性地判断该文本图像的质量好坏,我们期望达到如下的文本区域检测效果:
在这里插入图片描述
MSER对一幅已经处理成灰度的图像做二值化处理,这个处理的阈值从0到255递增,这个阈值的递增类似于在一片土地上做水平面的上升,随着水平面上升,高高低低凹凸不平的土地区域就会不断被淹没,这就是分水岭算法,而这个高低不同,就是图像中灰度值的不同。而在一幅含有文字的图像上,有些区域(比如文字)由于颜色(灰度值)是一致的,因此在水平面(阈值)持续增长的一段时间内都不会被覆盖,直到阈值涨到文字本身的灰度值时才会被淹没,这些区域就叫做最大稳定极值区域。

该算法可以用来粗略地寻找图像中的文字区域,虽然算法思想简单,但要做到效果又快又好还是需要一定基础的,好在opencv直接提供了该算法的接口,它使用了一种比算法作者要快的实现方式,一般来说我们只用知道怎么用它就行了。

要使用也比较简单:

view plaincopy to clipboardprint?
import cv2  
img = cv2.imread('img1.png')  
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 得到灰度图  
mser = cv2.MSER_create() # 得到mser算法对象  
regions, _ = mser.detectRegions(gray) # 获取文本区域  
hulls = [cv2.convexHull(p.reshape(-1, 1, 2)) for p in regions] # 绘制文本区域  
cv2.polylines(img, hulls, 1, (0, 255, 0))  
cv2.namedWindow("img",0)  
cv2.resizeWindow("img", 800, 640) # 限定显示图像的大小  
cv2.imshow('img', img)  
cv2.waitKey(0) # 显示图像直到按键盘任意键  
cv2.destroyAllWindows()  

在这里插入图片描述
但是上面效果中的文本框形状太多变了,我们检测文本区域一般都会设法得到一个包含文本的矩形框,以便于后续从图像中通过坐标获取该区域,那怎么把这些区域转换成矩形框呢?我们借用opencv的“cv2.boundingRect”和“cv2.rectangle”函数就可以了:

# 绘制目前的矩形文本框view plaincopy to clipboardprint?
vis = img.copy()  
for c in hulls:  x, y, w, h = cv2.boundingRect(c)  cv2.rectangle(vis, (x, y), (x + w, y + h), (255, 255, 0), 1)             
cv2.namedWindow("hulls",0)  
cv2.resizeWindow("hulls", 800, 640)  
cv2.imshow("hulls", vis)  
cv2.waitKey(0)  
cv2.destroyAllWindows()  

于是有结果:
在这里插入图片描述
但问题又出现了,这么多矩形框,而且还互相包含,很明显很多框是没有必要的,要全部处理也很麻烦,能不能去掉重复的矩形框呢?这就要用到NMS算法了。

NMS是经常伴随图像区域检测的算法,作用是去除重复的区域,在人脸识别、物体检测等领域都经常使用,全称是非极大值抑制(non maximum suppression),顾名思义就是抑制不是极大值的元素,所以用在这里就是抑制不是最大框的框,也就是去除大框中包含的小框。

NMS的基本思想是遍历将所有的框得分排序,选中其中得分最高的框,然后遍历其余框找到和当前最高分的框的重叠面积(IOU)大于一定阈值的框,删除。然后继续这个过程,找另一个得分高的框,再删除IOU大于阈值的框,循环。

在这个例子中,就是设定一个IOU阈值(比如0.5,也就是如果两个框的重叠面积大于其中一个框的50%,那么就删除那个框),然后遍历所有框,对剩下的每个框,遍历判断其余框中与他重叠面积大于阈值的,则删除。最后剩下的就是不包含重叠部分的文本框了。

view plaincopy to clipboardprint?
def non_max_suppression_fast(boxes, overlapThresh):  # 空数组检测  if len(boxes) == 0:  return []  # 将类型转为float  if boxes.dtype.kind == "i":  boxes = boxes.astype("float")  pick = []  # grab the coordinates of the bounding boxes  # 四个坐标数组  x1 = boxes[:,0]  y1 = boxes[:,1]  x2 = boxes[:,2]  y2 = boxes[:,3]  area = (x2 - x1 + 1) * (y2 - y1 + 1) # 计算面积数组  idxs = np.argsort(y2) # 返回的是右下角坐标从小到大的索引值  # 开始遍历删除重复的框  while len(idxs) > 0:  # 将最右下方的框放入pick数组  last = len(idxs) - 1  i = idxs[last]  pick.append(i)  # 找到剩下的其余框中最大的坐标x1y1,和最小的坐标x2y2,  xx1 = np.maximum(x1[i], x1[idxs[:last]])  yy1 = np.maximum(y1[i], y1[idxs[:last]])  xx2 = np.minimum(x2[i], x2[idxs[:last]])  yy2 = np.minimum(y2[i], y2[idxs[:last]])  # 计算重叠面积占对应框的比例  w = np.maximum(0, xx2 - xx1 + 1)  h = np.maximum(0, yy2 - yy1 + 1)  overlap = (w * h) / area[idxs[:last]]  # 如果占比大于阈值,则删除  idxs = np.delete(idxs, np.concatenate(([last], np.where(overlap > overlapThresh)[0])))  return boxes[pick].astype("int")  pick = non_max_suppression_fast(keep, 0.5)  

使用NMS算法后,就可以去除我们重复的文本框了,效果如下:
在这里插入图片描述
完整代码:

view plaincopy to clipboardprint?
import cv2  
import numpy as np  def non_max_suppression_fast(boxes, overlapThresh):  # 空数组检测  if len(boxes) == 0:  return []  # 将类型转为float  if boxes.dtype.kind == "i":  boxes = boxes.astype("float")  pick = []  # 四个坐标数组  x1 = boxes[:,0]  y1 = boxes[:,1]  x2 = boxes[:,2]  y2 = boxes[:,3]  area = (x2 - x1 + 1) * (y2 - y1 + 1) # 计算面积数组  idxs = np.argsort(y2) # 返回的是右下角坐标从小到大的索引值  # 开始遍历删除重复的框  while len(idxs) > 0:  # 将最右下方的框放入pick数组  last = len(idxs) - 1  i = idxs[last]  pick.append(i)  # 找到剩下的其余框中最大的坐标x1y1,和最小的坐标x2y2,  xx1 = np.maximum(x1[i], x1[idxs[:last]])  yy1 = np.maximum(y1[i], y1[idxs[:last]])  xx2 = np.minimum(x2[i], x2[idxs[:last]])  yy2 = np.minimum(y2[i], y2[idxs[:last]])  # 计算重叠面积占对应框的比例  w = np.maximum(0, xx2 - xx1 + 1)  h = np.maximum(0, yy2 - yy1 + 1)  overlap = (w * h) / area[idxs[:last]]  # 如果占比大于阈值,则删除  idxs = np.delete(idxs, np.concatenate(([last], np.where(overlap > overlapThresh)[0])))  return boxes[pick].astype("int")  img = cv2.imread('1501728414965.png')  
vis = img.copy() # 用于绘制矩形框图  
orig = img.copy() # 用于绘制不重叠的矩形框图  
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 得到灰度图  
mser = cv2.MSER_create() # 得到mser算法对象  
regions, _ = mser.detectRegions(gray) # 获取文本区域  
hulls = [cv2.convexHull(p.reshape(-1, 1, 2)) for p in regions] # 绘制文本区域  
cv2.polylines(img, hulls, 1, (255, 0, 0))  
cv2.namedWindow("img",0)  
cv2.resizeWindow("img", 800, 640) # 限定显示图像的大小  
cv2.imshow('img', img)  keep = []  
# 绘制目前的矩形文本框  
for c in hulls:  x, y, w, h = cv2.boundingRect(c)  keep.append([x, y, x + w, y + h])  cv2.rectangle(vis, (x, y), (x + w, y + h), (255, 255, 0), 1)             
print("[x] %d initial bounding boxes" % (len(keep)))  
cv2.namedWindow("hulls",0)  
cv2.resizeWindow("hulls", 800, 640)  
cv2.imshow("hulls", vis)  # 筛选不重复的矩形框  
keep2=np.array(keep)  
pick = non_max_suppression_fast(keep2, 0.5)  
print("[x] after applying non-maximum, %d bounding boxes" % (len(pick)))  
for (startX, startY, endX, endY) in pick:  cv2.rectangle(orig, (startX, startY), (endX, endY), (255, 185, 120), 2)  
cv2.namedWindow("After NMS",0)  
cv2.resizeWindow("After NMS", 800, 640)  
cv2.imshow("After NMS", orig)  cv2.waitKey(0)  
cv2.destroyAllWindows()  

原图:
在这里插入图片描述

可以得到结果:

image.png
在这里插入图片描述
在这里插入图片描述
查看文章汇总页https://blog.csdn.net/weixin_44237705/article/details/107864965
更多openvino技术信息可以入群交流~
申请备注:CSDN
在这里插入图片描述


http://chatgpt.dhexx.cn/article/sJZtNt2W.shtml

相关文章

opencv 中将 MSER 修改成 Hierarchical MSER 方法

http://code.opencv.org/issues/1577 描述 I attach a patch implementing the Hierarchical MSER. It extends the OpenCV MSER implementation to return the underlying component tree used by the MSER algorithm. The tree is returned in the CvSeq tree fields (h_next…

OpenCV实践之MSER/MSCR极值区域检测算法

MSER/MSCR极值区域检测算法 OpenCV中features2d.hpp中MSER类接口实现了MSER极值区域检测算法,MSER类根据输入参数判断是否为彩色or灰度图像进行不同的算法检测。若输入为灰度图像,那么采取MSER极值区域检测算法,若输入为彩色图像,…

MSER仿射不变特征匹配算法

MSER原理简述 个人博客 OpenCV实践之MSER仿射匹配算法 已更新讲述MSER仿射匹配算法代码      区域检测(Region Detection)方法是根据图像中具有某种同类性质的像元进行分类(例如相同像素值大小的点),然后把具有相同性质的像元合并成区域,实现区域的检测即图像分割。MSER…

OpenCV用MSER 算法提取特征区域

计算图像 MSER 的基础类是 cv::MSER&#xff0c;继承自 cv::Feature2D 类&#xff0c;cv::MSER 类的实例可以通过create 方法创建。我们在初始化时指定被检测区域的最小和最大尺寸&#xff0c;以便限制被检测特征的数量&#xff0c;调用方式如下&#xff1a; cv::Ptr<cv::M…

车牌定位之MSER — 文本检测

最大稳定极值区域&#xff08;MSER-Maximally Stable Extremal Regions&#xff09;可以用于图像的斑点区域检测。它是基于分水岭的概念。 SIFT和SURF算法高效实现了具有尺度和旋转不变性的特征检测&#xff0c;但这些特征不具有仿射不变性。区域检测针对各种不同形状的图像区域…

图像局部特征(十四)--MSER特征

原文: http://blog.csdn.net/zhaocj/article/details/40742191 最大稳定极值区域&#xff08;MSER-Maximally Stable Extremal Regions&#xff09;可以用于图像的斑点区域检测。该算法最早是由Matas等人于2002年提出&#xff0c;它是基于分水岭的概念。 MSER的基本原理是对…

【AI实战】手把手教你深度学习文字识别(文字检测篇:基于MSER, CTPN, SegLink, EAST等方法)

文字检测是文字识别过程中的一个非常重要的环节&#xff0c;文字检测的主要目标是将图片中的文字区域位置检测出来&#xff0c;以便于进行后面的文字识别&#xff0c;只有找到了文本所在区域&#xff0c;才能对其内容进行识别。 文字检测的场景主要分为两种&#xff0c;一种是…

MSRCR

带色彩恢复的多尺度视网膜增强算法&#xff08;MSRCR&#xff09;的原理、实现及应用。 Retinex这个词是由视网膜(Retina)和大脑皮层(Cortex) 两个词组合构成的。Retinex理论主要包含了两个方面的内容&#xff1a;物体的颜色是由物体对长波、 中波和短波光线的反射能力决定的&a…

mser场景文字检测及筛选

发现很多人都用mser,swt等进行场景文字的检测&#xff0c;最近也去实现了一下&#xff0c;虽然swt较新的算法&#xff0c;但实现过程中传统的mser算法反而更稳定&#xff0c;速度也会更快&#xff0c;可能是我还没有完全领会swt的精髓。ps:暂时只做水平及水平倾斜的文字 demo …

mser python篇

之前一直在matlab上用这个函数&#xff0c;现在转移到python上面使用 ———————————————————————————————————— 1、代码 I cv2.cvtColor(I, cv2.COLOR_BGR2GRAY); mser cv2.MSER_create() regions,boxes mser.detectRegions(I) for bo…

MSER — 自然场景文本检测

MSER是最大稳定极值区域&#xff1a;是对一幅灰度图像&#xff08;灰度值为0&#xff5e;255&#xff09;取阈值进行二值化处理&#xff0c;阈值从0到255依次递增。阈值的递增类似于分水岭算法中的水面的上升&#xff0c;随着水面的上升&#xff0c;有一些较矮的丘陵会被淹没&a…

文字检测与识别1-MSER

导语 文字识别在现实场景中的用途非常广泛&#xff0c;现在已经有很多公司将这项技术用于实际中。比如车牌识别&#xff0c;图片转换成文档&#xff0c;拍照搜题&#xff0c;拍照翻译等。这让很多人有了错觉&#xff0c;感觉文字识别的技术已经炉火纯青&#xff0c;可以广泛应…

MSER常见参数

MSER用于文本检测已经成熟了&#xff0c;现简单使用来识别车牌号。 目录 MSER参数最大最小区域固定 MSER参数 默认&#xff1a;int delta 5, int min_area 60, int max_area 14400, double max_variation 0.25, double min_diversity .2 * Full constructor for %MSER d…

MSER算法

最稳定极值区域介绍 如把灰度图看成高低起伏的地形图&#xff0c;其中灰度值看成海平面高度的话&#xff0c;MSER的作用就是在灰度图中找到符合条件的坑洼。条件为坑的最小高度&#xff0c;坑的大小&#xff0c;坑的倾斜程度&#xff0c;坑中如果已有小坑时大坑与小坑的变化率…

【MSER】基于MSER算法的交通标志分割仿真

1.软件版本 MATLAB2021a 2.本算法理论知识 [1]钱坤. 基于MSER和遗传优化SVM的交通标志识别的研究[D]. 大连理工大学. [2]王斌, 常发亮, 刘春生. 基于MSER和SVM的快速交通标志检测[J]. 光电子.激光, 2016. 3.部分源码 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%…

MSER相关总结

最近做项目用到了MSER&#xff0c;特地在这做总结。 以前提到字符检测首先会想到Tesseract&#xff0c;但是tesseact对图像的二值化要求过高&#xff0c;比较适合于白底黑字的字符识别&#xff0c;对于复杂情况就无能为力了&#xff1b; 于是就想到用轮廓检测&#xff0c;这种…

最大稳定极值区域(MSER)检测

Lowe和Bay提出的SIFT和SURF算法高效实现了具有尺度和旋转不变性的特征检测&#xff0c;但这些特征不具有仿射不变性。 区域检测针对各种不同形状的图像区域&#xff0c;通过对区域的旋转和尺寸归一化&#xff0c;可以实现仿射不变性。 MSER&#xff08;Maximally Stable Extr…

MSER最稳定极值区域源码分析

最稳定极值区域介绍 如把灰度图看成高低起伏的地形图&#xff0c;其中灰度值看成海平面高度的话&#xff0c;MSER的作用就是在灰度图中找到符合条件的坑洼。条件为坑的最小高度&#xff0c;坑的大小&#xff0c;坑的倾斜程度&#xff0c;坑中如果已有小坑时大坑与小坑的变化率。…

OpenCVSharp入门教程 特征提取①——MSER区域特征提取Maximally Stable Extremal Regions

文章目录 一、前文二、特征提取流程三、界面布局四、功能实现4.1 打开图片4.2 特征提取—源码4.3 特征提取—参数讲解4.4 特征提取—Detect和DetectRegions 五、运行效果图六、发现并解决问题七、其他问题 一、前文 MSER Maximally Stable Extremal Regions 最大极值稳定区 业…

【OpenCV 例程 300篇】247. 特征检测之最大稳定极值区域(MSER)

『youcans 的 OpenCV 例程300篇 - 总目录』 【youcans 的 OpenCV 例程 300篇】247. 特征检测之最大稳定极值区域&#xff08;MSER&#xff09; 1. 最大稳定极值区域&#xff08;MSER&#xff09; 最大稳定极值区域&#xff08;MSER-Maximally Stable Extremal Regions&#xf…