手機圖像簡單預處理(J2ME實現)
2009年5月27日星期三
最近看到以前的一本數字圖像處理書,不禁想用j2me嘗試一下簡單的數字圖像處理在手機上如何實現。于是便有本文。
1
package com.yuankai.ImageTest;
2
3
import java.io.IOException;
4
5
import javax.microedition.lcdui.Display;
6
import javax.microedition.lcdui.Form;
7
import javax.microedition.lcdui.Image;
8
import javax.microedition.midlet.MIDlet;
9
import javax.microedition.midlet.MIDletStateChangeException;
10
11
import com.yuankai.j2me.image.ImageUtil;
12
13
public class ImageProcessMIDlet extends MIDlet
{
14
15
Display display=null;
16
Image old_image=null;
17
Image new_image=null;
18
Form form=new Form("Image Processing");
19
20
public ImageProcessMIDlet()
{
21
display=Display.getDisplay(this);
22
try
{
23
old_image=Image.createImage("/1.png");
24
} catch (IOException e)
{
25
e.printStackTrace();
26
}
27
28
}
29
protected void destroyApp(boolean arg0) throws MIDletStateChangeException
{
30
// TODO Auto-generated method stub
31
32
}
33
34
protected void pauseApp()
{
35
// TODO Auto-generated method stub
36
37
}
38
39
protected void startApp() throws MIDletStateChangeException
{
40
41
display.setCurrent(form);
42
form.append("處理前\n");
43
form.append(old_image);
44
//進行圖像的預處理
45
46
form.append("\n灰度化處理后:\n");
47
new_image=ImageUtil.toGray(old_image);
48
form.append(new_image);
49
50
// form.append("\n邊緣檢測處理后:\n");
51
// new_image=ImageUtil.Sobel(new_image, new_image.getWidth());
52
// form.append(new_image);
53
54
form.append("\n二值化處理后:\n");
55
new_image=ImageUtil.Binarization(new_image,100);
56
form.append(new_image);
57
58
}
59
60
}
61
上面這個文件是我寫的一個MIDlet類文件,用來調用ImageUtil類圖像處理方法.
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

1
package com.yuankai.j2me.image;
2
3
import javax.microedition.lcdui.Image;
4
5
/** *//**
6
* 數字圖像處理工具類型
7
* */
8
public class ImageUtil
{
9
10
public static final int RED=1;
11
public static final int GREEN=2;
12
public static final int BLUE=3;
13
public static final int ALPHA=4;
14
/** *//**
15
* 圖像灰度化
16
* Image old_image:原始圖像
17
* */
18
public static Image toGray(Image old_image)
19
{
20
Image image=null;
21
int []RGBArray;
22
23
int width=old_image.getWidth();
24
int height=old_image.getHeight();
25
RGBArray=new int[width*height];
26
old_image.getRGB(RGBArray, 0, width, 0, 0, width, height);
27
int size=RGBArray.length;
28
29
for(int i=0;i<size;i++)
30
{
31
32
int color=RGBArray[i];
33
int alpha=color2RGB(color,ALPHA);
34
int red=color2RGB(color,RED);
35
int green=color2RGB(color,GREEN);
36
int blue=color2RGB(color,BLUE);
37
38
//修改成灰度圖象,采用的是權值平均值法
39
int temp=(int)(red*0.11+green*0.59+blue*0.3);
40
41
red=temp;
42
green=temp;
43
blue=temp;
44
45
color=RGB2color(red,green,blue,alpha);;
46
RGBArray[i]=color;
47
48
49
}
50
image=Image.createRGBImage(RGBArray, width, height,true);
51
return image;
52
53
}
54
/** *//**
55
* 圖像二值化
56
* Image old_image:原始圖像
57
* int level : 閥值
58
* */
59
public static Image Binarization(Image old_image,int level)
60
{
61
Image image=null;
62
int []RGBArray;
63
64
int width=old_image.getWidth();
65
int height=old_image.getHeight();
66
RGBArray=new int[width*height];
67
old_image.getRGB(RGBArray, 0, width, 0, 0, width, height);
68
int size=RGBArray.length;
69
for(int i=0;i<size;i++)
70
{
71
72
int color=RGBArray[i];
73
int alpha=color2RGB(color,ALPHA);
74
int red=color2RGB(color,RED);
75
int green=color2RGB(color,GREEN);
76
int blue=color2RGB(color,BLUE);
77
78
//修改成灰度圖象
79
if(red>level)
80
red=255;
81
else
82
red=0;
83
if(green>level)
84
green=255;
85
else
86
green=0;
87
if(blue>level)
88
blue=255;
89
else
90
blue=0;
91
92
93
color=RGB2color(red,green,blue,alpha);
94
RGBArray[i]=color;
95
96
97
}
98
image=Image.createRGBImage(RGBArray, width, height,true);
99
return image;
100
101
}
102
103
/** *//**
104
* 圖像邊緣檢測 Sobel 算子
105
* Image old_image:原始灰度圖像
106
* int widthstep : 行大小
107
*
108
* g(x,y)=
109
* abs(f(x-1,y-1)+2*f(x-1,y)+f(x-1,y+1)-f(x+1,y-1)-2*f(x+1,y)-f(x+1,y+1))
110
* +abs(f(x-1,y-1)+2*f(x,y-1)+f(x+1,y-1)-f(x-1,y+1)-2*f(x,y+1)-f(x+1,y+1))
111
*
112
* -1 0 1 -1 -2 -1
113
* -2 0 2 0 0 0
114
* -1 0 1 1 2 1
115
* */
116
public static Image Sobel(Image old_image,int widthstep)
117
{
118
Image image=null;
119
int []RGBArray;
120
121
int width=old_image.getWidth();
122
int height=old_image.getHeight();
123
RGBArray=new int[width*height];
124
old_image.getRGB(RGBArray, 0, width, 0, 0, width, height);
125
for(int i=1;i<height-1;i++)
126
{
127
128
129
for(int j=1;j<width-1;j++)
130
{
131
//獲得對應位置的灰度值
132
//f(x-1,y-1)
133
int color11=RGBArray[(i-1)*widthstep+j-1];
134
int gray11=color2RGB(color11,RED);
135
//f(x-1,y)
136
int color12=RGBArray[(i-1)*widthstep+j];
137
int gray12=color2RGB(color12,RED);
138
//f(x-1,y+1)
139
int color13=RGBArray[(i-1)*widthstep+j+1];
140
int gray13=color2RGB(color13,RED);
141
142
//f(x+1,y-1)
143
int color31=RGBArray[(i+1)*widthstep+j-1];
144
int gray31=color2RGB(color31,RED);
145
//f(x+1,y)
146
int color32=RGBArray[(i+1)*widthstep+j];
147
int gray32=color2RGB(color32,RED);
148
//f(x+1,y+1)
149
int color33=RGBArray[(i+1)*widthstep+j+1];
150
int gray33=color2RGB(color33,RED);
151
152
//f(x,y-1)
153
int color21=RGBArray[i*widthstep+j-1];
154
int gray21=color2RGB(color21,RED);
155
//f(x,y+1)
156
int color23=RGBArray[i*widthstep+j+1];
157
int gray23=color2RGB(color23,RED);
158
159
160
161
int Sx=gray11+2*gray12+gray13-gray31-2*gray32-gray33;
162
int Sy=gray11+2*gray21+gray31-gray12-2*gray13-gray33;
163
int temp=(int)Math.sqrt(Sx*Sx+Sy*Sy);
164
165
int color=RGBArray[i*widthstep+j-1];
166
int alpha=color2RGB(color,ALPHA);
167
168
RGBArray[i*widthstep+j-1]=RGB2color(temp,temp,temp,alpha);;
169
}
170
171
}
172
image=Image.createRGBImage(RGBArray, width, height,true);
173
return image;
174
175
}
176
/** *//**
177
* 獲得一個顏色分量的值
178
* */
179
public static int color2RGB(int color,int type)
180
{
181
int temp=-1;
182
switch(type)
183
{
184
case BLUE:
185
temp=(color&0x000000ff);
186
break;
187
case GREEN:
188
temp=(color&0x0000ff00)>>8;
189
break;
190
case RED:
191
temp=(color&0x00ff0000)>>16;
192
break;
193
case ALPHA:
194
temp=0xff;
195
break;
196
}
197
return temp;
198
}
199
/** *//**
200
* 根據rgb獲得color()
201
**/
202
public static int RGB2color(int red,int green,int blue,int alpha)
203
{
204
return (alpha<<24)+(red<<16)+(green<<8)+blue;
205
}
206
}
207
上面代碼,是我自己寫的ImageUtil類型,它提供簡單的圖像處理的靜態方法。
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

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176


177

178

179

180



181

182

183



184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199


200

201

202

203



204

205

206

207

程序測試結果:



以上代碼處理的圖片格式是j2me最常見的.png格式.可以看到使用soble算子+j2me實現邊緣檢測效果明顯比我們平時用VC實現的差,不知道如何進行修改,才可以提升在手機中處理效果。
什么事情?