python 马赛克拼图_使用 python 做到马赛克拼图
死宅一枚。爬取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 做到马赛克拼图相关推荐
- python 时间序列预测_使用Python进行动手时间序列预测
python 时间序列预测 Time series analysis is the endeavor of extracting meaningful summary and statistical ...
- python 概率分布模型_使用python的概率模型进行公司估值
python 概率分布模型 Note from Towards Data Science's editors: While we allow independent authors to publis ...
- python集群_使用Python集群文档
python集群 Natural Language Processing has made huge advancements in the last years. Currently, variou ...
- python 网页编程_通过Python编程检索网页
python 网页编程 The internet and the World Wide Web (WWW), is probably the most prominent source of info ...
- python机器学习预测_使用Python和机器学习预测未来的股市趋势
python机器学习预测 Note from Towards Data Science's editors: While we allow independent authors to publish ...
- python高斯求和_利用Python进行数据分析(3)- 列表、元组、字典、集合
本文主要是对Python的数据结构进行了一个总结,常见的数据结构包含:列表list.元组tuple.字典dict和集合set. image 索引 左边0开始,右边-1开始 通过index()函数查看索 ...
- python 免费空间_用python做大数据
不学Python迟早会被淘汰?Python真有这么好的前景? 最近几年Python编程语言在国内引起不小的轰动,有超越Java之势,本来在美国这个编程语言就是最火的,应用的非常非常的广泛,而Pytho ...
- python希腊字母字符串_#10 Python字符串
前言 通过上一节可知,Python6个序列的内置类型中,最常见的是列表和元组,但在Python中,最常用的数据类型却不是列表和元组,而是字符串.要想深入了解字符串,必须先掌握字符编码问题.因此本篇博文 ...
- 使用python预测基金_使用python先知3 1创建预测
使用python预测基金 This tutorial was created to democratize data science for business users (i.e., minimiz ...
- python选择题题目_《Python程序设计》题库 - 选择题
一.基础知识 1 . Python 语言属于( ) . C A . 机器语言 B . 汇编语言 C .高级语言 D .科学计算语言 2 .下列选项中,不属于 Python 特点的是( ) . B A ...
最新文章
- ADO.NET并发性
- java不建议用全局变量吗_不要使用全局变量, ThreadLocal也不行
- 10 条真心有趣的 Linux 命令
- 牛客网刷题(纯java题型 211~240题)
- python怎么命名未知数_Python4要来了?快来看看Python之父怎么说
- 猜你喜欢代码替换_如何在 GitHub 上找到你要的代码?
- android 摄像头检测工具,检摄app2.0.2最新版(摄像头检测)
- 绝对纯净:龙行天下GHOST XP SP3软件自选安装纯净版 2010 V13.0 2010年6月
- 风险预测模型_只学有用的:贷后评分模型的三种细分应用
- 神经网络加速器的兴起
- A*算法解决传教士—野人过河问题
- meterpreter_paranoid_mode.sh允许用户安全上演/无级连接Meterpreter经检查合格证书的处理程序正在连接到...
- 从淘宝P5到天猫总监,她的阿里十年发生了什么?
- 别再用PS啦!用Excel轻松实现更换证件照背景颜色!
- 【重新安装MySql5.7.24 / MySql57过程】好多个错误,慢慢改好的
- 马小妹的Android之旅——Android四大基本组件之Activity
- matlab的pnpoly,PNPoly 算法
- css魔法 真名,CSS3系列:魔法系列
- ubuntu12.04打开qt5.2.0時出现异常
- 这个冬天,我爱上了冻酸奶
热门文章
- 别只盯着LoRa、SigFox, LPWAN 连接技术还有这些!
- 2019.4 sigfox EMC
- Python爬虫+颜值打分,5000+图片找到你的Mrs. Right
- oos的上传和下载2
- cesium中的飞行动画fly
- Android 9.0 cmds
- vue 不同条件展示不同页面_vue根据条件不同显示不同按钮的操作
- SQL统计语句总结(运用场景:运营分析,财务分析等)
- persistence.cpp:2197:ann.xml(1): There should be space between attributes in function icvXMLParseTag
- 远心镜头与普通镜头拍摄工件孔径对比