前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >如何用女神的名字来画女神?

如何用女神的名字来画女神?

作者头像
巴山学长
发布2020-02-17 15:05:57
发布2020-02-17 15:05:57
86600
代码可运行
举报
文章被收录于专栏:巴山学长巴山学长
运行总次数:0
代码可运行

头几天在CSDN上逛博客时遇到一篇非常有趣的博文,大意是将照片的内容用汉字来替换,看后觉得不错,决定分享给大家,下面就一起来看看吧。

一、实现原理

对于一幅图像而言,总是可转换成取值范围在[0, 255]之间灰度图像,将灰度图用最大灰度值作归一化处理,归一化后的值作为像素点所在位置的灰度密度;对于汉字而言,往往具有不同数量和形状的笔画,若在一个固定的区域内使用同一种字体书写汉字,则不同汉字所占的区域面积一般是不同的,将每个汉字所占区域面积与总区域面积作比,并把对应的比值作为汉字密度。若将图像灰度密度与汉字密度建立一一对应关系,即可把相同位置的像素点用对应像素密度的汉字来占据,这样就可以完成从像素图到字符化图的转换。

不难看出,算法主要包括两个部分:一是建立一个汉字密度库,包含汉字与其密度;二是实现汉字密度与图像灰度密度之间的转换。

二、实现过程

2.1 基于汉字库创建汉字密度库

代码语言:javascript
代码运行次数:0
运行
复制
% 字符转密度值
clc;clear;close all;
% 加载字库集,可以自由定义字库集
load('str.mat');
N = size(str,2);
% 初始化汉字密度矩阵
strR =zeros(N,1);
% 定义figur背景颜色
fig = figure('color',[1 1 1]);%白色背景
hold on;
% 限制X, Y坐标轴范围
xlim([0,0.5]);ylim([0,0.5]);
% 设置figure位置
set(gcf,'Position',[488 342 375 420]);
% 设置坐标轴位置
set(gca,'Position',[0.0 0.0 1 1]);
% 获取当前坐标轴句柄
ax = gca;
F = getframe;
strd = F.cdata;
% 计算整个坐标轴区域面积
aS = size(strd,1)*size(strd,2);
% 不显示坐标轴
axis off;
% 通过循环计算字库集中每个汉字对应的密度值
for k = 1:N
    % 在figure指定位置放置文字
    text(ax,0,0,str(k),'FontUnits','normalized','FontSize',0.9,'verticalAlignment','bottom');
    % 获取文字图像信息
    F = getframe;
    strd = F.cdata;
    % 计算文字所占密度
    strdm = mean(strd,3);
    strdm = uint8((strdm ~= 255));
    % 计算汉字所占面积
    aC = sum(strdm(:));
    strR(k) = aC/aS;
    % 清除当前坐标区域内汉字
    cla;
end
% 保存每个字符密度
save('strR.mat','str','strR');

2.2 根据文字密度与图像灰度密度的对应关系,在相应位置进行汉字替换即可完成图像的字符化过程。

代码语言:javascript
代码运行次数:0
运行
复制
clc;clear;close;
% 加载字库集及其密度
load('strR.mat');
% 读取目标图片
x = imread('lenna.png');
% 重置图像尺寸
len = 80;
x = imresize(x,[len,len]);
% 将RGB图像转换为灰度图像
img = double(rgb2gray(x));
% 将灰度值用最大值归一化,越亮密度越低,越暗密度越高
img = 1 - img/255;

% 由于文字最大密度不能到1,而灰度密度可以取1,因此需要对文字的密度值进行缩放
enlarge = max(img(:))/max(strR(:));
% 初始化对应编码
strid = zeros(size(x(:,:,1)));
% 对每一个像素点的灰度值与文字密度进行匹配,记录下对应的文字编码
for k = 1:length(img(:))
    imk = img(k);
    [~,minid] = min(abs(imk-strR*enlarge));
    strid(k) = minid;
end
% 按照行进行每行的文字输出
n = size(img,1);
strI = cell(1,n);
figure('color',[1 1 1])
for k=1:n
    strI = str(strid(k,:));
    %由于默认matlab中text的行间距太大,这里人为约束固定每一行位置
    text(0,1-1/n*k,strI,'FontUnits','normalized','FontSize',1/n,...
        'verticalAlignment','bottom','HorizontalAlignment','center');
end
 %将文字居中
xlim([-1,1]);
axis off
F = getframe;
strdata=F.cdata;
% 保存图像
imwrite(strdata,'lennaNew.png');

处理前原始图

处理后效果图

肿么样?效果还不错吧!如果是视频,可以先对视频进行逐帧字符化处理,然后再逐帧整合就可以获得完整字符化效果的视频,这里就不给大家演示了,自行摸索吧。

参考资料:

原作者:hyhhyh21

原地址:https://blog.csdn.net/weixin_42943114/article/details/91406499

字库源:https://my.oschina.net/u/2510243/blog/716652/

图片来源:https://en.wikipedia.org/wiki/Lena_Forsén

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-01-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 巴山学长 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档