死宅一枚。爬取5000张二次元妹子的图片,生成了头图。

接下来看看怎么实现的:

使用 Scrapy 框架爬取5000张二次元图

使用 opencv 批量格式化图片

将图片按照RGB值的均方根排序,实现效果

一、安装环境

1.安装 Scrapy 爬虫框架

pip install Scrapy

windows 安装可以 点击此处

2. 推荐使用 wheel 来安装 opencv 点击此处

3.安装 numpy 科学计算库

pip install numpy

4. 初始化一个 Scrapy 项目 acg

scrapy startproject acg

二、爬取图片

以下代码主要实现操作:

中间裁剪

统一大小

下载图片

重复抓取

/image.py

import scrapy

import urllib.request,urllib.parse

import numpy as np

import cv2

class acgimages(scrapy.Spider):

"""docstring for acgimages"""

name = 'images'

start_urls = [

"http://m.52dmtp.com/tupiandaquan/index_2.html"

]

count = 1

page = 2

def parse(self,response):

def imageSave(item,path):

try:

maxsize = 512

res = urllib.request.urlopen(item).read()

image = np.asarray(bytearray(res),dtype="uint8")

image = cv2.imdecode(image,cv2.IMREAD_COLOR)

height,width = image.shape[:2]

if height > width:

scalefactor = (maxsize*1.0) / width

res = cv2.resize(image,(int(width * scalefactor),(int(height * scalefactor))),interpolation = cv2.INTER_CUBIC)

cutImage = res[0:maxsize,0:maxsize]

if width >= height:

scalefactor = (maxsize*1.0) / height

res = cv2.resize(image,(int(width * scalefactor), int(height*scalefactor)), interpolation = cv2.INTER_CUBIC)

center_x = int(round(width*scalefactor*0.5))

cutImage = res[0:maxsize,int(center_x - maxsize/2):int(center_x + maxsize/2)]

cv2.imwrite(path,cutImage)

print('image is save in ' + path)

except:

print('image save error')

image_url = response.xpath("//div[@class='grid-wrap']//img/@src").extract()

for item in image_url:

item = item.split('?')[0]

item = urllib.parse.quote(item,safe='/:?=.')

if 'jpg' in item:

self.count = self.count + 1

path = 'img/'+ str(self.count) + ".jpg"

imageSave(item,path)

if 'png' in item:

self.count = self.count + 1

path = 'img/'+ str(self.count) + ".png"

imageSave(item,path)

if self.page < 1180:

self.page = self.page + 1

next_url = "http://m.52dmtp.com/tupiandaquan/index_%d.html"%self.page

yield scrapy.Request(next_url,callback = self.parse)

三、生成图片

1.创建一个图片数据库

2.导入图片

3.导入过程中

4.创建一个马赛克风格图片

5.打开原图

6.选择已经上传的数据库

7.生成完成

简单高效的平民玩法到此结束。

2017年12月10日 本来今天开开心心。被迫更新

一、安装依赖

1.安装图像处理库 pillow

pip install pillow

二、使用 python 做到马赛克拼图效果

写在前面,有人私信说 hsv(颜色空间)做效果会更好。大家可以尝试一下,这里的话只是对rgb的对比。主要效果差上面提到的程序一点,答主也在尽可能的优化代码,有更好的方法,欢迎私信评论。

核心部分:求像素平均值,尝试过了方差和均方根,个人对整体优化并不明显。

def get_avg_color(img):

width, height = img.size

pixels = img.load()

data = []

for x in range(width):

for y in range(height):

content = pixels[x, y]

data.append(content)

r = 0

g = 0

b = 0

count = 0

for x in range(len(data)):

r += data[x][0]

g += data[x][1]

b += data[x][2]

count += 1

rAvg = r / count

gAvg = g / count

bAvg = b / count

return (rAvg, gAvg, bAvg)

核心部分:对比图片块颜色与马赛克块平均颜色差值。很重要的一步就是,求出近似值数组后,取一个随机数,有效的解决马赛克块重复问题(不是不重复使用,因为这样需要的图片集会很大)。

def find_closiest(color, list_colors):

diff = 10000

cur_closer = []

arr_len = 0

for cur_color in list_colors:

n_diff = abs(color[0] - cur_color[0]) + abs(color[1] - cur_color[1]) + abs(color[2] -cur_color[2])

if n_diff < diff:

diff = n_diff

if len(cur_closer) <= 5:

cur_closer.append(cur_color)

else:

cur_closer[arr_len] = cur_color

arr_len += 1

if arr_len > 5:

arr_len = 0

index = random.randint(0,len(cur_closer) - 1)

return cur_closer[index]

核心部分: 图片分割并且按图片集名字对比就近的图片

def make_puzzle(img, color_list):

width, height = img.size

print("Width = {}, Height = {}".format(width,height))

background = Image.new('RGB', img.size, (255,255,255))

total_images = 0

for y1 in range(0, heigth, SLICE_SIZE):

for x1 in range(0, width, SLICE_SIZE):

y2 = y1 + SLICE_SIZE

x2 = x1 + SLICE_SIZE

new_img = img.crop((x1, y1, x2, y2))

color = get_avg_color(new_img)

close_img_name = find_closiest(color, color_list)

close_img_name = OUT_DIR + str(close_img_name) + '.jpg'

paste_img = Image.open(close_img_name)

total_images += 1

print("%s images \r" % total_images),

background.paste(paste_img, (x1, y1))

return background

全部代码 /main.py

import os

from PIL import Image,ImageOps

import argparse

import time

# 多进程,

from multiprocessing import Pool

import random

import math

# 少年,你不试试看hsv吗,据说效果更好

from colorsys import rgb_to_hsv

SLICE_SIZE = 60 # 马赛克大小

OUT_SIZE = 5000 # 图片大小(注意:要做到清晰,必须要大)

IN_DIR = "database/"

OUT_DIR = "output/"

def get_avg_color(img):

width, height = img.size

pixels = img.load()

data = []

for x in range(width):

for y in range(height):

content = pixels[x, y]

data.append(content)

r = 0

g = 0

b = 0

count = 0

for x in range(len(data)):

r += data[x][0]

g += data[x][1]

b += data[x][2]

count += 1

rAvg = r / count

gAvg = g / count

bAvg = b / count

return (rAvg, gAvg, bAvg)

def find_closiest(color, list_colors):

diff = 10000

cur_closer = []

arr_len = 0

for cur_color in list_colors:

n_diff = abs(color[0] - cur_color[0]) + abs(color[1] - cur_color[1]) + abs(color[2] -cur_color[2])

if n_diff < diff:

diff = n_diff

if len(cur_closer) <= 5:

cur_closer.append(cur_color)

else:

cur_closer[arr_len] = cur_color

arr_len += 1

if arr_len > 5:

arr_len = 0

index = random.randint(0,len(cur_closer) - 1)

return cur_closer[index]

def make_puzzle(img,color_list):

width, height = img.size

print("Width = {}, Height = {}".format(width,heigth))

background = Image.new('RGB', img.size, (255,255,255))

total_images = 0

for y1 in range(0, heigth, SLICE_SIZE):

for x1 in range(0, width, SLICE_SIZE):

y2 = y1 + SLICE_SIZE

x2 = x1 + SLICE_SIZE

new_img = img.crop((x1, y1, x2, y2))

color = get_avg_color(new_img)

close_img_name = find_closiest(color, color_list)

close_img_name = OUT_DIR + str(close_img_name) + '.jpg'

paste_img = Image.open(close_img_name)

total_images += 1

print("%s images \r" % total_images),

background.paste(paste_img, (x1, y1))

return background

def get_image_paths():

paths = []

for file_ in os.listdir(IN_DIR):

paths.append(IN_DIR + file_)

print("一共找到了%s" % len(paths) + "张图片")

return paths

def resize_pic(in_name,size):

img = Image.open(in_name)

img = ImageOps.fit(img, (size, size), Image.ANTIALIAS)

return img

def convert_image(path):

img = resize_pic(path,SLICE_SIZE)

color = get_avg_color(img)

img.save(str(OUT_DIR) + str(color) + ".jpg")

def convert_all_images():

paths = get_image_paths()

pool = Pool()

pool.map(convert_image, paths)

pool.close()

pool.join()

def read_img_db():

img_db = []

for file_ in os.listdir(OUT_DIR):

print(file_)

if file_ == 'None.jpg':

pass

else:

file_ = file_.split('.jpg')[0]

file_ = tuple(map(float, file_[1:-1].split(',')))

img_db.append(file_)

return img_db

if __name__ == '__main__':

parse = argparse.ArgumentParser()

parse.add_argument("-i",'--input',required=True,help='input image')

parse.add_argument("-d", "--db", type=str, required=True,help="source database")

parse.add_argument("-o", "--output", type=str, required=True,help="out directory")

parse.add_argument("-is",'--inputSize',type=str, required=False,help="inputSize")

parse.add_argument("-os",'--outputSize',type=str, required=False,help="outputSize")

args = parse.parse_args()

start_time = time.time()

args = parse.parse_args()

image = args.input

if args.db:

IN_DIR = args.db

if args.output:

OUT_DIR= args.output

if args.inputSize:

SLICE_SIZE = args.inputSize

if args.outputSize:

OUT_SIZE = args.outputSize

img = resize_pic(image,OUT_SIZE)

convert_all_images()

list_of_imgs = read_img_db()

# 为了添加图片信息量,合并两张图片

out = make_puzzle(img, list_of_imgs)

img = Image.blend(out, img, 0.5)

img.save('out.jpg')

print("耗时: %s" % (time.time() - start_time))

print("已完成")

命令行输入

python main.py -i test.jpg(你的图片) -d D:/acg/img/(你的图片集合) -o output/(你的马赛克图片输出位置)

当然,你还可以给你的 background 滤色

上传一张结果图(根据喜欢,精度可以更高),知乎限制5m了

非洲小鸟,黑白对比度处理任然是败笔,建议还是 hsv

这个模型更适合颜色适配。

后续将会发布优化版本。

作者:今晚的风儿很喧嚣

python 马赛克拼图_使用 python 做到马赛克拼图相关推荐

  1. python 时间序列预测_使用Python进行动手时间序列预测

    python 时间序列预测 Time series analysis is the endeavor of extracting meaningful summary and statistical ...

  2. python 概率分布模型_使用python的概率模型进行公司估值

    python 概率分布模型 Note from Towards Data Science's editors: While we allow independent authors to publis ...

  3. python集群_使用Python集群文档

    python集群 Natural Language Processing has made huge advancements in the last years. Currently, variou ...

  4. python 网页编程_通过Python编程检索网页

    python 网页编程 The internet and the World Wide Web (WWW), is probably the most prominent source of info ...

  5. python机器学习预测_使用Python和机器学习预测未来的股市趋势

    python机器学习预测 Note from Towards Data Science's editors: While we allow independent authors to publish ...

  6. python高斯求和_利用Python进行数据分析(3)- 列表、元组、字典、集合

    本文主要是对Python的数据结构进行了一个总结,常见的数据结构包含:列表list.元组tuple.字典dict和集合set. image 索引 左边0开始,右边-1开始 通过index()函数查看索 ...

  7. python 免费空间_用python做大数据

    不学Python迟早会被淘汰?Python真有这么好的前景? 最近几年Python编程语言在国内引起不小的轰动,有超越Java之势,本来在美国这个编程语言就是最火的,应用的非常非常的广泛,而Pytho ...

  8. python希腊字母字符串_#10 Python字符串

    前言 通过上一节可知,Python6个序列的内置类型中,最常见的是列表和元组,但在Python中,最常用的数据类型却不是列表和元组,而是字符串.要想深入了解字符串,必须先掌握字符编码问题.因此本篇博文 ...

  9. 使用python预测基金_使用python先知3 1创建预测

    使用python预测基金 This tutorial was created to democratize data science for business users (i.e., minimiz ...

  10. python选择题题目_《Python程序设计》题库 - 选择题

    一.基础知识 1 . Python 语言属于( ) . C A . 机器语言 B . 汇编语言 C .高级语言 D .科学计算语言 2 .下列选项中,不属于 Python 特点的是( ) . B A ...

最新文章

  1. ADO.NET并发性
  2. java不建议用全局变量吗_不要使用全局变量, ThreadLocal也不行
  3. 10 条真心有趣的 Linux 命令
  4. 牛客网刷题(纯java题型 211~240题)
  5. python怎么命名未知数_Python4要来了?快来看看Python之父怎么说
  6. 猜你喜欢代码替换_如何在 GitHub 上找到你要的代码?
  7. android 摄像头检测工具,检摄app2.0.2最新版(摄像头检测)
  8. 绝对纯净:龙行天下GHOST XP SP3软件自选安装纯净版 2010 V13.0 2010年6月
  9. 风险预测模型_只学有用的:贷后评分模型的三种细分应用
  10. 神经网络加速器的兴起
  11. A*算法解决传教士—野人过河问题
  12. meterpreter_paranoid_mode.sh允许用户安全上演/无级连接Meterpreter经检查合格证书的处理程序正在连接到...
  13. 从淘宝P5到天猫总监,她的阿里十年发生了什么?
  14. 别再用PS啦!用Excel轻松实现更换证件照背景颜色!
  15. 【重新安装MySql5.7.24 / MySql57过程】好多个错误,慢慢改好的
  16. 马小妹的Android之旅——Android四大基本组件之Activity
  17. matlab的pnpoly,PNPoly 算法
  18. css魔法 真名,CSS3系列:魔法系列
  19. ubuntu12.04打开qt5.2.0時出现异常
  20. 这个冬天,我爱上了冻酸奶

热门文章

  1. 别只盯着LoRa、SigFox, LPWAN 连接技术还有这些!
  2. 2019.4 sigfox EMC
  3. Python爬虫+颜值打分,5000+图片找到你的Mrs. Right
  4. oos的上传和下载2
  5. cesium中的飞行动画fly
  6. Android 9.0 cmds
  7. vue 不同条件展示不同页面_vue根据条件不同显示不同按钮的操作
  8. SQL统计语句总结(运用场景:运营分析,财务分析等)
  9. persistence.cpp:2197:ann.xml(1): There should be space between attributes in function icvXMLParseTag
  10. 远心镜头与普通镜头拍摄工件孔径对比