提取图像里面的红色灯笼(二)

首先对图像进行简单的阈值处理:

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
/**************************************************************
 
函数功能:对图像hsi空间红色灯笼的提取
 
输入参数:源图像src;目标图像des;图像参数width,height,nChannels;
 
输出参数:目标图像
 
**************************************************************/
 
void  hsi_seg(unsigned  char * des,  const  unsigned  char * src,  int  width,  int  height,  int  nChannels)
 
{
 
printf ( "%d,%d,%d," ,nChannels,width,height);
 
unsigned  char * ocl =  new  unsigned  char [width * height * nChannels];
 
unsigned  char * hsi =  new  unsigned  char [width * height * nChannels];
 
rgb_hsi(hsi,src, width, height, nChannels); //hsi分量提取
 
for ( int  y = 0; y < height; y++)
 
{
 
for ( int  x = 0; x < width; x++)
 
{
 
int  img_H= hsi[y * width * nChannels + x * nChannels ] ;
 
int  img_S= hsi[y * width * nChannels + x * nChannels + 1] ;
 
int  img_I= hsi[y * width * nChannels + x * nChannels + 2] ;
 
if ((img_H<104)&&(img_H>102)&&(img_I>40)&&(img_S>60))
 
{
 
//printf("%d, ",img_S);
 
for ( int  n=0;n<nChannels;n++)
 
des[y * width * nChannels + x * nChannels + n] = src[y * width * nChannels + x * nChannels + n] ;
 
}
 
else
 
for ( int  n=0;n<nChannels;n++)
 
des[y * width * nChannels + x * nChannels + n] =255;
 
}
 
}
 
ImageDilation(ocl, des, width, height, nChannels,3); //进行3*3的模板膨胀

  

提取红色分量如下图所示,再进行一次3*3模板的膨胀:

clip_image002 clip_image004

再进行一次腐蚀和填充,效果如下:

clip_image006clip_image008

下面是图像填充的代码:

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
void  Imgfill(unsigned  char * des,  const  unsigned  char * src,  int  width,  int  height,  int  nChannels)
 
{
 
memcpy (des, src, nChannels*width*height);
 
// TODO: 在此添加命令处理程序代码
 
//记录填充行的最左位置
 
int  left_X=0;
 
//记录填充行的最右位置
 
int  right_X=0;
 
//记录填充列的最上位置
 
int  top_Y=0;
 
//记录填充列的最下位置
 
int  bottom_Y=0;
 
//横向填充
 
for ( int  y=0;y<height;y++)
 
{
 
for ( int  x=0;x<width-61;x++)
 
{
 
int  sl=src[y * width * nChannels + x * nChannels + 2];
 
if (sl!=255)
 
{
 
left_X=x; //找到最左边的白色点
 
for ( int  k=60;k>0;k--)
 
{
 
int  sr=src[y * width * nChannels + (x+k) * nChannels + 2];
 
if (sr!=255)
 
{
 
right_X=x+k;
 
break //跳出寻找最右边点的循环
 
}
 
}
 
//将left_X与right_X之间的点设置为黑色
 
for ( int  x=left_X;x<right_X-1;x++)
 
{
 
for ( int  n=0;n<nChannels;n++)
 
des[y * width * nChannels + x * nChannels + n]=0;
 
}
 
//x=right_X;
 
//printf("L%d ",left_X);
 
}
 
}
 
}
 
//纵向填充
 
for ( int  x=0;x<width;x++)
 
{
 
for ( int  y=0;y<height-61;y++)
 
{
 
int  st=src[y * width * nChannels + x * nChannels + 2];
 
if (255!=st)
 
{
 
top_Y=y; //y到最上边的非白色点
 
for ( int  m=10;m>0;m--)
 
{
 
int  sb=src[(y+m) * width * nChannels + x * nChannels + 2];
 
if (sb!=255)
 
{
 
bottom_Y=m+y;
 
break //跳出寻找最下边点的循环
 
}
 
}
 
//将top_Y与bottom_Y之间的点设置为黑色
 
for ( int  y=top_Y;y<bottom_Y-1;y++)
 
{
 
for ( int  n=0;n<nChannels;n++)
 
des[y * width * nChannels + x * nChannels + n]=0;
 
}
 
}
 
}
 
}
 
}

  

再进行一次8*8的腐蚀和5*5的膨胀:

clip_image010clip_image012

最后重建图像:

clip_image014

二、对大窗户区阴影的增强
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
/**************************************************************
 
函数功能:对图像窗户里阴影进行直方图均衡
 
输入参数:源图像src;目标图像des;图像参数width,height,nChannels;
 
输出参数:目标图像
 
**************************************************************/
 
void  win_enhance(unsigned  char * des,  const  unsigned  char * src,  int  width,  int  height,  int  nChannels)
 
{
 
printf ( "%d,%d,%d," ,nChannels,width,height);
 
unsigned  char * ocl =  new  unsigned  char [width * height * nChannels];
 
unsigned  char * flag =  new  unsigned  char [width * height * nChannels];
 
int  r[256] = {0}, g[256] = {0}, b[256] = {0};
 
int  sum = 0;  //图像中像素点的综合
 
for ( int  y = 0; y < height; y++)
 
{
 
for ( int  x = 0; x < width; x++)
 
{
 
int  B= src[y * width * nChannels + x * nChannels ] ;
 
int  G= src[y * width * nChannels + x * nChannels + 1] ;
 
int  R= src[y * width * nChannels + x * nChannels + 2] ;
 
if ((R+G+B<120)&&(y < height-240)&&(y >250))
 
{
 
//printf("%d, ",img_S);
 
for ( int  n=0;n<nChannels;n++)
 
{
 
des[y * width * nChannels + x * nChannels + n] = src[y * width * nChannels + x * nChannels + n] ;
 
}
 
}
 
else
 
{
 
for ( int  n=0;n<nChannels;n++)
 
{
 
des[y * width * nChannels + x * nChannels + n] =255;
 
}
 
}
 
}
 
}
 
ImageErosion(ocl, des, width, height, nChannels,9);
 
ImageDilation(des, ocl, width, height, nChannels,10);

  

下图分别为简单的阈值处理后进行一次9*9的腐蚀和10*10膨胀之后的图:

clip_image016clip_image018

下面进行对上图阴影区的直方图均衡:

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
memcpy (ocl, des,nChannels*width*height);
 
for ( int  y=0; y<height; y++)
 
for ( int  x=0; x<width; x++)
 
{
 
if ( des[y * width * nChannels + x * nChannels]!=255)
 
{
 
sum=sum+1;
 
flag[y * width * nChannels + x * nChannels ]= 1;
 
b[des[y * width * nChannels + x * nChannels + 0]]++;
 
g[des[y * width * nChannels + x * nChannels + 1]]++;
 
r[des[y * width * nChannels + x * nChannels + 2]]++;
 
}
 
else
 
{
 
flag[y * width * nChannels + x * nChannels ]= 0;
 
}
 
}
 
double  val[3] = {0};
 
for ( int  y=0; y<255; y++)
 
{
 
val[0] += b[y];
 
val[1] += g[y];
 
val[2] += r[y];
 
b[y] = val[0]*255/sum;
 
g[y] = val[1]*255/sum;
 
r[y] = val[2]*255/sum;
 
}
 
for ( int  y=0; y<height; y++)
 
for ( int  x=0; x<width; x++)
 
{
 
if (flag[y * width * nChannels + x * nChannels]==1)
 
{
 
ocl[y * width * nChannels + x * nChannels + 0] = b[des[y * width * nChannels + x * nChannels + 0]] ;
 
ocl[y * width * nChannels + x * nChannels + 1] = g[des[y * width * nChannels + x * nChannels + 1]] ;
 
ocl[y * width * nChannels + x * nChannels + 2] = r[des[y * width * nChannels + x * nChannels + 2]] ;
 
}
 
}
 
//memcpy(des, ocl, nChannels*width*height);
 
for ( int  y=0; y<height; y++)
 
for ( int  x=0; x<width; x++)
 
{
 
if (flag[y * width * nChannels + x * nChannels ]==1)
 
{
 
for ( int  n=0;n<nChannels;n++)
 
des[y * width * nChannels + x * nChannels + n] = ocl[y * width * nChannels + x * nChannels + n] ;
 
}
 
else
 
{
 
for ( int  n=0;n<nChannels;n++)
 
des[y * width * nChannels + x * nChannels + n] = src[y * width * nChannels + x * nChannels + n] ;
 
}
 
}
 
}

  

最后效果如下:

image

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值