基于像素权重实现图像的像素模糊从而达到近似油画效果模糊

其实卷积的变种,不是基于Stroke维诺图算法与采样moment算法

模拟实现。不想跟多的废话了,先看效果:

20140128225137687

说实话,货是干货,但是不想再多写罗嗦话,自己看代码吧!滤镜代码:


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; 
    } 
    
}

最后:


祝各位新春快乐,阖家欢乐!谢谢过去一年你们对本博客的关注与支持!