1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > python给图片加滤镜的方程_纯Python综合图像处理小工具(4)自定义像素级处理(剪纸滤

python给图片加滤镜的方程_纯Python综合图像处理小工具(4)自定义像素级处理(剪纸滤

时间:2023-12-08 13:55:32

相关推荐

python给图片加滤镜的方程_纯Python综合图像处理小工具(4)自定义像素级处理(剪纸滤

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

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

原图:

处理后:

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

threshold=150

bg_color=(255,255,255,0)

fg_color=(255,0,0,255)

iflen(sys.argv)>=2:

path=sys.argv[1]

iflen(sys.argv)==3:

threshold=int(sys.argv[2])

iflen(sys.argv)==5:

bg_color=tuple(sys.argv[3])

fg_color=tuple(sys.argv[4])

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

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

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

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

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

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

defImg2bin_arr(img,threshold):

'''@将位图流转化为二维二值数组

@paramimg:instanceofImage

@paramthreshold:大小范围[0,255]'''

threshold=max(0,threshold)

threshold=min(255,threshold)

ifimg.mode!='L':

img=img.convert('L')

width,height=img.size

pix=img.load()

get_val=lambdap:255ifp>=thresholdelse0

return[[get_val(pix[w,h])forwinxrange(width)]forhinxrange(height)]

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

defbin_arr2Img(matrix,bg_color,fg_color):

'''@将二维二值数组转化为位图流

@paramimg:instanceofImage

@parambg_color:背景色,元组类型,格式:(L)(灰度),(R,G,B),或者(R,G,B,A)

@paramfg_color:前景色'''

defensure_color(color):

iflen(color)==1:

return(color,color,color,255)

eliflen(color)==3:

color=list(color)

color.append(255)

returntuple(color)

eliflen(color)==4:

returncolor

else:

raiseValueError,'len(color)cannotbe%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()

forwinxrange(width):

forhinxrange(height):

ifmatrix[h][w]

dst_pix[w,h]=fg_color

else:

dst_pix[w,h]=bg_color

returndst_img

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

完整代码分享如下:

#start#-*-coding:cp936-*-importImage

img=Image.open("1.jpg")

defImg2bin_arr(img,threshold):

'''@将位图流转化为二维二值数组

@paramimg:instanceofImage

@paramthreshold:大小范围[0,255]'''

threshold=max(0,threshold)

threshold=min(255,threshold)

ifimg.mode!='L':

img=img.convert('L')

width,height=img.size

pix=img.load()

get_val=lambdap:255ifp>=thresholdelse0

return[[get_val(pix[w,h])forwinxrange(width)]forhinxrange(height)]

defbin_arr2Img(matrix,bg_color,fg_color):

'''@将二维二值数组转化为位图流

@paramimg:instanceofImage

@parambg_color:背景色,元组类型,格式:(L)(灰度),(R,G,B),或者(R,G,B,A)

@paramfg_color:前景色'''

defensure_color(color):

iflen(color)==1:

return(color,color,color,255)

eliflen(color)==3:

color=list(color)

color.append(255)

returntuple(color)

eliflen(color)==4:

returncolor

else:

raiseValueError,'len(color)cannotbe%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()

forwinxrange(width):

forhinxrange(height):

ifmatrix[h][w]

dst_pix[w,h]=fg_color

else:

dst_pix[w,h]=bg_color

returndst_img

defpaper_cut(img,threshold,bg_color,fg_color):

'''@效果:剪纸

@paramimg:instanceofImage

@paramthreshold:大小范围[0,255]

@parambg_color:背景色,元组类型,格式:(L)(灰度),(R,G,B),或者(R,G,B,A)

@paramfg_color:前景色

@return:instanceofImage'''

matrix=Img2bin_arr(img,threshold)#位图转化为二维二值数组returnbin_arr2Img(matrix,bg_color,fg_color)#二维二值数组转化为位图

if__name__=="__main__":

importsys,os,time

path=os.path.dirname(__file__)+os.sep.join(['','1.jpg'])

threshold=150

bg_color=(255,255,255,0)

fg_color=(255,0,0,255)

iflen(sys.argv)>=2:

path=sys.argv[1]

iflen(sys.argv)==3:

threshold=int(sys.argv[2])

iflen(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'Itallspends%fsecondstime'%(end-start)

#end

python给图片加滤镜的方程_纯Python综合图像处理小工具(4)自定义像素级处理(剪纸滤镜)...

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。