一个简单的马赛克例子
先看一张正常的图像,图像尺寸为640x558
人脸部分打赏马赛克,效果如下:
可以看出,马赛克为一个个的晶体小方格,每个小方格的各个像素颜色是一样的。
现在简单说明下,马赛克的原理。
我们列举一些数字,共5行8列,40个数字。
1 2 3 4 5 6 7 8
9 10 11 12 13 14 15 16
17 18 19 20 21 22 23 24
25 26 27 28 29 30 31 32
33 34 35 36 37 38 39 40
我们不妨将这40个数字看成40个像素,马赛克就是将这些像素相邻的像素进行归一化,取这些相邻数字的平均数,然后用这个平均数替代原来的数。
比如相邻定义为2x2,即相邻的4个进行归一化,则1,2,9,10为一组;3,4,11,12为一组;17,18,25,26为一组,33,34为一组。
其中第一组1,2,9,10的和为22,取平均数5(22/4),然后将这四个数字都替换成5;经过这样的处理后,
原来的数字变成如下模式:
5 7 9 11
21 23 25 27
33 35 37 39
打马赛克就是选定区域,然后将这块区域划分若干个晶体小方格,每个晶体小方格里面的rgb三原色取平均值。
本文采取开源库cximage进行图片像素的处理。
代码不多,直接粘贴出来,其中iGridLength为晶体小方格的尺寸,iGridLength为2时,表示2x2,为4表示4x4。
注意:cximage读取jpg像素时,像素数据顺序都是从最后一行到第一行,从左到右。
// CxImageTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//#include <iostream>
#include <Windows.h>#include "cximage/ximage.h"std::wstring string2wstring(const std::string& str)
{std::wstring result;//获取缓冲区大小,并申请空间,缓冲区大小按字符计算 int len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), NULL, 0);TCHAR* buffer = new TCHAR[len + 1];//多字节编码转换成宽字节编码 MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), buffer, len);buffer[len] = '\0'; //添加字符串结尾 //删除缓冲区并返回值 result.append(buffer);delete[] buffer;return result;
}int main()
{CxImage image(CXIMAGE_FORMAT_JPG);image.Load(L"E:\\learn\\c++\\cximage\\CxImageTest\\x64\\Release\\qiushuzhen_640x558.jpeg", CXIMAGE_FORMAT_JPG);int iJpgWidth = image.GetWidth();int iJpgHeight = image.GetHeight();long x1 = 0;long y1 = 0;image.GetOffset(&x1, &y1);const int iBeginX = 256;const int iBeginY = 96;const int iEndX = 424;const int iEndY = 280;int iRSum = 0;int iGSum = 0;int iBSum = 0;int iAverageR = 0;int iAverageG = 0;int iAverageB = 0;int iGridLength = 2;for (int x = iBeginX; x < iEndX; x = x + iGridLength){for (int y = iBeginY; y < iEndY; y = y + iGridLength){int iPartGridXNum = 0;int iPartGridYNum = 0;for (int iSpanX = 0; iSpanX < iGridLength; iSpanX++){if (x + iSpanX < iEndX){iPartGridXNum++;}}for (int iSpanY = 0; iSpanY < iGridLength; iSpanY++){if (y + iSpanY < iEndY){iPartGridYNum++;}}iRSum = 0;iGSum = 0;iBSum = 0;int iPartGridNum = iPartGridXNum * iPartGridYNum;for (int i = x; i < x + iPartGridXNum; i++){for (int j = y; j < y + iPartGridYNum; j++){RGBQUAD rgb = image.GetPixelColor(i, (iJpgHeight - 1) - j, false);iRSum += rgb.rgbRed;iGSum += rgb.rgbGreen;iBSum += rgb.rgbBlue;}}iAverageR = iRSum / iPartGridNum;iAverageG = iGSum / iPartGridNum;iAverageB = iBSum / iPartGridNum;COLORREF color = COLORREF(RGB(iAverageR, iAverageG, iAverageB));for (int i = x; i < x + iPartGridXNum; i++){for (int j = y; j < y + iPartGridYNum; j++){image.SetPixelColor(i, (iJpgHeight - 1) - j, color);}}}}std::string strSavePath = "E:\\learn\\c++\\cximage\\CxImageTest\\x64\\Release\\";char szPicName[100] = { 0 };sprintf(szPicName, "qiushuzhen_640x558_msk_%dx%d.jpeg", iGridLength, iGridLength);strSavePath = strSavePath + szPicName;std::wstring strwSavePath = string2wstring(strSavePath);image.Save(strwSavePath.c_str(), CXIMAGE_FORMAT_JPG);return 0;
}
本人尝试了2x2,4x4,8x8,16x16,32x32五种晶体小方格进行打马赛克,其中32x32就是本文前面部分的马赛克尺寸。
2x2的效果如下:
可以看出2x2情况下,完全看不出打了马赛克。
4x4的效果如下:
可以看出4x4已经有点马赛克效果了
8x8的效果如下:
马赛克效果很明显了
16x16的效果如下:
这时已经分辨不出是谁了。
本人就代码例子进行了百度网盘共享:
链接:https://pan.baidu.com/s/1nPO-XRcEVtD_mjuE9K2OKw
提取码:1234
一个简单的马赛克例子相关推荐
- mvc登录实例 mysql_spring mvc + mybatis + mysql 调整的一个简单的登录例子
spring mvc + mybatis + mysql 整合的一个简单的登录例子 今天用spring跟mybatis整合写了一个简单的登录例子,第一次整合,给自己做个笔记,可能注释写的有点少,做的不 ...
- boost::log模块实现一个简单日志的例子
boost::log模块实现一个简单日志的例子 实现功能 C++实现代码 实现功能 boost::log模块实现一个简单日志的例子 C++实现代码 #include <boost/log/tri ...
- 轻松创建nodejs服务器(1):一个简单nodejs服务器例子
这篇文章主要介绍了一个简单nodejs服务器例子,本文实现了一个简单的hello world例子,并展示如何运行这个服务器,需要的朋友可以参考下 我们先来实现一个简单的例子,hello world. ...
- 一个简单的CORBA例子
因为对CORBA分析的需要,这里写一个简单的CORBA例子.从JDK1.2开始,JDK中集成了ORB的实现,本例子使用了JDK1.7,对于JDK1.2+应该都没有问题.这个例子实现一个简单的加减乘除的 ...
- 使用Multiplayer Networking做一个简单的多人游戏例子-1/3(Unity3D开发之二十五)
猴子原创,欢迎转载.转载请注明: 转载自Cocos2Der-CSDN,谢谢! 原文地址: http://blog.csdn.net/cocos2der/article/details/51006463 ...
- java servlet例子_Servlet学习教程(三)---- 一个简单的Servlet例子
我们用个最简单的Servlet例子来解说一下Servlet简单配置以及Servlet类实现类的写法. 第一,我们新建一个Dynamic Web Project,起名Servlet 点击NEXT,设置D ...
- Python网络爬虫 - 一个简单的爬虫例子
下面我们创建一个真正的爬虫例子 爬取我的博客园个人主页首页的推荐文章列表和地址 scrape_home_articles.py from urllib.request import urlopen f ...
- python网页爬虫例子_Python网络爬虫 - 一个简单的爬虫例子
下面我们创建一个真正的爬虫例子 爬取我的博客园个人主页首页的推荐文章列表和地址 scrape_home_articles.py from urllib.request importurlopenfro ...
- 决策树分析例题经典案例_决策树原理及一个简单的小例子
首先通过两个图来引入什么是决策树. 是否学习的决策过程 决策树是仿树结构来进行决策的,例如上图来说,我们要对'是否学习'这个问题进行决策时,通常伴随一系列的子决策.先看是否有'对象',有的话是否需要' ...
最新文章
- 2022秋招算法岗卷成人间地狱!高薪惹眼,招录比100:1
- NYOJ 353 3D dungeon 【bfs】
- oracle创建数据库的三种方法
- CodeForces - 444C DZY Loves Colors(线段树+剪枝)
- 从头学习MVC4基础之视图
- windows phone笔记
- vulkan android 三星,vulkan android
- 数组作为方法的参数实例和细节(Java)
- Python2.7安装Numpy
- iTOP4412 uboot移植教程
- Android Studio Entry name *.xml collided解决方案
- laravel框架使用教程
- From.List用法详解
- 字节跳动做教育能否摆脱互联网公司“流量魔咒”?
- IEMS_11_课程信息相关的初始数据导入
- 摄影后期人像高端摄影后期PS修图技巧
- C# WAV音乐多音轨合并
- 在Qt中使用OpenGL(四)
- 机器学习—特征工程—OneHotEncoder独热编码
- 面试被骗 :当了一小时讲师,最后反倒说我不合格
热门文章
- Linux下如何拷贝隐藏文件
- 盘点个人信息保护方面的那些认证
- 深入探索C++对象模型之C++对象(vs,gcc,clang测试)
- 自定义ironic-python-agent镜像 ipa ramdisk and kernel
- 有时候人们用四位数字表示一个时间,比如 1106 表示 11 点零 6 分。现在,你的程序要根据起始时间和流逝的时间计算出终止时间。 读入两个数字,第一个数字以这样的四位数字表示当前时间,第二个数字
- Cuba 获取当前登录用户
- windows10应用商店打不开
- 帝国cms插件支持7.0/7.2 7.5/UTF-8 微信登入插件 一键登入
- dmpython部署操作轨迹
- 出走的门徒之七—驭势 吴甘沙:一步十年