图像处理之背景虚化
来源:互联网 发布:哪些高校有网络教育 编辑:程序博客网 时间:2024/05/01 22:00
废话不多说,先上图。
原图
圆形的清晰区域
竖直的清晰区域
水平的清晰区域
嘿嘿,看上去还可以哈~~我们这里说的背景虚化呢,自然没有能力做到自动识别背景与前景的,所以只能算是一个半自动的过程:由用户来指定哪片区域是清晰的,哪片区域是模糊的,然后在清晰的区域与模糊的区域之间做一个简单的过渡。
我们在这里提供了三张模式,分别是圆形的清晰区域,竖直的清晰区域和水平的清晰区域。示意图如下所示
圆形
横向
纵向
如果你还想折腾出其他的形状,可以参考我后面的代码自己折腾一下。
这里不打算讲高斯模糊之类的东西,相信现有的博客写高斯模糊早已写烂了。我也只是借用了图像模糊里面的一个思想而已:使用周围像素的平均值来代替当前像素。高斯模糊里面对像素点周围不同位置的像素点还赋予了不同的权重,我为了简单,索性让所有的权重都一样。产生的效果也还行。
下面就把全部代码都奉上。
package algorithm.blur;import java.awt.Color;import java.awt.image.BufferedImage;public class InteractiveBlur{// 掩码最小值public static final int MIN_MASK_SIZE = 3;// 掩码最大值public static final int MAX_MASK_SIZE = 15;//掩码最大值的一半public static final int HALF_MAX_MASK_SIZE = 7;// 最小值与最大值的差public static final int DIFF_MASK_SIZE = MAX_MASK_SIZE - MIN_MASK_SIZE;// 点在模糊区域中public static final int AREA_BLUR = 1;// 点在清晰区域中public static final int AREA_CLEAR = 2;// 点在过渡区域中public static final int AREA_TRAN = 3;// 圆形的清晰区域public static final int TYPE_CIRCLE = 1;// 垂直的清晰区域public static final int TYPE_VERTCIAL = 2;// 水平的清晰区域public static final int TYPE_HORIZONTAL = 3;//外部区域以外的都是模糊的private static int outSize;//内部区域以内的都是清晰的private static int innerSize;//区域private static int area;private static Color[][] colorMatrix;/** * 获取图像 * * @param image * 源图像 * @param x * x坐标 * @param y * y坐标 * @param size * 作用范围 * @param type * 类型 * */public static BufferedImage getImage(BufferedImage image, int x, int y, int size, int type){InteractiveBlur.innerSize = size;InteractiveBlur.outSize = (int) (size * 1.5);// 获取rgb矩阵colorMatrix = getColorMatrix(image);switch (type){case TYPE_VERTCIAL:return getVecticalImage(image, x, size);case TYPE_HORIZONTAL:return getHozizontalImage(image, y, size);default:return getCircleImage(image, x, y, size);}}/** * 获取圆形的清晰区域 * * @param image * 源图像 * @param x * x坐标 * @param y * y坐标 * @param size * 作用范围 * */private static BufferedImage getCircleImage(BufferedImage image, int centerX, int centerY, int size){int width = image.getWidth();int height = image.getHeight();BufferedImage outputImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);for (int y = HALF_MAX_MASK_SIZE; y < height - HALF_MAX_MASK_SIZE; y++){for (int x = HALF_MAX_MASK_SIZE; x < width - HALF_MAX_MASK_SIZE; x++){int distance = getDistance(x, y, centerX, centerY);area = getArea(distance);outputImage.setRGB(x, y, getRGBValue(image, x, y,distance));}}return outputImage;}/** * 获取纵向的背景虚化图像 * * @param image * 源图像 * @param x * x坐标 * @param y * y坐标 * @param size * 作用范围 * */public static BufferedImage getVecticalImage(BufferedImage image, int centerX, int size){int width = image.getWidth();int height = image.getHeight();BufferedImage outputImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);for (int x = HALF_MAX_MASK_SIZE; x < width - HALF_MAX_MASK_SIZE; x++){int distance = Math.abs(x - centerX);area = getArea(Math.abs(x - centerX));for (int y = HALF_MAX_MASK_SIZE; y < height - HALF_MAX_MASK_SIZE; y++){outputImage.setRGB(x, y, getRGBValue(image, x, y,distance));}}return outputImage;}/** * 获取水平的背景虚化图像 * * @param image * 源图像 * @param x * x坐标 * @param y * y坐标 * @param size * 作用范围 * */public static BufferedImage getHozizontalImage(BufferedImage image, int centerY, int size){int width = image.getWidth();int height = image.getHeight();BufferedImage outputImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);for (int y = HALF_MAX_MASK_SIZE; y < height - HALF_MAX_MASK_SIZE; y++){int distance = Math.abs(y - centerY);area = getArea(distance);for (int x = HALF_MAX_MASK_SIZE; x < width - HALF_MAX_MASK_SIZE; x++){outputImage.setRGB(x, y, getRGBValue(image, x, y,distance));}}return outputImage;}private static int getRGBValue(BufferedImage image, int x, int y,int distance){if (area == AREA_BLUR){return getBlurRGBValue(x, y, MAX_MASK_SIZE);}else if (area == AREA_TRAN){// 过渡区间int maskSize = MIN_MASK_SIZE + DIFF_MASK_SIZE * (distance - innerSize) / (outSize - innerSize);// 将masksize变为奇数maskSize = (maskSize / 2) * 2 + 1;return getBlurRGBValue(x, y, maskSize);}else{return image.getRGB(x, y);}}/** * 获取模糊后的图像的rgb值 * * @param colorMatrix * @param x * @param y * @param maskSize * */private static int getBlurRGBValue(int x, int y, int maskSize){int sum = maskSize * maskSize;int halfMaskSize = maskSize / 2;int sumR = 0, sumG = 0, sumB = 0;for (int i = -halfMaskSize; i <= halfMaskSize; i++){for (int j = -halfMaskSize; j <= halfMaskSize; j++){sumR += colorMatrix[x + i][y + j].getRed();sumG += colorMatrix[x + i][y + j].getGreen();sumB += colorMatrix[x + i][y + j].getBlue();}}sumR /= sum;sumG /= sum;sumB /= sum;sumR = sumR << 16;sumG = sumG << 8;return sumR|sumG|sumB;}// 判断点在那个区域private static int getArea(int distance){int area;if (distance > outSize){area = AREA_BLUR;}else if (distance < innerSize){area = AREA_CLEAR;}else{area = AREA_TRAN;}return area;}/** * 获取两点之间的距离 * * @param x1 * 第一个点的X坐标 * @param y1 * 第一个点的y坐标 * @param x2 * 第二个点的X坐标 * @param y2 * 第二个点的y坐标 * */private static int getDistance(int x1, int y1, int x2, int y2){int x = x1 - x2;int y = y1 - y2;return (int) Math.sqrt(x * x + y * y);}/** * 获取图像的color矩阵 * * @param image * */private static Color[][] getColorMatrix(BufferedImage image){int width = image.getWidth();int height = image.getHeight();Color[][] matrix = new Color[width][height];for (int y = 0; y < height; y++){for (int x = 0; x < width; x++){matrix[x][y] = new Color(image.getRGB(x, y));}}return matrix;}}
1 0
- 图像处理之背景虚化
- opencv图像处理之在手机上实现背景虚化
- 图像背景虚化
- 图像处理的背景
- C语言处理图像之改变背景前景颜色
- opencv图像处理之轮廓外背景颜色改变
- View之背景虚化处理(头像作为背景模糊化处理)
- 图像处理硬背景知识
- 图像虚拟化处理(图片背景虚拟化)
- 图像处理之图像灰度化
- 图像处理之图像灰度化
- 图像处理之图像恶魔化
- iOS图片处理之背景虚化原理解析
- 图像处理之灰度化
- 图像处理之卡通化
- html一之背景图像
- 图像算法研究---背景虚化算法
- 高斯处理图像背景模糊
- uploadify参数
- 亿级Web系统搭建——单机到分布式集群
- proxool是什么
- 制作字幕的软件(小帮手~)
- 动态加载未安装APK
- 图像处理之背景虚化
- poj 3352 Road Construction
- 13项目5 合并字符串
- MyEclipse打出sysout代码不能自动补全输出system.out.println()的解决办法
- 启动android项目无法成功解决办法
- iOS故障排除指南:基本技巧
- HDU 2033 人见人爱A+B
- Excel下2048的实现
- 一个操作系统的实现——进程