- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在处理这张图片作为来源:
应用下一个代码...
import cv2
import numpy as np
mser = cv2.MSER_create()
img = cv2.imread('C:\\Users\\Link\\Desktop\\test2.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
vis = img.copy()
regions, _ = mser.detectRegions(gray)
hulls = [cv2.convexHull(p.reshape(-1, 1, 2)) for p in regions]
cv2.polylines(vis, hulls, 1, (0, 255, 0))
mask = np.zeros((img.shape[0], img.shape[1], 1), dtype=np.uint8)
for contour in hulls:
cv2.drawContours(mask, [contour], -1, (255, 255, 255), -1)
text_only = cv2.bitwise_and(img, img, mask=mask)
cv2.imshow('img', vis)
cv2.waitKey(0)
cv2.imshow('img', mask)
cv2.waitKey(0)
cv2.imshow('img', text_only)
cv2.waitKey(0)
cv2.imwrite('C:\\Users\\Link\\Desktop\\test_o\\1.png', text_only)
...我得到这个作为结果(掩码):
问题是这样的:
如何合并成单个对象the number 5
在数字系列 (157661546) 中只要在蒙版图像中划分即可?
谢谢
最佳答案
看看here ,这似乎是确切的答案。
Here相反,我的上述代码版本针对文本提取进行了微调(也带有屏蔽)。
下面是上一篇文章的原始代码,“移植”到python 3,opencv 3,添加了mser和bounding boxes。与我的版本的主要区别在于分组距离的定义方式:我的是面向文本的,而下面的是自由几何距离。
import sys
import cv2
import numpy as np
def find_if_close(cnt1,cnt2):
row1,row2 = cnt1.shape[0],cnt2.shape[0]
for i in range(row1):
for j in range(row2):
dist = np.linalg.norm(cnt1[i]-cnt2[j])
if abs(dist) < 25: # <-- threshold
return True
elif i==row1-1 and j==row2-1:
return False
img = cv2.imread(sys.argv[1])
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
cv2.imshow('input', img)
ret,thresh = cv2.threshold(gray,127,255,0)
mser=False
if mser:
mser = cv2.MSER_create()
regions = mser.detectRegions(thresh)
hulls = [cv2.convexHull(p.reshape(-1, 1, 2)) for p in regions[0]]
contours = hulls
else:
thresh = cv2.bitwise_not(thresh) # wants black bg
im2,contours,hier = cv2.findContours(thresh,cv2.RETR_EXTERNAL,2)
cv2.drawContours(img, contours, -1, (0,0,255), 1)
cv2.imshow('base contours', img)
LENGTH = len(contours)
status = np.zeros((LENGTH,1))
print("Elements:", len(contours))
for i,cnt1 in enumerate(contours):
x = i
if i != LENGTH-1:
for j,cnt2 in enumerate(contours[i+1:]):
x = x+1
dist = find_if_close(cnt1,cnt2)
if dist == True:
val = min(status[i],status[x])
status[x] = status[i] = val
else:
if status[x]==status[i]:
status[x] = i+1
unified = []
maximum = int(status.max())+1
for i in range(maximum):
pos = np.where(status==i)[0]
if pos.size != 0:
cont = np.vstack(contours[i] for i in pos)
hull = cv2.convexHull(cont)
unified.append(hull)
cv2.drawContours(img,contours,-1,(0,0,255),1)
cv2.drawContours(img,unified,-1,(0,255,0),2)
#cv2.drawContours(thresh,unified,-1,255,-1)
for c in unified:
(x,y,w,h) = cv2.boundingRect(c)
cv2.rectangle(img, (x,y), (x+w,y+h), (255, 0, 0), 2)
cv2.imshow('result', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
示例输出(黄色 Blob 低于二进制阈值转换,因此被忽略)。红色:原始轮廓,绿色:统一轮廓,蓝色:边界框。
可能不需要使用 MSER,因为简单的 findContours 可能工作正常。
------------------------
在我找到上面的代码之前,从这里开始有我的旧答案。无论如何我都会离开它,因为它描述了几种不同的方法,这些方法可能更容易/更适合某些场景。
一个快速而肮脏的技巧是在 MSER 之前添加一个小的高斯模糊和一个高阈值(如果你喜欢花哨的东西,或者一些稀释/腐 eclipse )。在实践中,您只需将文本加粗,以填补小的空白。显然,您稍后可以丢弃此版本并从原始版本裁剪。
否则,如果您的文本成行,您可以尝试检测平均线中心(例如制作 Y 坐标的直方图并找到峰值)。然后,对于每一行,寻找具有接近平均 X 的片段。如果文本嘈杂/复杂,则非常脆弱。
如果您不需要拆分每个字母,获取整个单词的边界框可能会更容易:只需根据片段之间的最大水平距离(使用轮廓的最左/最右点)进行分组。然后使用每个组中最左边和最右边的框来找到整个边界框。对于多行文本,第一组按质心 Y 坐标。
实现说明:
Opencv 允许您创建 histograms但你可能可以摆脱这样的事情(为我工作过类似的任务):
def histogram(vals, th=4, bins=400):
hist = np.zeros(bins)
for y_center in vals:
bucket = int(round(y_center / 2.)) <-- change this "2."
hist[bucket-1] += 1
print("hist: ", hist)
hist = np.where(hist > th, hist, 0)
return hist
这里我的直方图只是一个包含 400 个桶的数组(我的图像是 800 像素高,所以每个桶捕获两个像素,这就是“2.”的来源)。 Vals 是每个片段质心的 Y 坐标(构建此列表时您可能希望忽略非常小的元素)。第 th 个阈值只是为了去除一些噪音。你应该得到这样的东西:
0,0,0,5,22,0,0,0,0,43,7,0,0,0
此列表从上到下描述了每个位置有多少片段。
现在我运行另一遍以将峰值合并为单个值(只需扫描数组并在非零时求和并将计数重置为第一个零)得到类似这样的 {y:count}:
{9:27, 20:50}
现在我知道我在 y=9 和 y=20 处有两个文本行。现在或之前,您将每个片段分配给在线(在我的情况下再次使用 8px 阈值)。现在您可以单独处理每一行,找到“单词”。顺便说一句,我遇到了与破损字母相同的问题,这就是我来这里寻找 MSER 的原因:)。请注意,如果您找到单词的整个边界框,此问题只会发生在第一个/最后一个字母上:其他断开的字母无论如何都落在单词框中。
Here是侵 eclipse /扩张事物的引用,但高斯模糊/th 对我有用。
更新:我注意到这一行有问题:
regions = mser.detectRegions(thresh)
我传入已经过阈值的图像(!?)。这与聚合部分无关,但请记住,mser 部分未按预期使用。
关于python - 合并 MSER 检测到的对象(OpenCV、Python),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47577184/
我的一位教授给了我们一些考试练习题,其中一个问题类似于下面(伪代码): a.setColor(blue); b.setColor(red); a = b; b.setColor(purple); b
我似乎经常使用这个测试 if( object && object !== "null" && object !== "undefined" ){ doSomething(); } 在对象上,我
C# Object/object 是值类型还是引用类型? 我检查过它们可以保留引用,但是这个引用不能用于更改对象。 using System; class MyClass { public s
我在通过 AJAX 发送 json 时遇到问题。 var data = [{"name": "Will", "surname": "Smith", "age": "40"},{"name": "Wil
当我尝试访问我的 View 中的对象 {{result}} 时(我从 Express js 服务器发送该对象),它只显示 [object][object]有谁知道如何获取 JSON 格式的值吗? 这是
我有不同类型的数据(可能是字符串、整数......)。这是一个简单的例子: public static void main(String[] args) { before("one"); }
嗨,我是 json 和 javascript 的新手。 我在这个网站找到了使用json数据作为表格的方法。 我很好奇为什么当我尝试使用 json 数据作为表时,我得到 [Object,Object]
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我听别人说 null == object 比 object == null check 例如: void m1(Object obj ) { if(null == obj) // Is thi
Match 对象 提供了对正则表达式匹配的只读属性的访问。 说明 Match 对象只能通过 RegExp 对象的 Execute 方法来创建,该方法实际上返回了 Match 对象的集合。所有的
Class 对象 使用 Class 语句创建的对象。提供了对类的各种事件的访问。 说明 不允许显式地将一个变量声明为 Class 类型。在 VBScript 的上下文中,“类对象”一词指的是用
Folder 对象 提供对文件夹所有属性的访问。 说明 以下代码举例说明如何获得 Folder 对象并查看它的属性: Function ShowDateCreated(f
File 对象 提供对文件的所有属性的访问。 说明 以下代码举例说明如何获得一个 File 对象并查看它的属性: Function ShowDateCreated(fil
Drive 对象 提供对磁盘驱动器或网络共享的属性的访问。 说明 以下代码举例说明如何使用 Drive 对象访问驱动器的属性: Function ShowFreeSpac
FileSystemObject 对象 提供对计算机文件系统的访问。 说明 以下代码举例说明如何使用 FileSystemObject 对象返回一个 TextStream 对象,此对象可以被读
我是 javascript OOP 的新手,我认为这是一个相对基本的问题,但我无法通过搜索网络找到任何帮助。我是否遗漏了什么,或者我只是以错误的方式解决了这个问题? 这是我的示例代码: functio
我可以很容易地创造出很多不同的对象。例如像这样: var myObject = { myFunction: function () { return ""; } };
function Person(fname, lname) { this.fname = fname, this.lname = lname, this.getName = function()
任何人都可以向我解释为什么下面的代码给出 (object, Object) 吗? (console.log(dope) 给出了它应该的内容,但在 JSON.stringify 和 JSON.parse
我正在尝试完成散点图 exercise来自免费代码营。然而,我现在只自己学习了 d3 几个小时,在遵循 lynda.com 的教程后,我一直在尝试确定如何在工具提示中显示特定数据。 This code
我是一名优秀的程序员,十分优秀!