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

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

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模板的膨胀:

 提取图像里面的红色灯笼(二)_第1张图片

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

提取图像里面的红色灯笼(二)_第2张图片

下面是图像填充的代码:

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的膨胀:

提取图像里面的红色灯笼(二)_第3张图片

最后重建图像:

提取图像里面的红色灯笼(二)_第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
/**************************************************************
 
函数功能:对图像窗户里阴影进行直方图均衡
 
输入参数:源图像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膨胀之后的图:

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

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] ;
 
}
 
}
 
}

  

最后效果如下:

提取图像里面的红色灯笼(二)_第5张图片

你可能感兴趣的:(提取图像里面的红色灯笼(二))