素描作为一种近乎完美的表现手法有其独特的魅力,随着数字技术的发展,素描早已不再是专业绘画师的专利,今天这篇文章就来讲一讲如何使用python批量获取小姐姐素描画像。文章共分两部分:

  • 第一部分介绍两种使用python生成素描画的思路

  • 第二部分介绍如何批量获取素描画

一、获取素描图的两个思路

本部分介绍的两个思路都是基于opencv来实现,不涉及深度学习相关内容。基本思想是读入一张照片图,然后通过各种变换转化成素描图。为了演示方便,我们先找来一张小姐姐的照片作为实验素材。

1、漫画风格

先来说第一种方法,这种方法的核心思想是利用了名为“阈值化”的技术,这种技术是基于图像中物体与背景之间的灰度差异,而进行的像素级别的分割。

如果想要把一张图片转化为只呈现黑色和白色的素描图,就需要对其进行二值化操作,opencv中提供了两种二值化操作方法:threshold()和adaptiveThreshold()。相比threshold(),adaptiveThreshold()能够根据图像不同区域亮度分布进行局部自动调节,因此被称为自适应二值化。下面这幅图就是对彩色图片进行二值化操作后的效果。

上面提到的概念可能比较晦涩,不理解也没有关系,下面我们重点讲讲怎么进行实际操作。

第一步,读入图片并转化为灰度图。这一步算是常规操作了,相信使用过opencv的同学都写过类似的代码。

img_rgb = cv2.imread(src_image)
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2GRAY)

第二步,使用adaptiveThreshold()方法对图片进行二值化操作,函数中的参数大多用于设置自适应二值化的算法和阈值等。

img_edge = cv2.adaptiveThreshold(img_gray, 255,
cv2.ADAPTIVE_THRESH_MEAN_C,
cv2.THRESH_BINARY, blockSize=3, C=2)

第三步,保存转换后的图片

cv2.imwrite(dst_image, img_edge)

经过上述步骤的操作,我们得到了一幅新的黑白图片,一起来看看转换后的图片效果。

从转换后的图片来看,虽然大概轮廓没有问题,但是效果很不理想,并不能够称之为素描图。这主要是因为adaptiveThreshold()会在图片的每一个小的局部区域内进行二值化操作,因此对于一些清晰度比较高、色彩区分比较细腻的图片,就会出现上面这样密密麻麻的情况。

这个问题解决起来其实也很简单,只要在进行二值化之前加入下面这行代码对原图进行模糊化就可以了。

img_gray = cv2.medianBlur(img_gray, 5)

再来看看这次生成的素描图(下图),是不是看起来舒服多了,还有一种手绘漫画的感觉。

2、写实风格

通过上面这种方法,虽然最终也获得了一幅还算不错的素描图,但是看起来多少有些“失真”,为了获取看起来更加真实的素描图,我们尝试另外一种方法。

这种方法的核心思想是通过“底片融合”的方式获取原图中一些比较重要的线条,具体实现步骤如下:

第一步,跟上面的方法一样,使用opencv读取图片并生成灰度图。

第二步,对灰度图进行模糊化操作。经过试验,使用上面提到的中值滤波函数cv2.medianBlur()进行模糊化操作最终得到的素描图效果并不好,这里我们尝试使用高斯滤波进行图片模糊化,代码如下:

img_blur = cv2.GaussianBlur(img_gray, ksize=(21, 21),
sigmaX=0, sigmaY=0)

其中,参数ksize表示高斯核的大小,sigmaX和sigmaY分别表示高斯核在 X 和 Y 方向上的标准差。

第三步,使用cv2.divide()方法对原图和模糊图像进行融合,cv2.divide()本质上进行的是两幅图像素级别的除法操作,其得到的结果可以简单理解为两幅图之间有明显差异的部分。来看代码:

cv2.divide(img_gray, img_blur, scale=255)

第四步,保存生成的图片,代码跟上一个方法中一样,我们直接来看获取到的素描图效果。

从结果来看,这种方法获得的素描图线条更加细腻,素描效果也更好。

二、批量获取小姐姐素描画像

在这一部分,我们要实现批量获取小姐姐素描画像的功能,基于上文中两种素描图效果比对,这里采用第二种方法来实现图片到素描图的转换。

那么,接下来要解决的就是图片源的问题了。最近很多项目都成功实现了从抖音或者知乎获取漂亮小姐姐这一操作,其实除了这些平台之外还有好多网站能获取到漂亮小姐姐的图片。

网站的具体内容我就不在文中展示了,为了指定图片爬取的思路,大概讲下页面结构:网站的主页罗列了N个主题,每个主题页面中都包含了M张小姐姐的图片,结构示意图如下:

各页面url的构建也很明了,例如下图中的页面url是http://www.waxjj.cn/2794.html,其中2794就是主题页的ID号。查看页面的html代码(下图),发现每张图片都在一个<li>标签下面。

遇到这种情况,一般来说我们可以通过某种解析器来获取每张图片的url。但是,经过仔细观察发现整个网页的html代码中只有涉及图片url的部分带有完整的http连接,因此可以考虑使用正则表达式来提取图片url,实现这部分功能的代码如下。

在上面这段代码中,我们提取主题页的ID作为待保存图片名称的一部分,save_jpg()函数中会把每张图片转换为素描图并保存到本地。

由于我们要使用opencv对抓取到的图片进行各种运算转换,因此使用requests获取的图片必须先保存到本地,再用opencv重新读入后才行。基于上述思想,我们构建了如下所示的save_jpg()函数,其中rgb_to_sketch()函数是对上文第一部分中所说的第二种素描图的获取方法进行的封装。

而在主函数中,我们只需要指定想要获取主题页面的id号,构建一组url列表就可以了:

def main():
idlist = ['id1', 'id2']
urllist = ['http://www.waxjj.cn/'+x+'.html' for x in idlist]
jpgurls = get_jpg_urls(urllist)

以上就是完整代码,在学习Python的过程中,往往因为没有资料或者没人指导从而导致自己不想学下去了,因此我特意准备了个群 592539176 ,群里有大量的PDF书籍、教程都给大家免费使用!不管是学习到哪个阶段的小伙伴都可以获取到自己相对应的资料!来看看运行后的效果吧~~

其实程序员要想防止脱发,我觉得还是要多锻炼身体,少熬夜,当然多看看养眼的小姐姐也不是不错的!

你说呢

女神说拍了一套写真集想弄成素描画?很简单,用Python就行了!的更多相关文章

  1. CF 327D - Block Tower 数学题 DFS 初看很难,想通了就感觉很简单

    D. Block Tower time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...

  2. Azure进阶攻略 | VS2015和Azure,想要在一起其实很容易

    下雨天,巧克力和音乐很配…… 大冬天,男神和捧在手里的奶茶很配…… 「驴牌」的包包,和女神的全部衣服都配…… 对于「王首富」,容易实现的小目标和一个亿是绝配…… …… 醒醒吧!!这些事情和每天只会写代 ...

  3. 想转行做3D游戏模型,如何快速入行

    随着技术和硬件迭代,3D建模,广泛运用在游戏,影视,动画,VR等领域,而且就业面非常广. 由于3D美术设计师薪资和前景确实都不错,很多同学想进入这个行业,从事相关工作,但是没有一个整体的学习思路和规划 ...

  4. 想在java接口自动化里用上Python的requests?这样做就可以了

    相信现在很多的公司自动化测试重点都在接口层,因为接口测试更加接近代码底层,相对于UI自动化,接口自动化有着开发更快.覆盖更全.回报率高等优点. 接口自动化代码实现不难,本质上就是代码模拟发送请求,然后 ...

  5. php基础知识(很简单一套适合零基础的朋友学习)

    红色的一般都是重点,还有自己的一些废话 运算符 算术运算符: 基本运算(除数不能为0) 比较运算符: 大小比较(类型比较), 如果两个类型不一样,系统会自动转换成统一类型 赋值运算符: 基本赋值和运算 ...

  6. 海尔公布首套智能套装SmartCare,主打智能、简单

        2014CIE智能硬件首发会于11月6-8日在上海国际展览中心举行.吸引了海尔.英特尔.百度等知名企业的积极參与. 作为国内智能家居领域的先驱者,海尔在本次大会上首发了轻量智能套装SmartC ...

  7. LeetCode 75,90%的人想不出最佳解的简单题

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode专题的44篇文章,我们一起来看下LeetCode的75题,颜色排序 Sort Colors. 这题的官方难度是Medi ...

  8. 牵扯较多属性和方法的类题目,很简单的题目本来不想发的,如果有同学学到这个题目感觉太长不愿敲代码,copy走我的即可~不过还是建议自己打一打

    /* 3.设计一个"学生"类 1> 属性 * 姓名 * 生日 * 年龄 * 身高(单位是m) * 体重(单位是kg) * 性别 * C语言成绩 * OC成绩 * iOS成绩 ...

  9. 想弄清楚LIBEVENT和EPOLL之类的关系,不要因为走得太急而迷失了方向

    要一步一步构架起整个体系, 来日方长. 系统调用级别的EPOLL和函数库LIBEVENT之间,大体关系应该是如何呢? 网上有说法: ~~~~~~~~~~~~~~ libevent对底层多路复用机制的封 ...

随机推荐

  1. DP_1d1d诗人小G

    显然:f[i]=min{f[j]+(s[i]-s[j]+i-j-1-l)^p} 此题可以基于决策单调优化 证明,反正我现在不打算学 实际上就是双向队列 不停弹出队头的元素,直到当前位置在队头元素最优的 ...

  2. Euler Sums系列(六)

    \[\Large\displaystyle \sum_{n=1}^{\infty}\frac{H_{2n}}{n(6n+1)}\] \(\Large\mathbf{Solution:}\) Let \ ...

  3. jsp+servlet实现的验证登陆

    可以将业务逻辑处理和视图相分离,使用jsp界面表示视图,使用servlet处理业务逻辑 login.jsp <%@ page language="java" contentT ...

  4. IDE - IDEA - tab - 方法相关的移动

    1. 概述 标题可能会改 一个 tab 里方法相关的操作 2. 前提 以默认的模式编辑 tab 对我来说, 就关掉 vim 插件 3. 操作 1. 查看文件结构 概述 唤出当前文件的 结构 唤出后可以 ...

  5. Codeforces Round #614 (Div. 2)E(思维,构造,DP)

    构造边权,从0开始给边赋值,初始选取一条边权为0,每次赋值的贡献为这一条链两侧的结点(包含链的端点)个数之积,下一次赋值以当前链其一端点续一条边,边权为上次赋的值+1.先DFS找到点的组合这条链两侧结 ...

  6. Codeforces Round #610 (Div. 2)E(模拟,DFS)

    先找到一条多边形的边,然后循环一圈输出多边形上的点.把每个三角形看作一个结点,以两个三角形之间公用边为边建立一张图,DFS输出叶子结点,则得到先切后切的顺序. #define HAVE_STRUCT_ ...

  7. Mac电脑安装openresty

    安装brew 软件仓库, /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/ ...

  8. 【C语言】找出1000以内可以被3整除的数

    分别用while,do-while,for语句实现 方法一:while #include<stdio.h> int main() { int m; m = ; ) { == ) print ...

  9. hadoop学习笔记(五)hadoop伪分布式集群的搭建

    本文原创,如需转载,请注明作者和原文链接 1.集群搭建的前期准备   见      搭建分布式hadoop环境的前期准备---需要检查的几个点 2.解压tar.gz包 [root@node01 ~]# ...

  10. JDK动态代理+反射实现动态修改注解属性值

    这是最近朋友的一个需求,正好闲来无聊有些时间,跟着研究一下,如有不正确的地方,欢迎大家指正~ 一.准备自定义注解 注:如何实现自定义注解,请移步百度. 二.实现 1.实现方式1:通过反射+动态代理动态 ...