1 开操作
主要应用在二值图像分析,灰度图像也可以;开操作 = 腐蚀 + 膨胀, 输入图像 + 结构元素
有利于消除图像中的噪声点分离不同的对象结构,基于不同的结构元素
2 闭操作
闭操作 = 膨胀 + 腐蚀输入 : 图像 + 结构元素不同的结构元素得到不同的效果;
有利于消除图像中的噪声点;分离不同的对象结构;
3 开操作测试
腐蚀 ErosionFilter
package binimage
.erosion
;
import binimage
.binary
.BinaryFilter
;
import java
.awt
.image
.BufferedImage
;
public class ErosionFilter extends BinaryFilter {
private int fcolor
;
public ErosionFilter() {
fcolor
= 255;
}
@Override
public BufferedImage
process(BufferedImage image
) {
BufferedImage binImage
= super.process(image
);
int width
= binImage
.getWidth();
int height
= binImage
.getHeight();
int[] pixels
= new int[width
* height
];
int[] output
= new int[width
* height
];
getRGB(binImage
, 0, 0, width
, height
, pixels
);
System
.arraycopy(pixels
, 0, output
, 0, pixels
.length
);
int p1
= 0, p2
= 0, p3
= 0;
int p4
= 0, p5
= 0, p6
= 0;
int p7
= 0, p8
= 0, p9
= 0;
int offset
= 0;
for (int row
= 1; row
< height
- 1; row
++) {
offset
= row
* width
;
for (int col
= 1; col
< width
- 1; col
++) {
p1
= (pixels
[offset
- width
+ col
- 1] >> 16) & 0xff;
p2
= (pixels
[offset
- width
+ col
] >> 16) & 0xff;
p3
= (pixels
[offset
- width
+ col
+ 1] >> 16) & 0xff;
p4
= (pixels
[offset
+ col
- 1] >> 16) & 0xff;
p5
= (pixels
[offset
+ col
] >> 16) & 0xff;
p6
= (pixels
[offset
+ col
+ 1] >> 16) & 0xff;
p7
= (pixels
[offset
+ width
+ col
- 1] >> 16) & 0xff;
p8
= (pixels
[offset
+ width
+ col
] >> 16) & 0xff;
p9
= (pixels
[offset
+ width
+ col
+ 1] >> 16) & 0xff;
int sum
= p1
+ p2
+ p3
+ p4
+ p6
+ p7
+ p8
+ p9
;
int total
= fcolor
* 8;
if (p5
== fcolor
&& sum
!= total
) {
int bc
= 255 - fcolor
;
output
[offset
+ col
] = (0xff << 24) | ((bc
& 0xff) << 16) | ((bc
& 0xff) << 8) | (bc
& 0xff);
}
}
}
BufferedImage bi
= new BufferedImage(width
, height
, BufferedImage
.TYPE_INT_ARGB
);
setRGB(bi
, 0, 0, width
, height
, output
);
return bi
;
}
public int getFcolor() {
return fcolor
;
}
public void setFcolor(int fcolor
) {
this.fcolor
= fcolor
;
}
}
膨胀 DilationFilter
package binimage
.dilation
;
import binimage
.binary
.BinaryFilter
;
import java
.awt
.image
.BufferedImage
;
public class DilationFilter extends BinaryFilter {
private int fcolor
;
public DilationFilter() {
fcolor
= 255;
}
@Override
public BufferedImage
process(BufferedImage image
) {
BufferedImage binImage
= super.process(image
);
int width
= binImage
.getWidth();
int height
= binImage
.getHeight();
int[] pixels
= new int[width
* height
];
int[] output
= new int[width
* height
];
getRGB(binImage
, 0, 0, width
, height
, pixels
);
System
.arraycopy(pixels
, 0, output
, 0, pixels
.length
);
int p1
= 0, p2
= 0, p3
= 0;
int p4
= 0, p5
= 0, p6
= 0;
int p7
= 0, p8
= 0, p9
= 0;
int offset
= 0;
for (int row
= 1; row
< height
- 1; row
++) {
offset
= row
* width
;
for (int col
= 1; col
< width
- 1; col
++) {
p1
= (pixels
[offset
- width
+ col
- 1] >> 16) & 0xff;
p2
= (pixels
[offset
- width
+ col
] >> 16) & 0xff;
p3
= (pixels
[offset
- width
+ col
+ 1] >> 16) & 0xff;
p4
= (pixels
[offset
+ col
- 1] >> 16) & 0xff;
p5
= (pixels
[offset
+ col
] >> 16) & 0xff;
p6
= (pixels
[offset
+ col
+ 1] >> 16) & 0xff;
p7
= (pixels
[offset
+ width
+ col
- 1] >> 16) & 0xff;
p8
= (pixels
[offset
+ width
+ col
] >> 16) & 0xff;
p9
= (pixels
[offset
+ width
+ col
+ 1] >> 16) & 0xff;
int sum
= p1
+ p2
+ p3
+ p4
+ p6
+ p7
+ p8
+ p9
;
int bc
= 255 - fcolor
;
int total
= bc
* 8;
if (p5
== bc
&& sum
!= total
) {
output
[offset
+ col
] = (0xff << 24) | ((fcolor
& 0xff) << 16) | ((fcolor
& 0xff) << 8) | (fcolor
& 0xff);
}
}
}
BufferedImage bi
= new BufferedImage(width
, height
, BufferedImage
.TYPE_INT_ARGB
);
setRGB(bi
, 0, 0, width
, height
, output
);
return bi
;
}
public int getFcolor() {
return fcolor
;
}
public void setFcolor(int fcolor
) {
this.fcolor
= fcolor
;
}
}
开操作 OpenFilter
package binimage
.openclose
;
import binimage
.dilation
.DilationFilter
;
import binimage
.erosion
.ErosionFilter
;
import binimage
.utils
.AbstractImageOptionFilter
;
import java
.awt
.image
.BufferedImage
;
public class OpenFilter extends AbstractImageOptionFilter {
private int fcolor
;
public int getFcolor() {
return fcolor
;
}
public void setFcolor(int fcolor
) {
this.fcolor
= fcolor
;
}
@Override
public BufferedImage
process(BufferedImage image
) {
ErosionFilter ef
= new ErosionFilter();
ef
.setFcolor(fcolor
);
BufferedImage eimage
= ef
.process(image
);
DilationFilter df
= new DilationFilter();
df
.setFcolor(fcolor
);
BufferedImage result
= df
.process(eimage
);
return result
;
}
}
ImagePanel
package binimage
.openclose
;
import binimage
.erosion
.ErosionFilter
;
import javax
.imageio
.ImageIO
;
import javax
.swing
.*
;
import java
.awt
.*
;
import java
.awt
.event
.ActionEvent
;
import java
.awt
.event
.ActionListener
;
import java
.awt
.image
.BufferedImage
;
import java
.io
.File
;
import java
.io
.IOException
;
public class ImagePanel extends JComponent implements ActionListener {
private BufferedImage image
;
private BufferedImage resultImage
;
private JButton processBtn
;
public ImagePanel(BufferedImage image
) {
this.image
= image
;
}
public JButton
getButton() {
processBtn
= new JButton("按钮");
processBtn
.addActionListener(this);
return processBtn
;
}
@Override
protected void paintComponent(Graphics g
) {
Graphics2D g2d
= (Graphics2D
) g
;
if (null
!= image
) {
g2d
.drawImage(image
, 0, 0, image
.getWidth(), image
.getHeight(), null
);
}
if (resultImage
!= null
) {
g2d
.drawImage(resultImage
, image
.getWidth() + 10, 0, resultImage
.getWidth(), resultImage
.getHeight(), null
);
}
}
public void process() {
OpenFilter filter
= new OpenFilter();
filter
.setFcolor(0);
resultImage
= filter
.process(image
);
}
@Override
public void actionPerformed(ActionEvent e
) {
if (e
.getSource() == processBtn
) {
this.process();
this.repaint();
}
}
public static void main(String
[] args
) {
File file
= new File("resource/num.png");
try {
BufferedImage image
= ImageIO
.read(file
);
ImagePanel imp
= new ImagePanel(image
);
JFrame frame
= new JFrame();
frame
.setDefaultCloseOperation(JFrame
.EXIT_ON_CLOSE
);
frame
.getContentPane().add(imp
, BorderLayout
.CENTER
);
frame
.getContentPane().add(imp
.getButton(), BorderLayout
.SOUTH
);
frame
.setSize(1000, 600);
frame
.setTitle("图像显示测试");
frame
.setVisible(true);
} catch (IOException e
) {
e
.printStackTrace();
}
}
}