图像打码其实也是图像卷积操作中,空间域滤波的一种方式,用一定大小的滤波器对马赛克范围内像素进行操作。实现过程:将需要打马范围按照滤波器大小划分为多个区块,取滤波器范围内像素,求取均值,再将均值赋值给范围内每一个像素,滤波器再滑到下一个区块。从原理上看,图像马赛克特效非常简单,下面就来看一下具体实现过程。

对整张图像打码。对整张图片打码也叫做像素格特效,我们只需要考虑滤波器大小即可。

代码:

/*** 对整个图片打码* @param image* @param length 马赛克大小*/
public void imageMosaic(BufferedImage image,int length) {int width = image.getWidth();int height = image.getHeight();int size = length * length;int x = width / length;int y = height / length;for(int i = 0; i < x; i++) {for(int j = 0; j < y; j++) {int R=0,G=0,B=0;for(int m = 0; m < length; m++) {for(int n = 0; n < length; n++) {int xCoordinate = i * length + m;int yCoordinate = j * length + n;int rgb = image.getRGB(xCoordinate, yCoordinate);R += (rgb >> 16) & 0xff;G += (rgb >> 8) & 0xff;B += rgb & 0xff;}}R = R / size;G = G / size;B = B / size;int RGB = (255 & 0xff) << 24 | (clamp(R) & 0xff) << 16 | (clamp(G) & 0xff) << 8 | (clamp(B) & 0xff);for(int m = 0; m < length; m++) {for(int n = 0; n < length; n++) {int xCoordinate = i * length + m;int yCoordinate = j * length + n;image.setRGB(xCoordinate, yCoordinate, RGB);}}}}}

局部打码。局部打码需要先定义好打码起始位置,打码范围,马赛克大小。

代码:

/*** 局部打码* @param image* @param xCoordinate 横坐标起始位置* @param yCoordinate 纵坐标起始位置* @param xLength     x方向长度* @param yLength     y方向长度* @param length      马赛克大小*/public void mosaic(BufferedImage image,int xCoordinate,int yCoordinate,int xLength,int yLength,int length) {if ((xCoordinate + xLength) > image.getWidth() || (yCoordinate + yLength) > image.getHeight()) {System.out.println("马赛克范围大于图像范围!");return;}int size = length * length;int x = xLength / length;int y = yLength / length;for(int m = 0; m < x; m++) {for(int n = 0; n < y; n++) {int R=0,G=0,B=0;for(int i = 0; i < length; i++) {for(int j = 0; j < length; j++) {int x1 = xCoordinate + m * length + i;int y1 = yCoordinate + n * length + j;int rgb = image.getRGB(x1, y1);R += (rgb >> 16) & 0xff;G += (rgb >> 8) & 0xff;B += rgb & 0xff;}}R = R / size;G = G / size;B = B / size;int RGB = (255 & 0xff) << 24 | (clamp(R) & 0xff) << 16 | (clamp(G) & 0xff) << 8 | (clamp(B) & 0xff);for(int i = 0; i < length; i++) {for(int j = 0; j < length; j++) {int x1 = xCoordinate + m * length + i;int y1 = yCoordinate + n * length + j;image.setRGB(x1, y1, RGB);}}}}}

完整的马赛克实现代码:

public class MosaicFilter {/*** 对整个图片打码* @param image* @param length 马赛克大小*/public void imageMosaic(BufferedImage image,int length) {int width = image.getWidth();int height = image.getHeight();int size = length * length;int x = width / length;int y = height / length;for(int i = 0; i < x; i++) {for(int j = 0; j < y; j++) {int R=0,G=0,B=0;for(int m = 0; m < length; m++) {for(int n = 0; n < length; n++) {int xCoordinate = i * length + m;int yCoordinate = j * length + n;int rgb = image.getRGB(xCoordinate, yCoordinate);R += (rgb >> 16) & 0xff;G += (rgb >> 8) & 0xff;B += rgb & 0xff;}}R = R / size;G = G / size;B = B / size;int RGB = (255 & 0xff) << 24 | (clamp(R) & 0xff) << 16 | (clamp(G) & 0xff) << 8 | (clamp(B) & 0xff);for(int m = 0; m < length; m++) {for(int n = 0; n < length; n++) {int xCoordinate = i * length + m;int yCoordinate = j * length + n;image.setRGB(xCoordinate, yCoordinate, RGB);}}}}}/*** 局部打码* @param image* @param xCoordinate 横坐标起始位置* @param yCoordinate 纵坐标起始位置* @param xLength     x方向长度* @param yLength     y方向长度* @param length      马赛克大小*/public void mosaic(BufferedImage image,int xCoordinate,int yCoordinate,int xLength,int yLength,int length) {if ((xCoordinate + xLength) > image.getWidth() || (yCoordinate + yLength) > image.getHeight()) {System.out.println("马赛克范围大于图像范围!");return;}int size = length * length;int x = xLength / length;int y = yLength / length;for(int m = 0; m < x; m++) {for(int n = 0; n < y; n++) {int R=0,G=0,B=0;for(int i = 0; i < length; i++) {for(int j = 0; j < length; j++) {int x1 = xCoordinate + m * length + i;int y1 = yCoordinate + n * length + j;int rgb = image.getRGB(x1, y1);R += (rgb >> 16) & 0xff;G += (rgb >> 8) & 0xff;B += rgb & 0xff;}}R = R / size;G = G / size;B = B / size;int RGB = (255 & 0xff) << 24 | (clamp(R) & 0xff) << 16 | (clamp(G) & 0xff) << 8 | (clamp(B) & 0xff);for(int i = 0; i < length; i++) {for(int j = 0; j < length; j++) {int x1 = xCoordinate + m * length + i;int y1 = yCoordinate + n * length + j;image.setRGB(x1, y1, RGB);}}}}}// 判断r,g,b值,大于256返回256,小于0则返回0,0到256之间则直接返回原始值private int clamp(int rgb) {if (rgb > 255)return 255;if (rgb < 0)return 0;return rgb;}public static void main(String[] args) throws Exception{File in = new File("C:/Users/admin/Desktop/1.jpg");File out = new File("C:/Users/admin/Desktop/3.jpg");BufferedImage image = ImageIO.read(in);new MosaicFilter().imageMosaic(image, 5);//new MosaicFilter().mosaic(image, 100, 70, 50, 50,10);ImageIO.write(image, "jpg", out);}
}

原图:

全局打码:

局部打码:

图像马赛克原理及实现相关推荐

  1. 利用opencv实现图像马赛克处理的三种方法

    前言:本文就图像的马赛克处理,基于opencv提出了三种解决方案,并详细地介绍了三种方法的原理.示例.问题及问题的解决方案. 方法一 原理介绍:利用resize()将图片先缩小,再放大 代码示例: i ...

  2. 《Kinect应用开发实战:用最自然的方式与机器对话》一3.4 深度图像成像原理...

    3.4 深度图像成像原理 Kinect有发射.捕捉.计算视觉重现的类似过程.严格说来,Kinect的"深度眼睛"是由一个红外投影机和红外摄像头组合而成的,投影和接收互为重叠,如图3 ...

  3. CV:计算机视觉技术之图像基础知识(二)—以python的skimage和numpy库来了解计算机视觉图像基础(图像存储原理-模糊核-锐化核-边缘检测核,进阶卷积神经网络(CNN)的必备基础)

    CV:计算机视觉技术之图像基础知识(二)-以python的skimage和numpy库来了解计算机视觉图像基础(图像存储原理-模糊核-锐化核-边缘检测核,进阶卷积神经网络(CNN)的必备基础) 目录 ...

  4. 前端性能优化之图像优化原理

    前端性能优化中,图像的优化是非常重要的一环,为什么要说图像的优化呢,而不是我们常见的图片优化?因为这里的图像包括矢量图和位图,我们常说的图片优化是指位图的优化.这篇文章转载至奇舞周刊,大佬总结的非常好 ...

  5. 4.python-opencv图像马赛克

    4.python-opencv图像马赛克 第一章 python-opencv-图片导入和显示 第二章 python-opencv图像简单处理 第三章 python-opencv图像mask掩膜处理 文 ...

  6. unity图像压缩算法原理

    概述 在计算机图形学中,存在许多纹理压缩方案.压缩既减少了纹理内存占用,又降低了使用纹理的带宽要求.本文中,"纹理压缩"与"图像压缩"不同,因为纹理压缩方案的设 ...

  7. 图像成像原理与相机标定

    一.图像成像原理 世界坐标系到相机坐标系 世界坐标系是空间中根据需求任意指定的坐标系,相机坐标系是以镜头为原点,光心方向为Z轴方向的坐标系. 同一个点在不同坐标系下的坐标可以通过平移旋转的仿射变换得到 ...

  8. 图像卷积原理及MATLAB实现

    数字图像卷积原理,matlab的conv2函数,不使用con2函数实现卷积 图像卷积原理 卷积,Convolution.卷积是两个变量在某范围内相乘后求和的结果.如果卷积的变量是序列x(n)和h(n) ...

  9. 图像仿射变换原理3:仿射变换类型及变换矩阵详解

    ☞ ░ 老猿Python博文目录:https://blog.csdn.net/LaoYuanPython ░ 仿射变换博文传送门(带星号的为付费专栏文章): *图像仿射变换原理1:齐次坐标来龙去脉详解 ...

最新文章

  1. 关于Android制作.9.png图片
  2. 汇编题20200330
  3. 初次面试Java岗位,这些技巧你要知道!
  4. 写在11期培训班第五次课后作业前面的话
  5. 前端路由的两种实现原理
  6. Ancient Berland Circus CodeForces - 1C
  7. UNIX高级环境编程 第3章 文件IO
  8. leetcode讲解--513. Find Bottom Left Tree Value
  9. Fread函数的用法
  10. testbench的设计
  11. zeppelin部署安装
  12. pandas绘图线条颜色大全
  13. 题目 1097: 蛇行矩阵 题解
  14. 跟Java面试官对线的一天!唬住就要50K,唬不住就要5K
  15. 俺老孙画个圈-板框与安装孔-PCB系列教程1-10
  16. Java一维数组学生成绩找最高分,输出成绩等级题目练习
  17. 原生js获取document_常见的原生javascript DOM操作
  18. 当谈论机器学习中的公平公正时,我们该谈论些什么?
  19. List的ArrayList类和LInkedlist的Vector类的使用
  20. JSON parse error: Invalid UTF-8 start byte 0xa0\n

热门文章

  1. 12.suggest_type
  2. [leetcode] 72.编辑距离
  3. mc显示服务器生命值,[1.7-1.8]CombatIndicator — 全息显示攻击伤害的数值 让我的世界服务器更有游戏感...
  4. html 载入中,用纯CSS实现加载中动画效果
  5. Redis数据库(二)——Redis高可用、持久化及性能管理
  6. OSPF简单多区域及末梢区域配置
  7. update 后面能接子查询吗_只用身份证能查询CPA成绩吗?查询步骤不能忘
  8. datatables 展开 折叠_更成熟的三星Z Fold2 折叠屏发展迈出关键一步
  9. java自定义findbugs规则_静态代码扫描 (三)——FindBugs 自定义规则入门
  10. python调参工作都是干啥的_xgboost原理及调参方法-通俗易懂版本