基于OpenCV进行文本分块切割
来源:互联网 发布:网络销售计划和目标 编辑:程序博客网 时间:2024/06/06 04:12
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public
void
HorizontalProjection()
{
//以灰度图方式读入源文件
string
filename =
"source.jpg"
;
var
src = IplImage.FromFile(filename, LoadMode.GrayScale);
//二值化,采用阈值分割法
Cv.Threshold(src, src, 0, 255, ThresholdType.BinaryInv | ThresholdType.Otsu);
//存储投影值的数组
var
h =
new
int
[src.Height];
//对每一行计算投影值
for
(
int
y = 0;y < src.Height;++y)
{
//遍历这一行的每一个像素,如果是有效的,累加投影值
for
(
int
x = 0;x < src.Width;++x)
{
var
s = Cv.Get2D(src, y, x);
if
(s.Val0 == 255)
h[y]++;
}
}
//准备一个图像用于画投影图
var
paintY = Cv.CreateImage(src.Size, BitDepth.U8, 1);
Cv.Zero(paintY);
//画图
var
t =
new
CvScalar(255);
for
(
int
y = 0;y < src.Height;++y)
{
for
(
int
x = 0;x < h[y];++x)
Cv.Set2D(paintY, y, x, t);
}
//显示
using
(
var
window =
new
CvWindow(
"Source"
))
{
window.Image = src;
using
(
var
win2 =
new
CvWindow(
"Projection"
))
{
win2.Image = paintY;
Cv.WaitKey();
}
}
}
1
2
var
kernal = Cv.CreateStructuringElementEx(3, 1, 1, 0, ElementShape.Rect);
Cv.Dilate(src, src, kernal, 4);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
using
System;
using
System.Collections.Generic;
using
System.IO;
using
System.Text;
using
OpenCvSharp;
using
OpenCvSharp.Extensions;
using
OpenCvSharp.Utilities;
namespace
OpenCvTest
{
class
Program
{
static
void
Main(
string
[] args)
{
//打开源文件
string
filename =
"source.jpg"
;
var
src = IplImage.FromFile(filename);
//转成灰度图
var
gray = Cv.CreateImage(src.Size, BitDepth.U8, 1);
Cv.CvtColor(src, gray, ColorConversion.BgrToGray);
//二值化,阈值分割算法
Cv.Threshold(gray, gray, 0, 255, ThresholdType.BinaryInv | ThresholdType.Otsu);
//分行
var
rows = GetRowRects(gray);
//针对每一行再分块
var
items =
new
List<CvRect>();
foreach
(
var
row
in
rows)
{
var
cols = GetBlockRects(gray.Clone(row), row.Y);
items.AddRange(cols);
}
//把识别出的每一块画到原图上去
var
color =
new
CvScalar(255, 0, 0);
foreach
(
var
rect
in
items)
{
Cv.DrawRect(src, rect, color, 1);
}
//显示
using
(
var
window =
new
CvWindow(
"Image"
))
{
window.Image = src;
Cv.WaitKey();
}
}
/// <summary>
/// 识别行
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
private
static
List<CvRect> GetRowRects(IplImage source)
{
var
rows =
new
List<CvRect>();
//用于存储投影值
var
projection =
new
int
[source.Height];
//遍历每一行计算投影值
for
(
int
y = 0; y < source.Height; ++y)
{
for
(
int
x = 0; x < source.Width; ++x)
{
var
s = Cv.Get2D(source, y, x);
if
(s.Val0 == 255)
projection[y]++;
}
}
bool
inLine =
false
;
int
start = 0;
//开始根据投影值识别分割点
for
(
int
i = 0; i < projection.Length; ++i)
{
if
(!inLine && projection[i] > 10)
{
//由空白进入字符区域了,记录标记
inLine =
true
;
start = i;
}
else
if
((i - start > 5) && projection[i] < 10 && inLine)
{
//由字符区域进入空白区域了
inLine =
false
;
//忽略高度太小的行,比如分隔线
if
(i - start > 10)
{
//记录下位置
var
rect =
new
CvRect(0, start - 1 , source.Width, i - start + 2);
rows.Add(rect);
}
}
}
return
rows;
}
/// <summary>
/// 识别块
/// </summary>
/// <param name="source"></param>
/// <param name="rowY"></param>
/// <returns></returns>
private
static
List<CvRect> GetBlockRects(IplImage source,
int
rowY)
{
var
blocks =
new
List<CvRect>();
//用于存储投影值
var
projection =
new
int
[source.Width];
//先进行横向膨胀
var
kernal = Cv.CreateStructuringElementEx(3, 1, 1, 0, ElementShape.Rect);
Cv.Dilate(source, source, kernal, 4);
//遍历每一列计算投影值
for
(
int
x = 0; x < source.Width; ++x)
{
for
(
int
y = 0; y < source.Height; ++y)
{
var
s = Cv.Get2D(source, y, x);
if
(s.Val0 == 255)
projection[x]++;
}
}
bool
inBlock =
false
;
int
start = 0;
//开始根据投影值识别分割点
for
(
int
i = 0; i < projection.Length; ++i)
{
if
(!inBlock && projection[i] >= 2)
{
//由空白区域进入字符区域了
inBlock =
true
;
start = i;
}
else
if
((i - start > 10) && inBlock && projection[i] < 2)
{
//由字符区域进入空白区域了
inBlock =
false
;
//记录位置,注意由于传入的是source只是一行,因此最终的位置信息要+rowY
if
(blocks.Count > 0)
{
//跟上一个比一下,如果距离过近,认为是同一个文本块,合并
var
last = blocks[blocks.Count - 1];
if
(start - last.X - last.Width <= 5)
{
blocks.RemoveAt(blocks.Count - 1);
var
rect =
new
CvRect(last.X, rowY, i - last.X, source.Height);
blocks.Add(rect);
}
else
{
var
rect =
new
CvRect(start, rowY, i - start, source.Height);
blocks.Add(rect);
}
}
else
{
var
rect =
new
CvRect(start, rowY, i - start, source.Height);
blocks.Add(rect);
} }
}
return
blocks;
}
}
}
阅读全文
0 0
- 基于OpenCV进行文本分块切割
- 文本分块切割
- 基于OpenCV进行相机标定
- 文本中的单词切割
- 基于Word2Vec Doc2Vec 进行文本情感分类
- opencv 图像分块处理
- opencv批量切割图片
- openCV实现图像切割
- 用opencv自带的haar方法进行人脸识别并切割
- opencv<二>基于opencv对图片进行高斯滤波
- Python + OpenCV实现基于傅里叶变换的旋转文本校正
- OpenCV实现基于傅里叶变换的旋转文本校正
- OpenCV实现基于傅里叶变换的旋转文本校正
- java版文本切割器
- awk切割文本中字符串
- 使用strtk来切割文本
- python-opencv 图像分块处理
- python,opencv切割图像操作
- LeetCode670. Maximum Swap
- 小米6使用Charles进行HTTPS抓包
- CVE-2017-12617漏洞分析
- Centos下R的安装
- 绝对定位时关于bottom的参照点的一些问题
- 基于OpenCV进行文本分块切割
- 页面之间URL传值处理特殊字符防止特殊字符将参数截断
- java内存泄漏,jvm内存溢出
- 响应式布局 媒体查询
- 标识接口的作用
- saltstack执行结果结合Elasticsearch来展现
- linux服务器用centos还是ubuntu系统_Linux
- Wrong committed revision number: -1
- 解放计算给服务带来的压力,第一想到的就是阿里云高性能计算(HPC)