1、题目:
分割图像,提取信封上的邮编。
2、算法原理:
原创:梁毅军(西安交大图像所,[email protected])
(1) 线框提取:
输入f(x,y)为彩色图像,输出g(x,y)为灰色图像。
g(x,y) = T[f(x,y).R, f(x,y).B, f(x,y).R] T为变换函数
T(R, G, B) = max{R- (G+B)/2 , 0};
经过T函数变换后,红色的线框被提取出来,值为255,其余颜色的点灰度值变为0.
(2)字符框位置的提取:投影算法
向x轴投影 Map_x(x) = ;
向y轴投影 Map_y(y) = ;
获取了字符框的位置后,可以采取相应算法提取各个邮编号码。
还可以继续对邮编字符做分割细化和特征提取,最后进行识别,这里暂不讨论。
3、代码:
void main()
{
ARGB [,] f = LoadColorImg();
if (f==null) return;
ShowImg("f",f);
int w = f.GetLength(0);
int h = f.GetLength(1);
byte [,] g = new byte[w,h];
//提取线框
for(int x = 0; x < w; x++)
for(int y = 0; y < h; y++)
{
double temp = f[x,y].R - (f[x,y].G+f[x,y].B)/2.0;
if(temp > 0) g[x,y] = (byte)temp;
else g[x,y] = 0;
}
//显示提取后的线框图像
ShowImg("g",g);
int [] Map_x = new int[w];//沿x轴投影值
int [] Map_y = new int[h];//沿y轴投影值
for(int x = 0; x < w; x++)
Map_x[x] = 0;
for(int y = 0; y < h; y++)
Map_y[y] = 0;
//沿x轴投影
for(int x = 0; x < w; x++)
for(int y = 0; y < h; y++)
Map_x[x] += g[x,y];
//沿y轴投影
for(int y = 0; y < h; y++)
for(int x = 0; x < w; x++)
Map_y[y] += g[x,y];
int [] Pos_x = new int[6];//x轴线框标记值
int [] Pos_y = new int[5];//y轴线框标记值
//获取x轴线框标记值
int i = 0;
for(int x = 0; x < w; x++)
if(Map_x[x] > 510)
{
Pos_x[i++] = x;
}
//获取y轴线框标记值
i = 0;
for(int y = 0; y < h; y++)
if(Map_y[y] > 1540)
{
Pos_y[i++] = y;
}
//ARGB [,] g_new = new ARGB[w,h];//显示分割后的图像,彩色图表示
byte [,] g_new = new byte[w,h];
for(int x = 0; x < w; x++)
for(int y = 0; y < h; y++)
//if((x>Pos_x[4] && xPos_y[1] && y
if((x!=Pos_x[0] && x!=Pos_x[1] &&x!=Pos_x[2] &&x!=Pos_x[3] &&x!=Pos_x[4] &&x!=Pos_x[5] )
&& (y>Pos_y[1] && y<Pos_y[2]))//获取所有邮编号码,用灰度图表示
g_new[x,y] = (byte)(255-((f[x,y].R+f[x,y].G+f[x,y].B)/3.0));
ShowImg("g_new",g_new);
}
4、结果
图 1 信封原图 f
图 2 提取的线框图 g
图 3 分割后的邮编 g_new