2021-01-02

Part6 图像分割 image segmentation
主要内容包括一些点、线、边缘的检测算子和检测原理。
在这里插入图片描述

点、线、边缘的检测 point line edge detection
基本思想
根据其变化程度,使用梯度或者Laplace算子来进行检测,再进行阈值筛选;
一般而言,一阶导数产生的边缘比较粗糙;二阶导数产生的边缘比较精细,如细线、孤立点和噪声;
在这里插入图片描述
小七资源网 http://wyyfz.com
孤立点的检测
基本原理
使用Laplace算子进行检测,再进行阈值筛选即可
在这里插入图片描述
在这里插入图片描述

直线的检测
基本原理
使用方向算子进行检测,再进行阈值筛选即可
在这里插入图片描述

边缘的检测
三步:1、平滑;2、检测;3、边缘定位; 梯度与边缘方向垂直

梯度算子
先高斯滤波,去除噪声;然后使用梯度算子进行检测,阈值筛选法
在这里插入图片描述
先高斯滤波,去除噪声;再使用梯度算子检测,zero crossing法
byte[,] zeroCross(float[,] f,float thr) //
{
int w = f.GetLength(0);
int h = f.GetLength(1);

byte[,] g = new byte[w,h];

for(int y=1;y<h-1;y++)
for (int x=1;x<w-1;x++)
{
if (f[x,y]>=0)
{
if (f[x+1,y]*f[x-1,y]<0 && Math.Abs(f[x+1,y]-f[x-1,y])>thr) g[x,y]=255;
if (f[x,y+1]*f[x,y-1]<0 && Math.Abs(f[x,y+1]-f[x,y-1])>thr) g[x,y]=255;
}
}

return g;

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
canny
在这里插入图片描述

Part7 表示与描述
霍夫变换 hough transformation
检测VLIine
基本原理:计算每一列(x=x0)下图像像素点的和,记录在p数组里面,之后遍历p,找到最大的列即为所在的垂直线段;

int detectVLine(byte[,]f)
{
int w = f.GetLength(0);
int h = f.GetLength(1);

int[] p = new int[w];

for (int y=0;y<h;y++)
for (int x=0;x<w;x++)
p[x]+=f[x,y];

int max = 0;
int x0 = 0;

for (int x=0;x<w;x++)
if (p[x]>max)
{
max = p[x];
x0 = x;
}

return x0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void drawVLine(byte[,]f,int x0)
{
int w = f.GetLength(0);
int h = f.GetLength(1);

for (int y=0;y<h;y++)
f[x0,y] = 255;

}
1
2
3
4
5
6
7
8
9
霍夫变换检测直线
原理:

将角度细分为360°,构建一个二维数组,然后使用下式求可能的所有,ρθ的数量,放在数组里面:
在这里插入图片描述
2.对图像上的每个点,若像素值=255,则遍历所有的θ(n=0-359)计算ρ,将计算得到的ρ取整,ρ对应数组下标的元素++;
int[,] hough(byte[,]f)
{
double pi = 3.1415926;

int w= f.GetLength(0);
int h= f.GetLength(1);

int[,] ps = new int[360,w+h];

for (int y=0;y<h;y++)
for (int x=0;x<w;x++)
{
if (f[x,y]==255)
for (int a=0;a<360;a++)
{
int r = (int)(xCos(api/180)+ySin(api/180));

       if (r>=0 && r<w+h) 
       {
           ps[a,r] += 1;
        } 
    }    

 }

return ps;
}
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
遍历二维数组的每个数,找到最大的ρθ组合,即为检测到的直线。
void get_params(int[,] ps,out int a0,out int r0)
{
int w= ps.GetLength(0);
int h= ps.GetLength(1);
int max = 0;
a0 = 0;
r0 = 0;

for (int r=0;r<h;r++)
for (int a=0;a<w;a++)
{
if (ps[a,r]>max)
{
max = ps[a,r];
a0 = a;
r0 = r;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
若要查看具体的ps数组图像,需要先找到其最大值,然后归一化到0-255 即可。
byte[,] toByte(int[,]f)
{
int w = f.GetLength(0);
int h = f.GetLength(1);

byte[,] g = new byte[w,h];

int max = 0;

for(int y=0;y<h;y++)
for (int x=0;x<w;x++)
if (f[x,y]>max) max = f[x,y];

for(int y=0;y<h;y++)
for (int x=0;x<w;x++)
g[x,y] = (byte)(f[x,y]*255/max);
return g;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2维中心矩(质心) 2D central moment
基本原理:计算加权平均值
在这里插入图片描述
在这里插入图片描述

void GetCenter(byte[,]f,out int x0,out int y0)
{
int w = f.GetLength(0);
int h = f.GetLength(1);

int m00 = 0; // 这里用int不是很严谨,用double比较严谨,int有可能会溢出
int m10 = 0;
int m01 = 0;

for (int y=0;y<h;y++)
for (int x=0;x<w;x++)
{
m00 += f[x,y];
m10 += xf[x,y];
m01 += y
f[x,y];
}

x0 = m10/m00;
y0 = m01/m00;
}

void main()
{
byte[,] f = LoadImg();
ShowImg(“f”,f);

int x0,y0;

GetCenter(f,out x0,out y0);

f[x0,y0] = 0;
ShowImg(“center”,f);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值