Initial commit

This commit is contained in:
Juvenile 2021-10-19 08:58:41 +08:00
parent 89986103c7
commit 594ce410b2
38 changed files with 1123 additions and 2 deletions

144
README.md
View File

@ -1,3 +1,143 @@
# picture-processing # 基于Java语言实现的医学图像的处理
基于Java语言实现的医学图像的处理 # 摘 要
随着计算机技术的迅速发展,数字图像处理技术在医学领域的研究和应用日益深入和广泛。现代医学已越来越离不开医学图像处理技术。医学图像处理技术在临床诊断、教学科研等方面发挥了重要的作用。计算机图像处理技术与影像技术的结合从根本上改变了医务人员进行诊断的传统方式。充分地利用这些技术可以提高诊断的正确性和准确性,提高诊断效率,降低医疗成本,可以更加充分地发挥各种医疗设备的功能。而且,随着数字化、智能化进程的深人,图像处理技术在医疗卫生领域将会有更加广阔的应用前景。
Java是Sun公司推出的一种面向对象编程语言。Java非常适合于企业网络和Internet环境现已成为Internet中最受欢迎、最有影响的编程语言之一。目前国内使用Java语言开发的图像处理系统比较少这也增加了这方面的研究价值。
本文首先对图像增强和图像分割中的几种算法进行了介绍包括线性灰度变换伪彩色处理平滑处理中值滤波阈值分割边缘检测等。然后用Java语言对上述各算法编程实现并设计Java GUI图形用户界面用来显示图像处理的结果以及创建一个数据库用于存储医学图像。
**关键词:**医学图像;图像增强;图像分割;面向对象
# 1 医学图像处理概述
近年来,随着计算机及其相关技术的迅速发展,图像处理技术日益成熟,使得该技术深入到医学领域的方方面面,开创了数字医疗的新时代。
借助图像处理技术的有力手段,医学图像的质量和显示方法可以得到极大的改善,从而使得诊断水平可以借助于图像处理与分析手段来得到极大的改善,这不仅可以基于现有的医学图像设备来极大地提高医学临床诊断水平,而且能为医学培训、医学研究与教学、计算机辅助临床外科手术等提供电子实现手段,为医学的研究与发展提供坚实的基础,具有无可估量的价值。
# 2 Java语言实现图像处理
## 2.1 图像增强技术
数字图像的增强是图像处理中的一个重要研究内容之一,是图像处理的一项基本技术。图像增强是指按特定的需要突出一幅图像的某些信息,同时,削弱或除去某些不需要的信息的处理方法。
图像增强在人眼对图像的识别中很重要。人眼有这样一视觉特性由人眼的视觉和人的心理特性可知变化幅度较大细节丰富的区域容易引起人眼的注意而变化平坦的区域则不容易注意。在人们对视觉的研究中进行过如下实验将两幅图同时放在测试者的视野中其中一幅有黑色线条另一幅全部都为白色用仪器分别记录下眼睛注视两幅图的时间结果表明了人眼有70%的时间在注视带线条的那一幅,这说明变化剧烈的图像更吸引人的注意力,对灰度图像而言,人眼会将注意力集中在灰度值变化大的区域。根据人眼的这一视觉特性,图像处理中对灰度图像的增强就是为了解决这一视觉上的障碍。
图像增强的方法分为两大类:空间域方法和频率域方法。
空间域增强是指增强构成图像的像素。空间域方法是直接对这些像素操作的过程。空间域处理可由下式定义:
![](http://www.write-bug.com/myres/static/uploads/2021/10/19/9fd4562c42978085a372319e1561877a.writebug)
其中fx,y是增强处理前的图像函数gx,y是增强处理后的图像函数T是对f的一种操作其定义在x,y的邻域。
频率域方法是在图像的某种变换域内对图像的变换值进行运算如fx,y表示增强处理前的图像函数hx,y表示空间运算函数增强处理后的图像函数gx,y是由fx,y和hx,y的卷积的
![](http://www.write-bug.com/myres/static/uploads/2021/10/19/75984e727886aa3fa40fe4c11f3e8f92.writebug)
根据卷积理论,在频域中有下面的变换关系
![](http://www.write-bug.com/myres/static/uploads/2021/10/19/dc8a8909d020d009c198d337c504d8e4.writebug)
这里G、H和F分别表示g、h和f的傅立叶变换H(u,v)称为传递函数。
在实际应用中可根据需要先对图像函数进行傅立叶变换并选定传递函数H(u,v)然后由计算出G(u,v),最后通过傅立叶反变换得出增强处理后的图像函数,即
![](http://www.write-bug.com/myres/static/uploads/2021/10/19/04964b6d579988d0345fd6e8f706824e.writebug)
### 2.1.1 灰度变换
如果一幅图像灰度的对比度差图像的质量就不好。为了改善图像灰度的对比度可以对图像中样点的灰度进行刻度尺方面的改变。假设fx,y和gx,y分别表示原始图像及增强处理后图像像素的灰度。这样使原始图像的像素灰度fx,y转换成增强后图像对应像素的灰度gx,y转换关系的一般表达式为
![](http://www.write-bug.com/myres/static/uploads/2021/10/19/7ee57cd406d44cbc9e7d66130e67519e.writebug)
线性灰度变换的一般表达式
![](http://www.write-bug.com/myres/static/uploads/2021/10/19/e9c9747989585fb3314140ba7c5022a4.writebug)
其中a为图像的对比度如果a>1对比度增强如果a<1对比度减弱
b为图像的亮度如果b>0,亮度增强如果b<0亮度降低
下面来看一下线性灰度变换的Java代码实现如下只列出如何实现算法的代码。
```java
red=(int)(a * red + b)
green=(int)(a * green + b)
blue=(int)(a * blue + b)
if(red>=255)
{
red=255
}
if(green>=255)
{
green=255
}
if(blue>=255)
{
blue=255
}
```
a是调整图像对比度的变量b是调整图像亮度的变量。由于R、G、B分量空间范围是0255所以需设置一个限定条件防止越界。
从下图中可以清晰的对比出经线性变换后的图像更容易观察出病灶,进而减少误诊率。左图为原始图像,右图为经线性灰度变换后图像。
![](http://www.write-bug.com/myres/static/uploads/2021/10/19/90272cad7d70b3a892904e94a840c0da.writebug)
上述所讨论的线性变换为正比变换,下面简要说明一下反比变换,在某些情况下,反比变换得到的图像更容易观察出病变。
灰度级范围为[0L-1]的图像反转变换的表达式为:
![](http://www.write-bug.com/myres/static/uploads/2021/10/19/2c0dfd8f6b072bdf13226aea9f4f0da8.writebug)
其中s和r分别表示处理前后的像素值。
用这种方式倒转图像的强度产生图像反转的对等图像。这种处理尤其适用于增强嵌入于图像暗色区域的白色或灰色细节特别是当黑色面积占主导地位时。一个例子示于下图原始图像为一乳房的数字X照片可看到有一小块病变。尽管事实上两幅图在视觉内容上都一样但注意在这种特殊情况下分析乳房组织结构时反转图像要容易得多。
![](http://www.write-bug.com/myres/static/uploads/2021/10/19/b638d5b85417b1d0ac734ae5172ccb7c.writebug)
下面来看一下反比变换的Java代码实现如下只列出了某一像素点反比变换代码。
```java
int red=255-cm.getRed(pixels[i*iw+j])
int green=255-cm.getGreen(pixels[i*iw+j])
int blue=255-cm.getBlue(pixels[i*iw+j])
```
### 2.1.2 伪彩色处理
伪彩色处理是用彩色来代替像素灰度值的一种技术。由于人眼对彩色的分辨率远高于对灰度差的分辨率,所以这种技术可用来识别灰度差较小的像素。这是一种视觉效果明显而技术又不是很复杂的图像增强技术。灰度图像中,如果相邻像素点的灰度相差不大,人眼将无法从图像中提取相应的信息,因为人眼分辨灰度的能力很差,一般只有几十个数量级,但是人眼对彩色信号的分辨率却很强,这样将黑白图像转换为彩色图像后,人眼可以提取更多的信息量。在转换过程中,对灰度图像中的每一个像素点,取得该点的灰度值并送入红、绿、蓝三个通道实施不同的变换,产生相应的红、绿、蓝的亮度值。
# 3 设计流程
## 3.1 主流程图
本系统的总体设计流程图如图所示
![](http://www.write-bug.com/myres/static/uploads/2021/10/19/c8d17e700129ed3ed61da83770493eb2.writebug)
程序设计流程图大体介绍:
首先设计Java GUI即Java用户图形界面对其中的按钮菜单添加事件监听器以便能够当用户触发事件做出相应的响应然后添加了文件选择器以及连接数据库并实现了数据库查询、插入功能使用户可以从本地磁盘或从数据库中查询图像。将图像显示在GUI后就可以通过相应的按钮对图像进行处理。
具体模块的实现将在以下几节中详细介绍。
## 3.2 图像处理界面
本设计的图形用户界面如图所示。
![](http://www.write-bug.com/myres/static/uploads/2021/10/19/98fa68eaf4e986a73fe6bc54aa1f34c5.writebug)
在这个界面中,无论是按钮还是菜单选项,都添加了监听器用来监听是否有事件发生,并且都有一个相应的事件处理器。当用户单击其中任何一个都会触发相应的事件,然后将事件发送到事件处理器中进行处理。界面的左侧用于显示载入的图像,即原始图像,右侧用于显示处理后图像,以便对处理前后的图像进行对比。
# 参考文献
[1] 刘榴娣,刘明奇.《实用数字图像处理》.第一版.北京理工大学出版社
[2] 章梳晋.《图像处理和分析》.第一版.清华大学出版社
[3] 陈浩,李本富.《医学图像处理技术新进展》.第四军医大学学报
[4] 林信良《Java JDK 5.0学习笔记》.清华大学出版社

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
src/医学图片/2per11.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
src/医学图片/2per14.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
src/医学图片/Thumbs.db Normal file

Binary file not shown.

BIN
src/医学图片/a.JPG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
src/医学图片/aaa.JPG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
src/医学图片/llung1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
src/医学图片/llung4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

BIN
src/文档.doc Normal file

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,938 @@
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import java.io.*;
import java.sql.*;
public class MedicalImageProcess extends JFrame implements ActionListener
{
JPanel jp1,jp11,jp111,jp112,jp2,jp21,jp211,jp212,northPanel,pictPanel,pict1,pict2;
JTabbedPane jtp;
JButton xianxing,fanzhuan,weicaise,pinghua,ruihua,zhongzhi,erzhihua,bianyuan;
TitledBorder titled1,titled2,titled3,titled4;
JSlider jSlider;
JMenuBar bar;
JMenu fileMenu,dataMenu;
JMenuItem openItem,exitItem,checkItem,insertItem;
JFileChooser chooser;
File file;
String filename;
Image im,tmp,tmp0;
int i,iw,ih;
int[] pixels;
Border etched1,etched2;
SoftBevelBorder softBevelBorder;
Connection con;
Statement stmt;
ResultSet rs;
String id,name,pi;
boolean flagGray = false;
boolean flagLoad = false;
boolean flag=false;
public MedicalImageProcess()
{
super("Java数字图像处理");
Container contents = getContentPane();//创建一个容器所有基本组件都放入其中
jtp = new JTabbedPane(SwingConstants.TOP);//创建一个可以在一组组件之间切换的选项卡
jp1 = new JPanel();
jp11 = new JPanel();
jp111 = new JPanel();
jp112 = new JPanel();
jp2 = new JPanel();
jp21 = new JPanel();
jp211 = new JPanel();
jp212 = new JPanel();
northPanel = new JPanel();
pictPanel = new JPanel();
pict1 = new JPanel();
pict2 = new JPanel();
jSlider = new JSlider(JSlider.HORIZONTAL,0,255,100);//创建一个通过移动滑块来选择值的组件
xianxing = new JButton("线性灰度变换");
fanzhuan = new JButton("反转灰度变换");
weicaise = new JButton("伪彩色处理");
pinghua = new JButton("平 滑 处 理");
ruihua = new JButton("锐 化 处 理");
zhongzhi = new JButton("中 值 滤 波");
erzhihua = new JButton("二值化处理");
bianyuan = new JButton("边 缘 检 测");
titled1 = new TitledBorder("图像灰度化及伪彩色处理");
titled2 = new TitledBorder("图像平滑锐化处理及其中值滤波");
titled3 = new TitledBorder("图像二值化处理");
titled4 = new TitledBorder("图像的Robert边缘检测");
softBevelBorder = new SoftBevelBorder(2,Color.black,Color.white);//实现凹凸斜面
init();
jp111.setBorder(titled1);//设置带标题边框的边框
jp112.setBorder(titled2);
jp211.setBorder(titled3);
jp212.setBorder(titled4);
jSlider.setMajorTickSpacing(50);//设置主刻度标记间隔
jSlider.setMinorTickSpacing(10);//设置次刻度标记间隔
jSlider.setPaintTicks(true);//设置在滑块上绘制刻度标记
jSlider.setPaintTrack(true);//通知是否绘制滑块
jSlider.setPaintLabels(true);//通知是否绘制标签
jp111.add(xianxing);
jp111.add(fanzhuan);
jp111.add(weicaise);
jp112.add(pinghua);
jp112.add(ruihua);
jp112.add(zhongzhi);
jp11.setLayout(new GridLayout(1,2));
jp11.add(jp111);
jp11.add(jp112);
jp211.add(jSlider);
jp211.add(erzhihua);
jp212.add(bianyuan);
jp21.setLayout(new GridLayout(1,2));
jp21.add(jp211);
jp21.add(jp212);
jp1.setLayout(new BorderLayout());
jp2.setLayout(new BorderLayout());
pictPanel.setBorder(softBevelBorder);
northPanel.setLayout(new BorderLayout());
jp1.add(jp11);
jp2.add(jp21);
jtp.add("图 像 增 强",jp1);
jtp.add("图 像 分 割",jp2);
northPanel.add(jtp,BorderLayout.CENTER);
etched1 = BorderFactory.createEtchedBorder();//创建一个具有浮雕化外观效果的边框
etched2 = BorderFactory.createEtchedBorder();
pictPanel.setLayout(new GridLayout(0,2));
pict1.setBorder(etched1);
pict2.setBorder(etched2);
pictPanel.add(pict1);
pictPanel.add(pict2);
contents.add(northPanel,BorderLayout.NORTH);
contents.add(pictPanel,BorderLayout.CENTER);
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
con = DriverManager.getConnection("jdbc:odbc:image");
stmt = con.createStatement();
}
catch(Exception e){}
xianxing.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
jxianxing_ActionPerformed(e);
}
});
fanzhuan.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
jfanzhuan_ActionPerformed(e);
}
});
weicaise.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
jweicaise_ActionPerformed(e);
}
});
pinghua.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
jpinghua_ActionPerformed(e);
}
});
ruihua.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
jruihua_ActionPerformed(e);
}
});
zhongzhi.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
jzhongzhi_ActionPerformed(e);
}
});
jSlider.addChangeListener(new ChangeListener(){
public void stateChanged(ChangeEvent e)
{
jerzhihua_ActionPerformed(e);
}
});
erzhihua.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
jerzhihua_ActionPerformed(e);
}
});
bianyuan.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
jbianyuan_ActionPerformed(e);
}
});
}
public void init()
{
bar = new JMenuBar();//创建一个菜单栏
setJMenuBar( bar );
fileMenu = new JMenu("File");//创建菜单
fileMenu.setMnemonic('F');
openItem = new JMenuItem("Open");//菜单项
openItem.setMnemonic('O');
exitItem = new JMenuItem("Exit");
exitItem.setMnemonic('X');
dataMenu = new JMenu("Data");
dataMenu.setMnemonic('D');
checkItem = new JMenuItem("Check");
checkItem.setMnemonic('C');
insertItem = new JMenuItem("Insert");
insertItem.setMnemonic('I');
fileMenu.add(openItem);
fileMenu.add(exitItem);
dataMenu.add(checkItem);
dataMenu.add(insertItem);
bar.add(fileMenu);
bar.add(dataMenu);
openItem.addActionListener(this);
exitItem.addActionListener(this);
checkItem.addActionListener(this);
insertItem.addActionListener(this);
}
public void actionPerformed(ActionEvent event)
{
if(event.getSource() == openItem)
{
chooser = new JFileChooser("F:/");//文件选择器
chooser.addChoosableFileFilter(new MyFileFilter("jpg;gif", "图像文件"));
int returnVal = chooser.showOpenDialog(pictPanel);
if(returnVal == JFileChooser.APPROVE_OPTION)//选择确认yesok后返回该值
{
file = chooser.getSelectedFile();//返回选中的文件
filename = file.getPath();//将此抽象路径名转换为一个路径名字符串
jLoad_ActionPerformed(event);
}
}
else if(event.getSource() == exitItem)
{
int i = JOptionPane.showConfirmDialog(null,"要退出系统吗?","退出系统",2,2);
if(i == 0)//如果用户按的是确定
{
try
{
rs.close(); //关闭记录集
stmt.close(); //关闭Statement对象
con.close(); //关闭数据库链接
}
catch(Exception e6){}
this.dispose();//释放资源
System.exit(0);
}
}
else if(event.getSource() == checkItem)
{
try
{
int rec=0;
String s=JOptionPane.showInputDialog(null,"请输入ID");
rs = stmt.executeQuery("SELECT ID, 姓名,图片 FROM pic");
while (rs.next())
{
id= rs.getString("ID");
name= rs.getString("姓名");
pi=rs.getString("图片");
if(id.equals(s.trim()))
{
filename=pi;
jLoad_ActionPerformed(event);
rec=1;
break;
}
}
if(rec==0)JOptionPane.showMessageDialog(null,"数据库中没有此图片");
rs.close();
}
catch(Exception e2){}
}
else if(event.getSource() == insertItem)
{
try
{
String s1=JOptionPane.showInputDialog(null,"请输入ID");
String s2 = JOptionPane.showInputDialog(null,"请输入姓名");
String strInc = "INSERT INTO pic(ID,姓名,图片) Values('"+s1+"','"+s2+"','"+filename+"')";
stmt.executeUpdate(strInc);
}
catch(Exception e3){}
finally{
JOptionPane.showMessageDialog(null,"图像已添加进数据库");
}
}
}
public void jLoad_ActionPerformed(ActionEvent e)
{
//利用MediaTracker跟踪图像的加载
MediaTracker tracker = new MediaTracker(this);
im=Toolkit.getDefaultToolkit().getImage(filename);
tracker.addImage(im,0);//im为跟踪的图像0为所跟踪图像标识符
//等待图像的完全加载
try{
tracker.waitForID(0);//此0与上面的0对应
}catch(InterruptedException e2){ e2.printStackTrace();}//将中断输出至标准错误流
//获取图像的宽度iw和高度ih
iw=im.getWidth(this);
ih=im.getHeight(this);
pixels=new int[iw*ih];
try{//从im中获得图像的像素子集存储在pixels数组中
PixelGrabber pg=new PixelGrabber(im,0,0,iw,ih,pixels,0,iw);
pg.grabPixels();//请求Image开始传递像素
}catch (InterruptedException e3) {
e3.printStackTrace();
}
//将数组中的象素产生一个图像默认使用RGB
ImageProducer ip=new MemoryImageSource(iw,ih,pixels,0,iw);
tmp=createImage(ip);//由指定的图像生成器ip创建一幅图像
flagLoad = true;
repaint();
}
public void jxianxing_ActionPerformed(ActionEvent e)
{
if(flagLoad)
{
try{
PixelGrabber pg=new PixelGrabber(im,0,0,iw,ih,pixels,0,iw);
pg.grabPixels();
}catch (InterruptedException e3) {
e3.printStackTrace();
}
// ColorModel 抽象类封装了将像素值转换为颜色分量例如红色绿色和蓝色 alpha 分量的方法
ColorModel cm=ColorModel.getRGBdefault();//返回描述默认 RGB 值的对象
for(i=0;i<ih*iw;i++)
{
int alpha=cm.getAlpha(pixels[i]);
int red=cm.getRed(pixels[i]);
int green=cm.getGreen(pixels[i]);
int blue=cm.getBlue(pixels[i]);
red=(int)(1.1*red+20);
green=(int)(1.1*green+20);
blue=(int)(1.1*blue+20);
if(red>=255){red=255;}
if(green>=255){green=255;}
if(blue>=255){blue=255;}
pixels[i]=alpha<<24|red<<16|green<<8|blue;
}
//将数组中的象素产生一个图像
ImageProducer ip=new MemoryImageSource(iw,ih,pixels,0,iw);
tmp0=createImage(ip);
flagGray=true;
flag = true;
repaint();
}else{
JOptionPane.showMessageDialog(null,"请先打开一幅图片!",
"提示",JOptionPane.WARNING_MESSAGE);
}
}
public void jfanzhuan_ActionPerformed(ActionEvent e)
{
if(flagLoad)
{
try{
PixelGrabber pg=new PixelGrabber(im,0,0,iw,ih,pixels,0,iw);
pg.grabPixels();
}catch (InterruptedException e3) {
e3.printStackTrace();
}
// ColorModel 抽象类封装了将像素值转换为颜色分量例如红色绿色和蓝色 alpha 分量的方法
ColorModel cm=ColorModel.getRGBdefault();//返回描述默认 RGB 值的对象
for(i=0;i<ih;i++)
{
for(int j=0;j<iw;j++)
{
int alpha=cm.getAlpha(pixels[i*iw+j]);
int red=255-cm.getRed(pixels[i*iw+j]);
int green=255-cm.getGreen(pixels[i*iw+j]);
int blue=255-cm.getBlue(pixels[i*iw+j]);
pixels[i*iw+j]=alpha<<24|red<<16|green<<8|blue;
}
}
//将数组中的象素产生一个图像
ImageProducer ip=new MemoryImageSource(iw,ih,pixels,0,iw);
tmp0=createImage(ip);
flagGray=true;
flag = true;
repaint();
}else{
JOptionPane.showMessageDialog(null,"请先打开一幅图片!",
"提示",JOptionPane.WARNING_MESSAGE);
}
}
public void jweicaise_ActionPerformed(ActionEvent e)
{
if(flagLoad)
{
try{
PixelGrabber pg=new PixelGrabber(im,0,0,iw,ih,pixels,0,iw);
pg.grabPixels();
}catch (InterruptedException e3)
{
e3.printStackTrace();
}
ColorModel cm=ColorModel.getRGBdefault();
for(int i=0;i<ih;i++)
{
for(int j=0;j<iw;j++)
{
int grey = pixels[i*iw+j]&0xff;
int alpha=cm.getAlpha(pixels[i*iw+j]);
int red,green ,blue ;
//方法1
/* if(grey<64)
{
red = 0;
green = 4 * grey;
blue = 255;
}
else if(grey<128)
{
red = 0;
green = 255;
blue = (127-grey)*4;
}
else if(grey<192)
{
red = (grey-128)*4;
green = 255;
blue = 0;
}
else
{
red = 255;
green = (255-grey)*4;
blue = 0;
}
*/
//方法2
/* switch(grey/64)
{
case 0:red = 0;green = 4 * green;blue = 255;break;
case 1:red = 0;green = 255;blue = 511 - 4 * grey;break;
case 2:red = 4 * grey - 511;green = 255;blue = 0;break;
case 3:red = 255;green = 1023 - 4 * grey;blue = 0;break;
}
*/
// pixels[i*iw+j]=alpha<<24|red<<16|green<<8|blue;
//方法3
/* int[] colorTable = {0x000000,0x000055,0x005500,0x550000,0x3F3F3F,0x550055,0x0000FF,
0x555500,0x00FF00,0xFF0000,0x808080,0x00FFFF,0xFFFF00,0xFFFFFF,0x005555,0xFF00FF};
int newGrey = grey * 16 / 255;
pixels[i*iw+j]=alpha<<24|colorTable[newGrey];
*/
//方法(4)
int[] colorTable = {0x000000,0x0000a8,0x00a800,0x00a8a8,0xa80000,0xa800a8,0xa85400,0xa8a8a8,
0x545454,0x5454fc,0x54fc54,0x54fcfc,0xfc5454,0xfc54fc,0xfcfc54,0xfcfcfc,
0x000000,0x141414,0x202020,0x2c2c2c,0x383838,0x444444,0x505050,0x606060,
0x707070,0x808080,0x909090,0xa0a0a0,0xb4b4b4,0xc8c8c8,0xe0e0e0,0xfcfcfc,
0x0000fc,0x4000fc,0x7c00fc,0xbc00fc,0xfc00fc,0xfc00bc,0xfc007c,0xfc0040,
0xfc0000,0xfc4000,0xfc7c00,0xfcbc00,0xfcfc00,0xbcfc00,0x7cfc00,0x40fc00,
0x00fc00,0x00fc40,0x00fc7c,0x00fcbc,0x00fcfc,0x00bcfc,0x007cfc,0x0040fc,
0x7c7cfc,0x9c7cfc,0xbc7cfc,0xdc7cfc,0xfc7cfc,0xfc7cdc,0xfc7cbc,0xfc7c9c,
0xfc7c7c,0xfc9c7c,0xfcbc7c,0xfcdc7c,0xfcfc7c,0xdcfc7c,0xbcfc7c,0x9cfc7c,
0x7cfc7c,0x7cfc9c,0x7cfcbc,0x7cfcdc,0x7cfcfc,0x7cdcfc,0x7cbcfc,0x7c9cfc,
0xb4b4fc,0xc4b4fc,0xd8b4fc,0xe8b4fc,0xfcb4fc,0xfcb4e8,0xfcb4d8,0xfcb4c4,
0xfcb4b4,0xfcc4b4,0xfcd8b4,0xfce8b4,0xfcfcb4,0xe8fcb4,0xd8fcb4,0xc4fcb4,
0xb4fcb4,0xb4fcc4,0xb4fcd8,0xb4fce8,0xb4fcfc,0xb4e8fc,0xb4d8fc,0xb4c4fc,
0x000070,0x1c0070,0x380070,0x540070,0x700070,0x700054,0x700038,0x70001c,
0x700000,0x701c00,0x703800,0x705400,0x707000,0x547000,0x387000,0x1c7000,
0x007000,0x00701c,0x007038,0x007054,0x007070,0x005470,0x003870,0x001c70,
0x383870,0x443870,0x543870,0x603870,0x703870,0x703860,0x703854,0x703844,
0x703838,0x704438,0x705438,0x706038,0x707038,0x607038,0x547038,0x447038,
0x387038,0x387044,0x387054,0x387060,0x387070,0x386070,0x385470,0x384470,
0x505070,0x585070,0x605070,0x685070,0x705070,0x705068,0x705060,0x705058,
0x705050,0x705850,0x706050,0x706850,0x707050,0x687050,0x607050,0x587050,
0x507050,0x507058,0x507060,0x507068,0x507070,0x506870,0x506070,0x505870,
0x000040,0x100040,0x200040,0x300040,0x400040,0x400030,0x400020,0x400010,
0x400000,0x401000,0x402000,0x403000,0x404000,0x304000,0x204000,0x104000,
0x004000,0x004010,0x004020,0x004030,0x004040,0x003040,0x002040,0x001040,
0x202040,0x282040,0x302040,0x382040,0x402040,0x402038,0x402030,0x402028,
0x402020,0x402820,0x403020,0x403820,0x404020,0x384020,0x304020,0x284020,
0x204020,0x204028,0x204030,0x204038,0x204040,0x203840,0x203040,0x202840,
0x2c2c40,0x302c40,0x342c40,0x3c2c40,0x402c40,0x402c3c,0x402c34,0x402c30,
0x402c2c,0x40302c,0x40342c,0x403c2c,0x40402c,0x3c402c,0x34402c,0x30402c,
0x2c402c,0x2c4030,0x2c4034,0x2c403c,0x2c4040,0x2c3c40,0x2c3440,0x2c3040,
0x000000,0x000000,0x000000,0x000000,0x000000,0x000000,0x000000,0x000000};
if(grey<16)
{
pixels[i*iw+j]=alpha<<24|colorTable[grey];
}
if(grey>=16&&grey<255)
{
pixels[i*iw+j]=alpha<<24|colorTable[30+grey/4];
}
}
}
//将数组中的象素产生一个图像
ImageProducer ip=new MemoryImageSource(iw,ih,pixels,0,iw);
tmp0=createImage(ip);
flag=true;
repaint();
}else{
JOptionPane.showMessageDialog(null,"请先打开一幅图片!",
"提示",JOptionPane.WARNING_MESSAGE);
}
}
public void jpinghua_ActionPerformed(ActionEvent e)
{
if(flagLoad)
{
try{
PixelGrabber pg=new PixelGrabber(im,0,0,iw,ih,pixels,0,iw);
pg.grabPixels();
}catch (InterruptedException e3) {
e3.printStackTrace();
}
//对图像进行平滑化处理Alpha值保持不变
ColorModel cm=ColorModel.getRGBdefault();
for(int i=1;i<ih-1;i++)
{
for(int j=1;j<iw-1;j++)
{
int alpha=cm.getAlpha(pixels[i*iw+j]);
int red=cm.getRed(pixels[i*iw+j]);
int green=cm.getGreen(pixels[i*iw+j]);
int blue=cm.getBlue(pixels[i*iw+j]);
//对图像进行平滑
int red1=cm.getRed(pixels[(i-1)*iw+j-1]);
int red2=cm.getRed(pixels[(i-1)*iw+j]);
int red3=cm.getRed(pixels[(i-1)*iw+j+1]);
int red4=cm.getRed(pixels[i*iw+j-1]);
int red6=cm.getRed(pixels[i*iw+j+1]);
int red7=cm.getRed(pixels[(i+1)*iw+j-1]);
int red8=cm.getRed(pixels[(i+1)*iw+j]);
int red9=cm.getRed(pixels[(i+1)*iw+j+1]);
int averageRed=(red1+red2+red3+red4+red6+red7+red8+red9)/8;
int green1=cm.getGreen(pixels[(i-1)*iw+j-1]);
int green2=cm.getGreen(pixels[(i-1)*iw+j]);
int green3=cm.getGreen(pixels[(i-1)*iw+j+1]);
int green4=cm.getGreen(pixels[i*iw+j-1]);
int green6=cm.getGreen(pixels[i*iw+j+1]);
int green7=cm.getGreen(pixels[(i+1)*iw+j-1]);
int green8=cm.getGreen(pixels[(i+1)*iw+j]);
int green9=cm.getGreen(pixels[(i+1)*iw+j+1]);
int averageGreen=(green1+green2+green3+green4+green6+green7+green8+green9)/8;
int blue1=cm.getBlue(pixels[(i-1)*iw+j-1]);
int blue2=cm.getBlue(pixels[(i-1)*iw+j]);
int blue3=cm.getBlue(pixels[(i-1)*iw+j+1]);
int blue4=cm.getBlue(pixels[i*iw+j-1]);
int blue6=cm.getBlue(pixels[i*iw+j+1]);
int blue7=cm.getBlue(pixels[(i+1)*iw+j-1]);
int blue8=cm.getBlue(pixels[(i+1)*iw+j]);
int blue9=cm.getBlue(pixels[(i+1)*iw+j+1]);
int averageBlue=(blue1+blue2+blue3+blue4+blue6+blue7+blue8+blue9)/8;
pixels[i*iw+j]=alpha<<24|averageRed<<16|averageGreen<<8|averageBlue;
}
}
//将数组中的象素产生一个图像
ImageProducer ip=new MemoryImageSource(iw,ih,pixels,0,iw);
tmp0=createImage(ip);
flag=true;
repaint();
}else{
JOptionPane.showMessageDialog(null,"请先打开一幅图片!",
"提示",JOptionPane.WARNING_MESSAGE);
}
}
public void jruihua_ActionPerformed(ActionEvent e)
{
if(flagLoad)
{
try{
PixelGrabber pg=new PixelGrabber(im,0,0,iw,ih,pixels,0,iw);
pg.grabPixels();
}catch (InterruptedException e3) {
e3.printStackTrace();
}
//对图像进行尖锐化处理Alpha值保持不变
ColorModel cm=ColorModel.getRGBdefault();
for(int i=1;i<ih-1;i++)
{
for(int j=1;j<iw-1;j++)
{
int alpha=cm.getAlpha(pixels[i*iw+j]);
//对图像进行尖锐化
int red6=cm.getRed(pixels[i*iw+j+1]);
int red5=cm.getRed(pixels[i*iw+j]);
int red8=cm.getRed(pixels[(i+1)*iw+j]);
int sharpRed=Math.abs(red6-red5)+Math.abs(red8-red5);
int green5=cm.getGreen(pixels[i*iw+j]);
int green6=cm.getGreen(pixels[i*iw+j+1]);
int green8=cm.getGreen(pixels[(i+1)*iw+j]);
int sharpGreen=Math.abs(green6-green5)+Math.abs(green8-green5);
int blue5=cm.getBlue(pixels[i*iw+j]);
int blue6=cm.getBlue(pixels[i*iw+j+1]);
int blue8=cm.getBlue(pixels[(i+1)*iw+j]);
int sharpBlue=Math.abs(blue6-blue5)+Math.abs(blue8-blue5);
if(sharpRed>255) {sharpRed=255;}
if(sharpGreen>255) {sharpGreen=255;}
if(sharpBlue>255) {sharpBlue=255;}
pixels[i*iw+j]=alpha<<24|sharpRed<<16|sharpGreen<<8|sharpBlue;
}
}
//将数组中的象素产生一个图像
ImageProducer ip=new MemoryImageSource(iw,ih,pixels,0,iw);
tmp0=createImage(ip);
flag=true;
repaint();
}else{
JOptionPane.showMessageDialog(null,"请先打开一幅图片!",
"提示",JOptionPane.WARNING_MESSAGE);
}
}
public void jzhongzhi_ActionPerformed(ActionEvent e)
{
if(flagLoad)
{
try{
PixelGrabber pg=new PixelGrabber(im,0,0,iw,ih,pixels,0,iw);
pg.grabPixels();
}catch (InterruptedException e3) {
e3.printStackTrace();
}
//对图像进行中值滤波Alpha值保持不变
ColorModel cm=ColorModel.getRGBdefault();
for(int i=1;i<ih-1;i++)
{
for(int j=1;j<iw-1;j++)
{
int red,green,blue;
int alpha=cm.getAlpha(pixels[i*iw+j]);
int red2=cm.getRed(pixels[(i-1)*iw+j]);
int red4=cm.getRed(pixels[i*iw+j-1]);
int red5=cm.getRed(pixels[i*iw+j]);
int red6=cm.getRed(pixels[i*iw+j+1]);
int red8=cm.getRed(pixels[(i+1)*iw+j]);
//水平方向进行中值滤波
if(red4>=red5){
if(red5>=red6) {red=red5;}
else{
if(red4>=red6) {red=red6;}
else{red=red4;}
}}
else{
if(red4>red6) {red=red4;}
else{
if(red5>red6) {red=red6;}
else{red=red5;}
}}
int green2=cm.getGreen(pixels[(i-1)*iw+j]);
int green4=cm.getGreen(pixels[i*iw+j-1]);
int green5=cm.getGreen(pixels[i*iw+j]);
int green6=cm.getGreen(pixels[i*iw+j+1]);
int green8=cm.getGreen(pixels[(i+1)*iw+j]);
//水平方向进行中值滤波
if(green4>=green5){
if(green5>=green6) {green=green5;}
else{
if(green4>=green6) {green=green6;}
else{green=green4;}
}}
else{
if(green4>green6) {green=green4;}
else{
if(green5>green6) {green=green6;}
else{green=green5;}
}}
int blue2=cm.getBlue(pixels[(i-1)*iw+j]);
int blue4=cm.getBlue(pixels[i*iw+j-1]);
int blue5=cm.getBlue(pixels[i*iw+j]);
int blue6=cm.getBlue(pixels[i*iw+j+1]);
int blue8=cm.getBlue(pixels[(i+1)*iw+j]);
//水平方向进行中值滤波
if(blue4>=blue5){
if(blue5>=blue6) {blue=blue5;}
else{
if(blue4>=blue6) {blue=blue6;}
else{blue=blue4;}
}}
else{
if(blue4>blue6) {blue=blue4;}
else{
if(blue5>blue6) {blue=blue6;}
else{blue=blue5;}
}}
pixels[i*iw+j]=alpha<<24|red<<16|green<<8|blue;
}
}
//将数组中的象素产生一个图像
ImageProducer ip=new MemoryImageSource(iw,ih,pixels,0,iw);
tmp0=createImage(ip);
flag=true;
repaint();
}else{
JOptionPane.showMessageDialog(null,"请先打开一幅图片!",
"提示",JOptionPane.WARNING_MESSAGE);
}
}
public void jerzhihua_ActionPerformed(ChangeEvent e)
{
if(flagLoad)
{
try{
PixelGrabber pg=new PixelGrabber(im,0,0,iw,ih,pixels,0,iw);
pg.grabPixels();
}catch (InterruptedException e3) {
e3.printStackTrace();
}
//设定二值化的域值默认值为100
int grey=jSlider.getValue();
//对图像进行二值化处理Alpha值保持不变
ColorModel cm=ColorModel.getRGBdefault();
for(int i=0;i<iw*ih;i++)
{
int red,green,blue;
int alpha=cm.getAlpha(pixels[i]);
if(cm.getRed(pixels[i])>grey)
{
red = 255;
}else{ red=0;}
if(cm.getGreen(pixels[i])>grey)
{
green=255;
}else{green=0;}
if(cm.getBlue(pixels[i])>grey)
{
blue=255;
}else{blue=0;}
pixels[i]=alpha<<24|red<<16|green<<8|blue;
}
//将数组中的象素产生一个图像
ImageProducer ip=new MemoryImageSource(iw,ih,pixels,0,iw);
tmp0=createImage(ip);
flag = true;
repaint();
}else{
JOptionPane.showMessageDialog(null,"请先打开一幅图片!",
"提示",JOptionPane.WARNING_MESSAGE);
}
}
public void jerzhihua_ActionPerformed(ActionEvent e)
{
if(flagLoad)
{
try{
PixelGrabber pg=new PixelGrabber(im,0,0,iw,ih,pixels,0,iw);
pg.grabPixels();
}catch (InterruptedException e3) {
e3.printStackTrace();
}
//设定二值化的域值默认值为100
int grey=100;
Object tmpGrey="100";
String s=JOptionPane.showInputDialog(null,"输入二值化的域值0-255",tmpGrey);
if(s!=null)
{
grey=Integer.parseInt(s);
}
if(grey>255)
{
grey=255;
}else if(grey<0)
{
grey=0;
}
//对图像进行二值化处理Alpha值保持不变
ColorModel cm=ColorModel.getRGBdefault();
for(int i=0;i<iw*ih;i++)
{
int red,green,blue;
int alpha=cm.getAlpha(pixels[i]);
if(cm.getRed(pixels[i])>grey)
{
red = 255;
}else{ red=0;}
if(cm.getGreen(pixels[i])>grey)
{
green=255;
}else{green=0;}
if(cm.getBlue(pixels[i])>grey)
{
blue=255;
}else{blue=0;}
pixels[i]=alpha<<24|red<<16|green<<8|blue;
}
//将数组中的象素产生一个图像
ImageProducer ip=new MemoryImageSource(iw,ih,pixels,0,iw);
tmp0=createImage(ip);
flag = true;
repaint();
}else{
JOptionPane.showMessageDialog(null,"请先打开一幅图片!",
"提示",JOptionPane.WARNING_MESSAGE);
}
}
public void jbianyuan_ActionPerformed(ActionEvent e)
{
if(flagLoad)
{
try{
PixelGrabber pg=new PixelGrabber(im,0,0,iw,ih,pixels,0,iw);
pg.grabPixels();
}catch (InterruptedException e3) {
e3.printStackTrace();
}
//对图像进行边缘提取Alpha值保持不变
ColorModel cm=ColorModel.getRGBdefault();
for(i=1;i<ih-1;i++)
{
for(int j=1;j<iw-1;j++)
{
//对图像进行边缘提取
int alpha=cm.getAlpha(pixels[i*iw+j]);
int red5=cm.getRed(pixels[i*iw+j]);
int red6=cm.getRed(pixels[i*iw+j+1]);
int red8=cm.getRed(pixels[(i+1)*iw+j]);
int red9=cm.getRed(pixels[(i+1)*iw+j+1]);
int robertRed=Math.max(Math.abs(red5-red9),Math.abs(red8-red6));
int green5=cm.getGreen(pixels[i*iw+j]);
int green6=cm.getGreen(pixels[i*iw+j+1]);
int green8=cm.getGreen(pixels[(i+1)*iw+j]);
int green9=cm.getGreen(pixels[(i+1)*iw+j+1]);
int robertGreen=Math.max(Math.abs(green5-green9),Math.abs(green8-green6));
int blue5=cm.getBlue(pixels[i*iw+j]);
int blue6=cm.getBlue(pixels[i*iw+j+1]);
int blue8=cm.getBlue(pixels[(i+1)*iw+j]);
int blue9=cm.getBlue(pixels[(i+1)*iw+j+1]);
int robertBlue=Math.max(Math.abs(blue5-blue9),Math.abs(blue8-blue6));
pixels[i*iw+j]=alpha<<24|robertRed<<16|robertGreen<<8|robertBlue;
}
}
//将数组中的象素产生一个图像
ImageProducer ip=new MemoryImageSource(iw,ih,pixels,0,iw);
tmp0=createImage(ip);
flag = true;
repaint();
}else{
JOptionPane.showMessageDialog(null,"请先打开一幅图片!",
"提示",JOptionPane.WARNING_MESSAGE);
}
}
public void paint(Graphics g)
{
if(flagLoad)
{
g.drawImage(tmp,9,171,this);
}
if(flagLoad&&flag)
{
g.drawImage(tmp0,9+pict1.getWidth(),171,this);
}
}
public static void main(String[] args)
{
MedicalImageProcess mig = new MedicalImageProcess();
mig.setLocation(30,30);
mig.setSize(964,708);
mig.setVisible(true);
}
}

Binary file not shown.

View File

@ -0,0 +1,43 @@
import java.io.File;
import javax.swing.filechooser.FileFilter;
import java.util.Vector;
import java.util.StringTokenizer;
import java.util.*;
//文件过滤器
public class MyFileFilter extends FileFilter
{
Vector extensions = new Vector(); //构造一个空向量使其内部数据数组的大小为 10
String description;
public MyFileFilter(String extensions,String description)
{
super(); //将字符串分解为标记
StringTokenizer stringTokenizer = new StringTokenizer(extensions,";");
while(stringTokenizer.hasMoreElements()) //测试是否包含更多的元素
this.extensions.add(stringTokenizer.nextElement());
this.description = description;
}
public boolean accept(File file)
{
if(file.isDirectory())
return true;
String fileName = file.getName();
int periodIndex = fileName.lastIndexOf(".");
if(periodIndex > 0 && periodIndex < fileName.length() - 1)
{
String extension = fileName.substring(periodIndex + 1).toLowerCase();
for(int i = 0;i < extensions.size();i++)
if(extension.equals(extensions.elementAt(i)))
return true;
}
return false;
}
public String getDescription()
{
String s = "";
for(int i = 0;i < extensions.size();i++)
s += "*." + extensions.elementAt(i) + " ; ";
return description + "(" + s + ")";
}
}

BIN
src/系统/Thumbs.db Normal file

Binary file not shown.

BIN
src/系统/image.mdb Normal file

Binary file not shown.