⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mypanel.java

📁 维纳滤波
💻 JAVA
字号:
/**
 * MyPanel.java
 * 
 * 该类显示两个图片:滤波前和滤波后的图片
 * 用函数WFilter来对图片进行滤波处理
 * 由于JAVA的Image类不直接支持bmp位图,所以要自己编写代码来显示位图
 *
 * Copyright 2004 by 海南大学信息学院
 * @author 温小斌
 * @version 1.0
 */

import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.io.*;
import javax.swing.*;
import java.awt.color.*;

public class MyPanel extends JPanel
{
	BufferedImage image;

	FileInputStream fs;
	int bflen=14; // 14 字节 BitmapFileHeader
	byte bf[]=new byte[bflen];
	int bilen=40; // 40 字节 BitmapInfoHeader
	byte bi[]=new byte[bilen];
	int nsize;
	int nbisize;
	int nwidth;
	int nheight;
	int nplanes;//位面数总为1
	int nbitcount;//比特数/象素
	int ncompression;//压缩数据
	int nsizeimage;
	int nxpm;
	int nypm;
	int nclrused;//使用的颜色索引
	int nclrimp;//重要颜色索引
	int nNumColors = 0;
	int npalette[];
	byte bpalette[];//调色板范围
	int npad8;
	int ndata8[];
	byte bdata[];

	protected void paintComponent(Graphics g)  //重画,刷新
	{
		super.paintComponent(g);
		if (image != null)
			g.drawImage(image, 0, 0, null);
	}

   public void loadImage(String name, boolean filter, float a, float q, float c, float r) //参数name表示文件名,filter表示是否滤波
   {  
	   // 调用图像,在这之前需要先调用自定义的loadBitmap函数,这是因为JAVA不直接支持bmp位图
      Image loadedImage
         = loadBitmap(name, filter, a, q, c, r);
      MediaTracker tracker = new MediaTracker(this);
      tracker.addImage(loadedImage, 0);
      try { tracker.waitForID(0); }
      catch (InterruptedException e) {}
      //调入图像缓冲
      image = new BufferedImage(loadedImage.getWidth(null), loadedImage.getHeight(null), BufferedImage.TYPE_INT_BGR);
      Graphics2D g2 = image.createGraphics();
      g2.drawImage(loadedImage, 0, 0, null);
      repaint();  //调用paintComponent刷新窗口
   }

   public Image loadBitmap(String name, boolean filter, float a, float q, float c, float r)
	{
	   Image bitmap;

	   try{
			fs=new FileInputStream(name);
			fs.read(bf,0,bflen);
			fs.read(bi,0,bilen);

			//解释数据
			nsize = (((int)bf[5]&0xff)<<24) | (((int)bf[4]&0xff)<<16) | (((int)bf[3]&0xff)<<8) | (int)bf[2]&0xff;
			nbisize = (((int)bi[3]&0xff)<<24) | (((int)bi[2]&0xff)<<16) | (((int)bi[1]&0xff)<<8) | (int)bi[0]&0xff;
			nwidth = (((int)bi[7]&0xff)<<24) | (((int)bi[6]&0xff)<<16) | (((int)bi[5]&0xff)<<8) | (int)bi[4]&0xff;
			nheight = (((int)bi[11]&0xff)<<24) | (((int)bi[10]&0xff)<<16) | (((int)bi[9]&0xff)<<8) | (int)bi[8]&0xff;
			nplanes = (((int)bi[13]&0xff)<<8) | (int)bi[12]&0xff;
			nbitcount = (((int)bi[15]&0xff)<<8) | (int)bi[14]&0xff;
			ncompression = (((int)bi[19])<<24) | (((int)bi[18])<<16) | (((int)bi[17])<<8) | (int)bi[16];
			nsizeimage = (((int)bi[23]&0xff)<<24) | (((int)bi[22]&0xff)<<16) | (((int)bi[21]&0xff)<<8) | (int)bi[20]&0xff;
			nxpm = (((int)bi[27]&0xff)<<24) | (((int)bi[26]&0xff)<<16) | (((int)bi[25]&0xff)<<8) | (int)bi[24]&0xff;
			nypm = (((int)bi[31]&0xff)<<24) | (((int)bi[30]&0xff)<<16) | (((int)bi[29]&0xff)<<8) | (int)bi[28]&0xff;
			nclrused = (((int)bi[35]&0xff)<<24) | (((int)bi[34]&0xff)<<16) | (((int)bi[33]&0xff)<<8) | (int)bi[32]&0xff;
			nclrimp = (((int)bi[39]&0xff)<<24) | (((int)bi[38]&0xff)<<16) | (((int)bi[37]&0xff)<<8) | (int)bi[36]&0xff;
			if (nbitcount == 8)  //如果是256色位图
		   {
				if (nclrused > 0)//clrused 为0表示使用所有调色板项
					nNumColors = nclrused;
				else
					nNumColors = (1&0xff)<<nbitcount;
				
				// 读取调色板颜色。
				npalette = new int [nNumColors];
				bpalette = new byte [nNumColors*4];
				fs.read (bpalette, 0, nNumColors*4);
				int nindex8 = 0;
				for (int n = 0; n < nNumColors; n++)
				{
					npalette[n] = (255&0xff)<<24 | (((int)bpalette[nindex8+2]&0xff)<<16) | (((int)bpalette[nindex8+1]&0xff)<<8) | (int)bpalette[nindex8]&0xff;
					nindex8 += 4;
				}
				
				// 读取图像数据(实际上是调色板的索引)
				// 扫描行仍被补足到 4 个字节。
				npad8 = (nsizeimage / nheight) - nwidth;
				ndata8 = new int [nwidth*nheight];
				bdata = new byte [(nwidth+npad8)*nheight];
				fs.read (bdata, 0, (nwidth+npad8)*nheight);
				nindex8 = 0;
				for (int j8 = 0; j8 < nheight; j8++)
				{
					for (int i8 = 0; i8 < nwidth; i8++)
					{
						if(filter)  //如果需要滤波,调用滤波函数WFilter
						{
							ndata8 [nwidth*(nheight-j8-1)+i8] = npalette [(WFilter(nindex8, a, q, c, r)&0xff)];
							nindex8++;
						}
						else  //如果不需要滤波
						{
							ndata8 [nwidth*(nheight-j8-1)+i8] = npalette [((int)bdata[nindex8]&0xff)];
							nindex8++;
						}
					}
					nindex8 += npad8;
				}
				bitmap = createImage(new MemoryImageSource(nwidth, nheight, ndata8, 0, nwidth));  //产生Image的对象bitmap
		   }
		   else
		   {
			   return (Image)null;
		   }
		   fs.close();
		   return bitmap;
		}
		catch(Exception e){
			System.err.println(e);
			return (Image)null;
		}
	}

	//维纳滤波函数
	public int WFilter(int n, float a, float q, float c, float r)
	{
		// x 为滤波器的输入信号
		float p;
		float p1, p2, p3, p4, p5;
		float g;
		float f;
		 //滤波器的冲激响应
		int j;
		int s[]; //滤波器的输出信号

		p1 = (a*a-1)*r;
		p2 = c*c*q;
		p3 = (a*a-1)*(a*a-1)*r*r;
		p4 = 2*c*c*r*q*(1+a*a);
		p5 = c*c*c*c*q*q;
		p = (float)((p1+p2+Math.sqrt(p3+p4+p5))/(2*a));

		g = (c*p)/(r+c*c*p);
		f = a*(1-c*g);

		/*
		for(int i=0; i<=n; i++)
		{
			s += g*(float)Math.pow(f, n)*bdata[n-i];
		}
		*/
		if(j=0)
		{
			s[j]=g*bdata[0];
		return Math.round(s);
	    }
		else
	   {
		for(int i=1;i<=n;i++)
		{j=i;
			s[j]=f*s[j-1]+g*bdata[i]

		/*s=g*f*bdata[n];*/
		
		return Math.round(s);
		}
	   }

	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -