首页 技术 正文
技术 2022年11月23日
0 收藏 430 点赞 4,480 浏览 4202 个字

 

上一节介绍了python PIL库自带的10种滤镜处理,现成的库函数虽然用起来方便,但是对于图像处理的各种实际需求,还需要开发者开发自定义的滤镜算法。本文将给大家介绍如何使用PIL对图像进行自定义的像素级操作

 

本文以剪纸风格图像处理作为例子:(算法借鉴了残阳似血的博客http://qinxuye.me/,特此鸣谢。)

原图:

纯Python综合图像处理小工具(4)自定义像素级处理(剪纸滤镜) 

处理后: 

纯Python综合图像处理小工具(4)自定义像素级处理(剪纸滤镜) 

1.首先将处理参数预先设定好。设定阈值threshold,该阈值会用来区分作为目标颜色的前景色和将要被去除掉的的背景色的分界线。同时设置处理后前景色和后景色的颜色,用以呈现最终的分割效果。

    threshold = 150    bg_color = (255, 255, 255, 0)    fg_color = (255, 0, 0, 255)        if len(sys.argv) >= 2:        path  = sys.argv[1]    if len(sys.argv) == 3:        threshold = int(sys.argv[2])    if len(sys.argv) == 5:        bg_color = tuple(sys.argv[3])        fg_color = tuple(sys.argv[4])

在这一步中,如果阈值threshold设定不同数值,图片会呈现不同的二值分界效果,如下图: 

 纯Python综合图像处理小工具(4)自定义像素级处理(剪纸滤镜)

如果阈值过小,则图像中的斑马,会有部分颜色较浅的前景色,即灰色斑纹被误判成背景色而被滤除掉,从而造成前景图像轮廓的残缺。

如果阈值过大,则与上述情况相反,会有背景色被误判成前景色,造成斑纹的边缘膨胀,视觉上看也类似膨胀的效果(虽然原理完全不同)。

所以,选择一个合适的阈值,对图像的分割效果至关重要。而这一点,又是随着图像不同而变化的,阈值要适应图像内容。

对于这个问题,可以尝试使用动态阈值,结合图像统计来实现自匹配,本文未涉及,有兴趣的童鞋可以自行尝试。

 

2.将图片转换成可以做像素操作的二值像素集合,然后使用设定好的阈值threshold进行前景后景分割:

def Img2bin_arr(img, threshold):    '''    @将位图流转化为二维二值数组    @param img: instance of Image    @param threshold: 大小范围[0, 255]    '''    threshold = max(0, threshold)    threshold = min(255, threshold)        if img.mode != 'L':        img = img.convert('L')            width, height = img.size    pix = img.load()        get_val = lambda p: 255 if p >= threshold else 0            return [[get_val(pix[w, h]) for w in xrange(width)] for h in xrange(height)]

3.将分割好的像素使用预先设定的颜色上色,然后将像素集合重新封装成图片格式,然后返回这个图片,用于保存或显示。

def bin_arr2Img(matrix, bg_color, fg_color):    '''    @将二维二值数组转化为位图流    @param img: instance of Image    @param bg_color: 背景色,元组类型,格式:(L)(灰度),(R, G, B),或者(R, G, B, A)    @param fg_color: 前景色    '''    def ensure_color(color):        if len(color) == 1:            return (color, color, color, 255)        elif len(color) == 3:            color = list(color)            color.append(255)            return tuple(color)        elif len(color) == 4:            return color        else:            raise ValueError, 'len(color) cannot be %d' % len(color)            bg_color = ensure_color(bg_color)    fg_color = ensure_color(fg_color)        height, width = len(matrix), len(matrix[0])    dst_img = Image.new("RGBA", (width, height))    dst_pix = dst_img.load()        for w in xrange(width):        for h in xrange(height):            if matrix[h][w] 

总结:使用python进行像素级图像处理,同其他平台的像素处理类似,整个过程非常清晰,大体上都是三步,拆包-处理-封包。鉴于python的处理速度实在是不敢恭维,所以它是一个很好的算法效果验证平台。 

 

完整代码分享如下:

#start# -*- coding: cp936 -*-import Imageimg = Image.open("1.jpg")def Img2bin_arr(img, threshold):    '''    @将位图流转化为二维二值数组    @param img: instance of Image    @param threshold: 大小范围[0, 255]    '''    threshold = max(0, threshold)    threshold = min(255, threshold)        if img.mode != 'L':        img = img.convert('L')            width, height = img.size    pix = img.load()        get_val = lambda p: 255 if p >= threshold else 0            return [[get_val(pix[w, h]) for w in xrange(width)] for h in xrange(height)]def bin_arr2Img(matrix, bg_color, fg_color):    '''    @将二维二值数组转化为位图流    @param img: instance of Image    @param bg_color: 背景色,元组类型,格式:(L)(灰度),(R, G, B),或者(R, G, B, A)    @param fg_color: 前景色    '''    def ensure_color(color):        if len(color) == 1:            return (color, color, color, 255)        elif len(color) == 3:            color = list(color)            color.append(255)            return tuple(color)        elif len(color) == 4:            return color        else:            raise ValueError, 'len(color) cannot be %d' % len(color)            bg_color = ensure_color(bg_color)    fg_color = ensure_color(fg_color)        height, width = len(matrix), len(matrix[0])    dst_img = Image.new("RGBA", (width, height))    dst_pix = dst_img.load()        for w in xrange(width):        for h in xrange(height):            if matrix[h][w] = 2:        path  = sys.argv[1]    if len(sys.argv) == 3:        threshold = int(sys.argv[2])    if len(sys.argv) == 5:        bg_color = tuple(sys.argv[3])        fg_color = tuple(sys.argv[4])    start = time.time()        img = Image.open(path)    img = paper_cut(img, threshold, bg_color, fg_color)    img.save(os.path.splitext(path)[0]+'.papercut_'+str(threshold)+'.png', 'PNG')    end = time.time()    print 'It all spends %f seconds time' % (end-start) #end

 

微信扫一扫

支付宝扫一扫

本文网址:https://www.zhankr.net/141699.html

上一篇: ORM查询语言OQL
下一篇: phpredis扩展
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:876 阅读:5,464
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:806 阅读:3,688
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:565 阅读:4,503
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:731 阅读:4,468
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:5,379
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:3,263
发表评论
暂无评论

还没有评论呢,快来抢沙发~

助力内容变现

将您的收入提升到一个新的水平

点击联系客服

在线时间:8:00-16:00

客服电话

400-888-8888

客服邮箱

ceotheme@ceo.com

扫描二维码

关注微信公众号

扫描二维码

手机访问本站