基于内容的图像检索-聚类分析
来源:互联网 发布:新手如何经营淘宝 编辑:程序博客网 时间:2024/04/30 13:19
//导入必要的包
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.*;
import java.util.Scanner;
import java.util.Arrays;
import javax.swing.*;
import java.awt.*;
/**
*基于k-means的简单图像检索
* @author xuweibin
* */
class CBIR
{
private File srcFile; //图像路径
private boolean bFile;
private File[] file; //读入图片文件
private BufferedImage[] bi;
private int imNum; //图像个数
private int width; //图像宽度
private int height; //图像高度
private int minx; //图像最小横坐标
private int miny; //图像最小纵坐标
public int[][] rgb; //图像rgb颜色值
private double[][] rate; //图像频率数组
private static final int N=65536; //图像像素个数,256*256,可以智能化
private static final int M=8; //颜色级数,可以智能化
private static final int IN=6; //图像个数,可以改变
private static boolean[] flag; //标记数组
private int It1; //初始化簇1
private int It2; //初始化簇2
private double center1[]; //簇1中心
private double center2[]; //簇2中心
private double dis1; //到簇1中心的距离
private double dis2; //到簇2中心的距离
/**
*在构造函数中初始化
* */
public CBIR()
{
srcFile=null;
bFile=false;
file=null;
imNum=0;
width=0;
height=0;
minx=0;
miny=0;
rgb=null;
rate=null;
flag=null;
It1=It2=-1;
center1=center2=null;
dis1=dis2=0;
}
/**
*读入图像文件流
* */
public void readImage()
{
srcFile=new File("image/");
bFile=srcFile.exists();
if(!bFile||!srcFile.isDirectory()||!srcFile.canRead())
{
try{
srcFile.createNewFile();
}catch(IOException e){e.printStackTrace();}
}
else
{
file=srcFile.listFiles();
imNum=file.length;
}
}
/**
*获得图像的rgb,并转化为亮度值
* */
public void getRGB()
{
readImage();
bi=new BufferedImage[imNum];
for(int i=0;i<imNum;i++)
{
try{
bi[i]=ImageIO.read(file[i]);
}catch(IOException e){System.out.println(e);}
}
rgb=new int[imNum][];
for(int k=0;k<imNum;k++)
{
width=bi[k].getWidth();
height=bi[k].getHeight();
minx=bi[k].getMinX();
miny=bi[k].getMinY();
rgb[k]=new int[width*height];
int count=0;
for(int i=minx;i<width;i++)
for(int j=miny;j<height;j++)
{
int pixel=bi[k].getRGB(i,j);
int r=(pixel&0xff0000)>>16;
int g=(pixel&0xff00)>>8;
int b=(pixel&0xff);
rgb[k][count++]=(int)(r*0.299+g*0.586+b*0.114); //转化为亮度值
}
}
// for(int i=0;i<imNum;i++)
// for(int j=0;j<N;j++)
// {
// System.out.println(rgb[i][j]);
// }
}
/**
*获得图像的频率数组
* */
public void getRATE()
{
getRGB();
rate=new double[imNum][M];
for(int j=0;j<imNum;j++)
{
int[] temp=new int[M];
for(int i=0;i<M;i++)
temp[i]=0;
int sum=0;
for(int i=0;i<N;i++)
{
if(0<=rgb[j][i]&&rgb[j][i]<32)
temp[0]++;
else if(32<=rgb[j][i]&&rgb[j][i]<64)
temp[1]++;
else if(64<=rgb[j][i]&&rgb[j][i]<96)
temp[2]++;
else if(96<=rgb[j][i]&&rgb[j][i]<128)
temp[3]++;
else if(128<=rgb[j][i]&&rgb[j][i]<160)
temp[4]++;
else if(160<=rgb[j][i]&&rgb[j][i]<192)
temp[5]++;
else if(192<=rgb[j][i]&&rgb[j][i]<234)
temp[6]++;
else
temp[7]++;
sum++;
}
for(int i=0;i<M;i++)
{
rate[j][i]=temp[i]/(sum*1.0);
}
}
// for(int i=0;i<imNum;i++)
// {
// for(int j=0;j<M;j++)
// System.out.println(rate[i][j]);
// System.out.println();
// }
}
/**
*获得两个频率数组的距离
* */
public double getDistance(double[] r1,double[] r2)
{
double pe=0;
for(int i=0;i<M;i++)
{
pe+=Math.abs(r1[i]-r2[i]); //使用的是曼哈顿距离,也即城市街区距离
}
return pe;
}
/**
*获得初始化的簇中心
* */
public void getIntial()
{
getRATE();
Scanner input=new Scanner(System.in);
System.out.print("请输入初始化簇1:");
It1=input.nextInt();
System.out.print("请输入初始化簇2:");
It2=input.nextInt();
}
/**
*获得更新后的簇中心
* */
public void getCenter(double rt[][],boolean fl[],boolean fg,double center[])
{
int temp=0;
double[] centerTemp=new double[M];
for(int i=0;i<M;i++)
centerTemp[i]=0;
if(fg)
{
for(int i=0;i<IN;i++)
if(fl[i])
{
temp++;
for(int j=0;j<M;j++)
centerTemp[j]+=rt[i][j];
}
}
else
{
for(int i=0;i<IN;i++)
if(!fl[i])
{
temp++;
for(int j=0;j<M;j++)
centerTemp[j]+=rt[i][j];
}
}
for(int i=0;i<M;i++)
center[i]=centerTemp[i]/temp;
}
/**
*对图像进行k-means聚类
* */
public boolean[] cluster()
{
getIntial();
flag=new boolean[IN];
for(int i=0;i<IN;i++)
{
flag[i]=false;
}
flag[It1-1]=false;
flag[It2-1]=true;
center1=new double[M];
center1=(double[])rate[It1-1];
center2=new double[M];
center2=(double[])rate[It2-1];
// for(int i=0;i<M;i++)
// System.out.println(center1[i]);
boolean[] tflag=new boolean[flag.length];
tflag=(boolean[])flag.clone();
while(true)
{
for(int i=0;i<IN;i++)
{
dis1=getDistance(center1,rate[i]);
dis2=getDistance(center2,rate[i]);
if(dis1>dis2)
tflag[i]=true;
else
tflag[i]=false;
}
if(Arrays.equals(flag,tflag))
break;
else
{
flag=(boolean[])tflag.clone();
getCenter(rate,flag,false,center1);
getCenter(rate,flag,true,center2);
}
}
System.out.println();
System.out.println("聚类结果簇1:");
for(int i=0;i<IN;i++)
{
if(!flag[i])
System.out.println(i+1);
}
System.out.println("聚类结果簇2:");
for(int i=0;i<IN;i++)
{
if(flag[i])
System.out.println(i+1);
}
return flag;
}
}
/**
*一个简单的UI,使用Gridlayout布局、jLabel容器
* */
class ImageShow
{
private Frame f;
private JLabel bt1;
private ImageIcon icon1;
public void show(boolean[] fg,boolean fa)
{
if(fa)
{
f = new Frame("簇2:");
f.setLayout (new GridLayout (5, 1));
for(int i=0;i<fg.length;i++)
if(fg[i])
{
bt1=new JLabel("",JLabel.CENTER);
bt1.setBorder(BorderFactory.createLineBorder(Color.white,3));
icon1=new ImageIcon("image/"+(i+1)+".gif");
bt1.setIcon(icon1);
f.add(bt1);
f.setLocation(1000,10);
}
}
else
{
f = new Frame("簇1:");
f.setLayout (new GridLayout (5, 1));
for(int i=0;i<fg.length;i++)
if(!fg[i])
{
bt1=new JLabel("",JLabel.CENTER);
bt1.setBorder(BorderFactory.createLineBorder(Color.white,3));
icon1=new ImageIcon("image/"+(i+1)+".gif");
bt1.setIcon(icon1);
f.add(bt1);
f.setLocation(10,10);
}
}
f.pack();
f.setSize(400,1000);
f.setVisible(true);
}
}
/**
*主类调用
* */
public class XunKang
{
public static void main(String args[])
{
CBIR c=new CBIR();
ImageShow is=new ImageShow();
boolean[] flag=c.cluster();
is.show(flag,false);
is.show(flag,true);
}
}
- 基于内容的图像检索-聚类分析
- 基于内容的图像检索
- 基于内容的图像检索
- 基于内容图像检索
- 图像检索:基于内容的图像检索技术
- 图像检索:基于内容的图像检索技术
- 图像检索:基于内容的图像检索技术
- 图像检索:基于内容的图像检索技术
- 图像检索:基于内容的图像检索技术
- 基于内容的图像检索技术
- 基于内容图像检索的若干技术研究
- 基于内容的图像检索概述
- 基于内容的图像检索实例
- 基于内容图像检索的关键技术研究
- 基于内容的图像检索概述
- 基于内容的图像检索 概述
- opencv_基于直方图内容的图像检索
- 基于内容的图像检索引擎
- WPF关闭应用程序方法
- 线段树简单应用 - 区间是否包含
- 依旧在前进
- 数论学习之起步篇(三)
- 网络编程二(整理)
- 基于内容的图像检索-聚类分析
- 最酷的证明:Pick定理另类证法
- hdu 4565——So Easy!
- 链表的逆转
- linux内核软中断及tasklet
- 基于Flex的实时H.264流转发平台之流媒体推送端(librtmp)
- JAVA中String与StringBuffer的区别
- jpa之hibernate4.2.4之tomcat6.0测试
- 野人过河问题