博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
图像处理之六边形网格分割效果
阅读量:5786 次
发布时间:2019-06-18

本文共 5897 字,大约阅读时间需要 19 分钟。

一:原理

根据输入参数blockSize的大小,将图像分块,决定每块的中心通过该像素块内所有

像素之和的均值与该块内部每个像素比较,RGB值之间几何距离最小为新的中心,迭

代更新运算,直到达到输入参数声明的最大循环次数为止,然后输出结果图像即可。

二:程序实现

类MyCluster,存储每个像素块中心的信息,计算中心位置。

类SuperPixelsFilter, 滤镜实现,完成六边形网格分割的主要功能,其中距离计算,基

于欧几里德距离公式。

三:效果

原图:

效果:

四:完全源代码

package com.gloomyfish.image.cluster.effect;import java.awt.image.BufferedImage;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import com.gloomyfish.filter.study.AbstractBufferedImageOp;public class SuperPixelsFilter extends AbstractBufferedImageOp {	private double[] distances;	private int[] labels; 	private MyCluster[] clusters;	private int maxClusteringLoops = 50;		private double blockSize;	private double modifier;		public SuperPixelsFilter()	{		blockSize = 16;		modifier = 130;	}		public double getBlockSize() {		return blockSize;	}	public void setBlockSize(double blockSize) {		this.blockSize = blockSize;	}	public double getModifier() {		return modifier;	}	public void setModifier(double modifier) {		this.modifier = modifier;	}    	@Override	public BufferedImage filter(BufferedImage src, BufferedImage dest) {		int width = src.getWidth();        int height = src.getHeight();        if ( dest == null )            dest = createCompatibleDestImage( src, null );        int[] inPixels = new int[width*height];        getRGB( src, 0, 0, width, height, inPixels );        int index = 0;        // initialization        distances = new double[width*height];        labels = new int[width*height];        Arrays.fill(distances, Integer.MAX_VALUE);        Arrays.fill(labels, -1);        initClusters(width, height, inPixels, blockSize, modifier);        // loop to get all block/cells, image segmentation        int loops = 0;        boolean pixelChangedCluster = true;        while (pixelChangedCluster&&loops
> 16) & 0xff; int tg = (inPixels[pos] >> 8) & 0xff; int tb = inPixels[pos] & 0xff; double D = c.distance(x, y, tr, tg, tb, blockSize, modifier, width, height); if ((D
> 16) & 0xff; int tg = (inPixels[pos] >> 8) & 0xff; int tb = inPixels[pos] & 0xff; clusters[labels[pos]].addPixel(x, y, tr, tg, tb); } } // calculate centers for (index=0;index
<< 24) | (0 << 16) | (0 << 8) | 0; } } } setRGB( dest, 0, 0, width, height, inPixels ); return dest; } public void initClusters(int width, int height, int[] input, double S, double m) { List
temp = new ArrayList
(); boolean even = false; double xstart = 0; int id = 0; for (double y = S / 2; y < height; y += S) { // 创建六边形网格 if (even) { xstart = S / 2.0; even = false; } else { xstart = S; even = true; } for (double x = xstart; x < width; x += S) { int index = (int) (x + y * width); int tr = (input[index] >> 16) & 0xff; int tg = (input[index] >> 8) & 0xff; int tb = input[index] & 0xff; MyCluster c = new MyCluster(id, tr, tg, tb, (int) x, (int) y, S, m); temp.add(c); id++; } } clusters = new MyCluster[temp.size()]; for (int i = 0; i < temp.size(); i++) { clusters[i] = temp.get(i); } } }

MyCluster类代码:

package com.gloomyfish.image.cluster.effect;public class MyCluster {	int id;	double inv = 0; // inv variable for optimization	double pixelCount; // pixels in this cluster	double avg_red; // average red value	double avg_green; // average green value	double avg_blue; // average blue value	double sum_red; // sum red values	double sum_green; // sum green values	double sum_blue; // sum blue values	double sum_x; // sum x	double sum_y; // sum y	double avg_x; // average x	double avg_y; // average y	public MyCluster(int id, int in_red, int in_green, int in_blue, int x,			int y, double S, double m) {		// inverse for distance calculation		this.inv = 1.0 / ((S / m) * (S / m));		this.id = id;		addPixel(x, y, in_red, in_green, in_blue);		// calculate center with initial one pixel		calculateCenter();	}	public void reset() {		avg_red = 0;		avg_green = 0;		avg_blue = 0;		sum_red = 0;		sum_green = 0;		sum_blue = 0;		pixelCount = 0;		avg_x = 0;		avg_y = 0;		sum_x = 0;		sum_y = 0;	}	/*	 * Add pixel color values to sum of previously added color values.	 */	void addPixel(int x, int y, int in_red, int in_green, int in_blue) {		sum_x += x;		sum_y += y;		sum_red += in_red;		sum_green += in_green;		sum_blue += in_blue;		pixelCount++;	}	public void calculateCenter() {		// Optimization: using "inverse"		// to change divide to multiply		double inv = 1 / pixelCount;		avg_red = sum_red * inv;		avg_green = sum_green * inv;		avg_blue = sum_blue * inv;		avg_x = sum_x * inv;		avg_y = sum_y * inv;	}	double distance(int x, int y, int red, int green, int blue, double S,			double m, int w, int h) {		// power of color difference between		// given pixel and cluster center		double dx_color = (avg_red - red) * (avg_red - red)				+ (avg_green - green) * (avg_green - green) + (avg_blue - blue)				* (avg_blue - blue);		// power of spatial difference between		// given pixel and cluster center		double dx_spatial = (avg_x - x) * (avg_x - x) + (avg_y - y)				* (avg_y - y);		// Calculate approximate distance D		// double D = dx_color+dx_spatial*inv;		// Calculate squares to get more accurate results		double D = Math.sqrt(dx_color) + Math.sqrt(dx_spatial * inv);		return D;	}}
五:参考这里

该滤镜是SuperPixel算法的简单应用,多数时候,我们可能更熟悉

K-Means等图像分割算法,其实SuperPixel是图像分割算法之一。

告示一下:

博客从这个月恢复更新,请大家继续关注,之前消失了一年,完

了本人的第一本关于图像处理的书初稿写作,谢谢大家厚爱

你可能感兴趣的文章
[解题报告]ural 1176 Hyperchannels
查看>>
CSS修改滚动条样式
查看>>
java switch
查看>>
Linux 进程
查看>>
文件方式实现完整的英文词频统计实例
查看>>
c语言第五次作业
查看>>
eclipse快捷键
查看>>
向前向前向前!向W“.NET研究”indows Phone平台前进
查看>>
可视化的数据结构和算法
查看>>
瑞星2009新品正式发布 开启“云安全” 时代
查看>>
常见问题的解决方法
查看>>
约瑟夫环之数学方法【只能求最后胜利者】+ 循环链表【实现】
查看>>
第十六章 多态性
查看>>
匿名函数-------lambda
查看>>
关于《selenium2自动测试实战--基于Python语言》
查看>>
URLConnection简单使用_md
查看>>
win7 64位安装vs2013 出现'System.AccessViolationException的错误
查看>>
1077 互评成绩计算 (20 分)
查看>>
<script> 的defer和async
查看>>
五子棋算法
查看>>