Python CV 实现风格化图片转换
前几天遇到一个风格化图片转换的需求,效果像这样:
像这样,需要用纯色圆形填充图像,形成风格化的图片样式。
实现原理
整体原理还是比较简单的,有点类似与马赛克的处理方式。
假设图片宽 w 像素,高 h 像素,需要使用半径为 r 的圆填充好,那么只需要:
- 先把图片划分成边长为 2*r 的栅格;
- 选取每个栅格中心点的像素颜色,作为这个栅格要填充的颜色;
- 新建画布,对每个栅格绘制实心圆形,颜色是上一步计算的结果。
代码分解
读取图片
import cv2 # pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple pip install opencv-python==4.5.5.62img = cv2.imread(target_file)
print(f'Read image, got width={img.shape[1]}, height={img.shape[0]}')
新建画布
dest = numpy.zeros((img.shape[0], img.shape[1], 3), dtype=numpy.uint8)
这个比较简单,就是创建一个三维数组,最低维有三个元素代表颜色(BGR),第二维是行,最高维是列。
划分并遍历栅格
for i in range(0, len(img), circle_radius * 2):# 数组每一行代表图形中的一行,从左上角开始(i相当于y值)for j in range(0, len(img[i]), circle_radius * 2):# 数组每一列代表图形中的一列,从左上角开始(j相当于x值)center = (j + circle_radius, i + circle_radius) # x, y
这里有个比较坑的点,在使用数组遍历所有像素的时候,第一层循环从从上到下遍历图片的每一行,第二层循环从左到右遍历该行的像素。
但是啊但是,CV 中的点坐标以左上角为原点,右方向为 x 轴正方向,下方向为 y 轴正方向。注意看这个 center,它的点表示要和数组访问恰好相反。
获取颜色并在新画布绘制圆形
point_color_arr = img[min(center[1], len(img)) - 1][min(center[0], len(img[i])) - 1]
point_color = (int(point_color_arr[0]), int(point_color_arr[1]), int(point_color_arr[2])) # BGR
cv2.circle(dest, center, circle_radius, point_color, -1)
取中点处的颜色,即是我们要的颜色。注意这里访问的时候是 img[center[1]][center[0]]
,就是因为前面说的,点坐标与数组下标恰好相反。
优化:取栅格中全部颜色的平均值
我们还可以顺带实现一下类似于马赛克的那种,每个格子颜色取平均值,这样能使格子之间的颜色过渡更自然。
n_points = 0
point_color = [0, 0, 0]
for ii in range(i, min(i + circle_radius * 2, len(img)), 1):for jj in range(j, min(j + circle_radius * 2, len(img[i])), 1):n_points += 1point_color += img[ii][jj]
point_color = tuple([int(x / n_points) for x in point_color])
这里唯一要注意的点就是,直接从 img 读出来的是数组,我们需要转换成 int tuple 才能用。
写入文件或显示到屏幕
显示到屏幕可以这样:
cv2.namedWindow("image")
cv2.imshow('image', dest)
cv2.waitKey(100000) # 显示 10000 ms 即 10s 后消失
cv2.destroyAllWindows()
要把图片保存到文件可以这样:
dest_file = 'dest-test-29-t.png'
cv2.imwrite(dest_file, dest)
完整源代码
circle_radius = 29 # in px
target_file = 'test.png'
dest_file = 'dest-test-29-t.png'
use_average = True
save_file = Trueimport cv2 # opencv默认读取格式是BGR
import numpy
import tqdm# Press the green button in the gutter to run the script.
if __name__ == '__main__':img = cv2.imread(target_file)print(f'Read image, got width={img.shape[1]}, height={img.shape[0]}')dest = numpy.zeros((img.shape[0], img.shape[1], 3), dtype=numpy.uint8)for i in tqdm.tqdm(range(0, len(img), circle_radius * 2), "Processing: "):# 数组每一行代表图形中的一行,从左上角开始(i相当于y值)for j in range(0, len(img[i]), circle_radius * 2):# 数组每一列代表图形中的一列,从左上角开始(j相当于x值)center = (j + circle_radius, i + circle_radius) # x, y# calculate color for this area, get averageif use_average:n_points = 0point_color = [0, 0, 0]for ii in range(i, min(i + circle_radius * 2, len(img)), 1):for jj in range(j, min(j + circle_radius * 2, len(img[i])), 1):n_points += 1point_color += img[ii][jj]point_color = tuple([int(x / n_points) for x in point_color])else:point_color_arr = img[min(center[1], len(img)) - 1][min(center[0], len(img[i])) - 1]point_color = (int(point_color_arr[0]), int(point_color_arr[1]), int(point_color_arr[2])) # BGRcv2.circle(dest, center, circle_radius, point_color, -1)if save_file:cv2.imwrite(dest_file, dest)else:cv2.namedWindow("image")cv2.imshow('image', dest)cv2.waitKey(100000) # 显示 10000 ms 即 10s 后消失cv2.destroyAllWindows()
程序效果
原图:
使用中心点作为颜色来源:
使用颜色平均值:
Python CV 实现风格化图片转换相关推荐
- python动态图片转字符画_使用python实现一个将图片转换成字符画的功能
使用python实现一个将图片转换成字符画的功能 发布时间:2020-11-05 16:01:25 来源:亿速云 阅读:97 使用python实现一个将图片转换成字符画的功能?针对这个问题,这篇文章详 ...
- python tif格式的图片转换成其他格式
为了解决python 将tif格式图片用cv2等其他包转成其他格式,会出现图片变成灰色或者其他颜色的问题. 用第三方库tifffile就可以完全解决这个问题,代码如下: import tifffile ...
- python PIL库将图片转换成字符画
将图片转换成文本文件查看形式 准备 源码 原始图像 生成文本文件后显示的结果 注意事项 准备 语言:python 环境:PIL库,准备好图片素材 源码 from PIL import Image as ...
- [Python]PDF文件与图片转换(PyMuPDF)及转PPT
文章目录 安装与简介 MuPDF PyMuPDF PyMuPDF使用 元数据 页面Page 代码示例 PDF转图片 图片转PDF PDF转PPT PyMuPDF提供了PDF及流行图片处理接口. 安装与 ...
- python修改文件格式为jpg_python将.ppm格式图片转换成.jpg格式文件的方法
python将.ppm格式图片转换成.jpg格式文件的方法 将.ppm格式的图片转换成.jpg格式的图像,除了通过软件转换,还可以使用python脚本直接转换,so easy!!! from PIL ...
- python3图片转代码_python3图片转换二进制存入mysql示例代码
python3图片转换二进制存入mysql示例代码 发布于 2014-09-29 18:00:01 | 198 次阅读 | 评论: 0 | 来源: 网友投递 Python编程语言Python 是一种面 ...
- c语言将一幅画转换为字符画,C#将图片转换成字符画
先看一下效果图 在Main方法中调用(首先要添加程序集System.Drawing,然后引入命名空间System.Drawing) ConvertToChar(new Bitmap(@"D: ...
- python二进制和图片转换
python二进制和图片转换 之前做项目,发现很多图片都是存储成二进制的形式,比如存储为.bin .dat等文件,如果你直接用记事本打开文件,会发现里面内容如下: 0005 0000 0000 000 ...
- Python关于人脸图片转换128/512维度向量的两种做法
近期工作需要调研关于人脸转换向量存储到自家的数据库去做人脸识别,所以我在网上pick了两种关于人脸转换向量的两种简单做法,但是作为一个java开发工程师,对python的使用不是很精通,所以代码仅供参 ...
最新文章
- 全球AI技术开放日系列之(七):走进阿里业务中台
- 监控web站点目录下所有文件是否被恶意篡改
- C++函数的传入参数是指针的指针(**)的详解
- 前端学习(2024)vue之电商管理系统电商系统之根据分页获取订单列表数据
- 如何在 Ubuntu 和 CentOS 上启用 Nginx 的 HTTP/2 协议支持
- html主要的骨架结构
- 【Presto】Cannot connect to discovery server for announce: Announcement failed with status code 404
- PgSQL · 应用案例 · 逻辑订阅给业务架构带来了什么?
- 一篇文章为你深度解析HTTPS 协议 1
- 落谷 P3375 【模板】KMP字符串匹配
- BZOJ 4030: [HEOI2015]小L的白日梦
- 冰点文库下载器,免积分下载百度文库文档
- 华为IPD你学不会(转)
- Vue中使用Bscroll @click无法执行的问题
- SmartFoxServer,多人flash游戏开发
- jbe 可以用来修改Java class的字节码,配合jd-gui 使用
- CODE RO RW ZI的区别
- 颠覆平庸 在技术上持续精进
- 点滴收集-HyperSnap 截图工具
- php小说在线阅读下载网站