首先对图像进行简单的阈值处理:
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
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的膨胀:
最后重建图像:
二、对大窗户区阴影的增强
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] ;
}
}
}
|
最后效果如下: