基于像素权重实现图像的像素模糊从而达到近似油画效果模糊
其实卷积的变种,不是基于Stroke维诺图算法与采样moment算法
模拟实现。不想跟多的废话了,先看效果:
说实话,货是干货,但是不想再多写罗嗦话,自己看代码吧!滤镜代码:
package com.gloomyfish.nature.filter.study; import java.awt.image.BufferedImage; import com.gloomyfish.filter.study.AbstractBufferedImageOp; public class OilPaintFilter extends AbstractBufferedImageOp { private int radius = 5; // default value private int intensity = 20; // default value public OilPaintFilter(int radius, int graylevel) { this.radius = radius; this.intensity = graylevel; } public OilPaintFilter() { this(5, 20); } public int getRadius() { return radius; } public void setRadius(int radius) { this.radius = radius; } public int getIntensity() { return intensity; } public void setIntensity(int intensity) { this.intensity = intensity; } @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]; int[] outPixels = new int[width*height]; getRGB( src, 0, 0, width, height, inPixels ); int index = 0; int subradius = this.radius / 2; int[] intensityCount = new int[intensity+1]; int[] ravg = new int[intensity+1]; int[] gavg = new int[intensity+1]; int[] bavg = new int[intensity+1]; for(int i=0; i<=intensity; i++) { intensityCount[i] = 0; ravg[i] = 0; gavg[i] = 0; bavg[i] = 0; } for(int row=0; row<height; row++) { int ta = 0, tr = 0, tg = 0, tb = 0; for(int col=0; col<width; col++) { for(int subRow = -subradius; subRow <= subradius; subRow++) { for(int subCol = -subradius; subCol <= subradius; subCol++) { int nrow = row + subRow; int ncol = col + subCol; if(nrow >=height || nrow < 0) { nrow = 0; } if(ncol >= width || ncol < 0) { ncol = 0; } index = nrow * width + ncol; tr = (inPixels[index] >> 16) & 0xff; tg = (inPixels[index] >> 8) & 0xff; tb = inPixels[index] & 0xff; int curIntensity = (int)(((double)((tr+tg+tb)/3)*intensity)/255.0f); intensityCount[curIntensity]++; ravg[curIntensity] += tr; gavg[curIntensity] += tg; bavg[curIntensity] += tb; } } // find the max number of same gray level pixel int maxCount = 0, maxIndex = 0; for(int m=0; m<intensityCount.length; m++) { if(intensityCount[m] > maxCount) { maxCount = intensityCount[m]; maxIndex = m; } } // get average value of the pixel int nr = ravg[maxIndex] / maxCount; int ng = gavg[maxIndex] / maxCount; int nb = bavg[maxIndex] / maxCount; index = row * width + col; outPixels[index] = (ta << 24) | (nr << 16) | (ng << 8) | nb; // post clear values for next pixel for(int i=0; i<=intensity; i++) { intensityCount[i] = 0; ravg[i] = 0; gavg[i] = 0; bavg[i] = 0; } } } setRGB( dest, 0, 0, width, height, outPixels ); return dest; } }
最后:
祝各位新春快乐,阖家欢乐!谢谢过去一年你们对本博客的关注与支持!