java 绘制六边形_JAVA代码怎么实现图像六边形网格分割效果
下面給大家介紹JAVA代碼怎么實現圖像六邊形網格分割效果,希望能給大家提供幫助。
一:原理
根據輸入參數blockSize的大小,將圖像分塊,決定每塊的中心通過該像素塊內所有像素之和的均值與該塊內部每個像素比較,RGB值之間幾何距離最小為新的中心,迭代更新運算,直到達到輸入參數聲明的最大循環(huán)次數為止,然后輸出結果圖像即可。
二:程序實現
類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?intmaxClusteringLoops=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)?{
intwidth=src.getWidth();
intheight=src.getHeight();
if?(dest==?null?)
dest=createCompatibleDestImage(?src,?null?);
int[]inPixels=newint[width*height];
getRGB(?src,?0,?0,?width,?height,?inPixels?);
intindex=0;
//?initialization
distances=newdouble[width*height];
labels=newint[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
intloops=0;
booleanpixelChangedCluster=true;
while?(pixelChangedCluster&&loops
pixelChangedCluster=false;
loops++;
//?for?each?cluster?center?C
for?(inti=0;i
MyClusterc=clusters[i];
//?for?each?pixel?i?in?2S?region?around
//?cluster?center
intxs=Math.max((int)(c.avg_x-blockSize),0);
intys=Math.max((int)(c.avg_y-blockSize),0);
intxe=Math.min((int)(c.avg_x+blockSize),width);
intye=Math.min((int)(c.avg_y+blockSize),height);
for?(inty=ys;y
for?(intx=xs;x
intpos=x+width*y;
inttr=?(inPixels[pos]>>16)?&?0xff;
inttg=?(inPixels[pos]>>8)?&?0xff;
inttb=inPixels[pos]?&?0xff;
doubleD=c.distance(x,?y,?tr,
tg,
tb,
blockSize,?modifier,?width,?height);
if?((D
distances[pos]?????????=?D;
labels[pos]????????????=?c.id;
pixelChangedCluster=true;
}
}?//?end?for?x
}?//?end?for?y
}?//?end?for?clusters
//?reset?clusters
for?(index=0;index
clusters[index].reset();
}
//?add?every?pixel?to?cluster?based?on?label
for?(inty=0;y
for?(intx=0;x
intpos=x+y*width;
inttr=?(inPixels[pos]>>16)?&?0xff;
inttg=?(inPixels[pos]>>8)?&?0xff;
inttb=inPixels[pos]?&?0xff;
clusters[labels[pos]].addPixel(x,?y,
tr,?tg,?tb);
}
}
//?calculate?centers
for?(index=0;index
clusters[index].calculateCenter();
}
}
//?Create?output?image?with?pixel?edges
for?(inty=1;y
for?(intx=1;x
intid1=labels[x+y*width];
intid2=labels[(x+1)+y*width];
intid3=labels[x+(y+1)*width];
if?(id1!=id2||id1!=id3)?{
intpos=x+y*width;
inPixels[pos]?=?(255<<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)?{
Listtemp=newArrayList();
booleaneven=false;
doublexstart=0;
intid=0;
for?(doubley=S/?2;?y
//?創(chuàng)建六邊形網格
if?(even)?{
xstart=S/?2.0;
even=false;
}?else?{
xstart=S;
even=true;
}
for?(doublex=xstart;?x
intindex=?(int)?(x?+?y?*?width);
inttr=?(input[index]>>16)?&?0xff;
inttg=?(input[index]>>8)?&?0xff;
inttb=input[index]?&?0xff;
MyClusterc=newMyCluster(id,?tr,?tg,?tb,
(int)?x,?(int)?y,?S,?m);
temp.add(c);
id++;
}
}
clusters=newMyCluster[temp.size()];
for?(inti=0;?i
clusters[i]?=?temp.get(i);
}
}
}
MyCluster類代碼:
package?com.gloomyfish.image.cluster.effect;
public?class?MyCluster?{
int?id;
doubleinv=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
doubleinv=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
doubledx_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
doubledx_spatial=?(avg_x?-?x)?*?(avg_x?-?x)?+?(avg_y?-?y)
*?(avg_y?-?y);
//?Calculate?approximate?distance?D
//?doubleD=dx_color+dx_spatial*inv;
//?Calculate?squares?to?get?more?accurate?results
doubleD=Math.sqrt(dx_color)?+?Math.sqrt(dx_spatial?*?inv);
return?D;
}
}
五:參考這里
該濾鏡是SuperPixel算法的簡單應用,多數時候,我們可能更熟悉K-Means等圖像分割算法,其實SuperPixel是圖像分割算法之一。
(責任編輯:6g下載網)
總結
以上是生活随笔為你收集整理的java 绘制六边形_JAVA代码怎么实现图像六边形网格分割效果的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android pcm频谱_Androi
- 下一篇: Oracle 12安装教程