问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

python图像处理初学者求助

发布网友 发布时间:2022-04-22 10:44

我来回答

2个回答

懂视网 时间:2022-04-06 07:56

【相关学习推荐:python教程】

文章目录

  • 前言
  • Github
  • 效果
  • 实现过程
  • 整体代码
  • 前言

    看电影的时候发现一个照片墙的功能,觉得这样生成照片挺好玩的,于是就动手用Python做了一下,觉得用来作照片纪念的效果可能会不错。

    P:后面了解到我想做的功能叫蒙太奇拼图,所以这篇博客记录先留着,闲下来会去看一下蒙太奇拼图的算法

    Github

    https://github.com/jiandi1027/photo.git

    效果

    在这里插入图片描述
    在这里插入图片描述

    实现过程

    1.获取图片文件夹的图片个数N,将底图拆分成XY块区域,且使X * Y<N
    (为了保证整体的协调,会舍弃几张图片,比如5张时可能只取2
    2的4张图片)

    	# 打开图片 
    	base = Image.open(baseImgPath)
     base = base.convert('RGBA')
     # 获取图片文件夹图片并打乱顺序
     files = glob.glob(imagesPath + '/*.*') 
     random.shuffle(files)
     # 图片数量
     num = len(files)
    	# 底图大小
     x = base.size[0]
     y = base.size[1]
     # 每张图片数量 这个公式是为了xNum * yNum 的总图片数量<num又成比例的最大整数
     yNum = int((num / (y / x)) ** 0.5)
     if yNum == 0:
     yNum = 1
     xNum = int(num / yNum)
     # 图片大小 因为像素没有小数点 为防止黑边所以+1
     xSize = int(x / xNum) + 1
     ySize = int(y / yNum) + 1

    在这里插入图片描述

    2.遍历文件夹的图片,依次填充生成最终合成图

    for file in files:
     fromImage = Image.open(file)
     i = int(num % xNum)
     j = int(num / xNum)
     out = fromImage.resize((xSize, ySize), Image.ANTIALIAS).convert('RGBA')
     toImage.paste(out, (i * xSize, j * ySize))
     toImage = toImage.convert('RGBA')
     img = Image.blend(base, toImage, 0.3)
     # 显示图片
     photo = ImageTk.PhotoImage(img)
     showLabel.config(image=photo)
     showLabel.image = photo
     if num < xNum * yNum:
      num = num + 1

    3.生成结束后保存图片
    toImage.save(‘generator.png’)
    img.save(“final.png”)
    在这里插入图片描述
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190805150649966.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NoaWppYW5kaQ==,size_16,color_FFFFFF,t_70
    4.建立可视化界面
    在这里插入图片描述
    5.Pyinstaller生成exe可执行文件
    安装pyinstaller模块,执行命令生成exe文件

    pyinstaller -F -w test.py (-w就是取消窗口)

    整体代码

    Python的语法和设计规范还没学过,所以代码规范代码复用之类的可能会有点不到位,本博文主要是一个思路与整体流程的记录。
    后续又优化了一下一些特效,比如合成图片采用随机位置,增加黑白,流年等显示特效,透明度自选等。

    import PIL.Image as Image
    import glob
    import random
    import tkinter.filedialog
    from tkinter.filedialog import askdirectory, Label, Button, Radiobutton, Entry
    import threading
    
    import numpy as np
    from PIL import ImageTk
    
    alpha = 0.3
    imagesPath = ''
    
    
    # 滑动条回调 修改透明度
    def resize(ev=None):
     global alpha
     alpha = scale.get() / 100
    
    
    # 黑白
    def blackWithe(image):
     # r,g,b = r*0.299+g*0.587+b*0.114
     im = np.asarray(image.convert('RGB'))
     trans = np.array([[0.299, 0.587, 0.114], [0.299, 0.587, 0.114], [0.299, 0.587, 0.114]]).transpose()
     im = np.dot(im, trans)
     return Image.fromarray(np.array(im).astype('uint8'))
    
    
    # 流年
    def fleeting(image, params=12):
     im = np.asarray(image.convert('RGB'))
     im1 = np.sqrt(im * [1.0, 0.0, 0.0]) * params
     im2 = im * [0.0, 1.0, 1.0]
     im = im1 + im2
     return Image.fromarray(np.array(im).astype('uint8'))
    
    
    # 旧电影
    def oldFilm(image):
     im = np.asarray(image.convert('RGB'))
     # r=r*0.393+g*0.769+b*0.189 g=r*0.349+g*0.686+b*0.168 b=r*0.272+g*0.534b*0.131
     trans = np.array([[0.393, 0.769, 0.189], [0.349, 0.686, 0.168], [0.272, 0.534, 0.131]]).transpose()
     # clip 超过255的颜色置为255
     im = np.dot(im, trans).clip(max=255)
     return Image.fromarray(np.array(im).astype('uint8'))
    
    
    # 反色
    def reverse(image):
     im = 255 - np.asarray(image.convert('RGB'))
     return Image.fromarray(np.array(im).astype('uint8'))
    
    
    def chooseBaseImagePath():
     name = tkinter.filedialog.askopenfilename()
     if name != '':
     global baseImgPath
     baseImgPath = name
     baseImageLabel.config(text=name)
     baseImg = Image.open(baseImgPath)
     widthEntry.delete(0, tkinter.END)
     heightEntry.delete(0, tkinter.END)
     widthEntry.insert(0, baseImg.size[0])
     heightEntry.insert(0, baseImg.size[1])
     else:
     baseImageLabel.config(text="您没有选择任何文件")
    
    
    def chooseImagesPath():
     name = askdirectory()
     if name != '':
     global imagesPath
     imagesPath = name
     ImagesLabel.config(text=name)
     else:
     ImagesLabel.config(text="您没有选择任何文件")
    
    
    def thread_it(func, *args):
     # 创建
     t = threading.Thread(target=func, args=args)
     # 守护 !!!
     t.setDaemon(True)
     # 启动
     t.start()
    
    
    def test():
     MyThread(1, "Thread-1", 1).start()
    
    
    baseImgPath = ''
    
    
    def generator():
     baseImg = Image.open(baseImgPath)
     baseImg = baseImg.convert('RGBA')
     files = glob.glob(imagesPath + '/*.*') # 获取图片
     random.shuffle(files)
     num = len(files)
     # 模板图片大小
     x = baseImg.size[0]
     y = baseImg.size[1]
     # 每张图片数量 这个公式是为了xNum * yNum 的总图片数量<num又成比例的最大整数
     yNum = int((num / (y / x)) ** 0.5)
     if yNum == 0:
     yNum = 1
     xNum = int(num / yNum)
     # 图片大小 因为像素没有小数点 为防止黑边所以+1
     xSize = int(x / xNum) + 1
     ySize = int(y / yNum) + 1
     # 生成数量的随机列表 用于随机位置合成图片
     l = [n for n in range(0, xNum * yNum)]
     random.shuffle(l)
     toImage = Image.new('RGB', (x, y))
     num = 1
     for file in files:
     if num <= xNum * yNum:
      num = num + 1
     else:
      break
     fromImage = Image.open(file)
    
     temp = l.pop()
     i = int(temp % xNum)
     j = int(temp / xNum)
     out = fromImage.resize((xSize, ySize), Image.ANTIALIAS).convert('RGBA')
     toImage.paste(out, (i * xSize, j * ySize))
     toImage = toImage.convert('RGBA')
     img = Image.blend(baseImg, toImage, alpha)
     # 特效 但是会读取像素会降低效率
     choose = v.get()
     if choose == 1:
      img = blackWithe(img)
     elif choose == 2:
      img = fleeting(img)
     elif choose == 3:
      img = oldFilm(img)
     elif choose == 4:
      img = reverse(img)
    
     resize = img.resize((300, 300), Image.ANTIALIAS).convert('RGBA')
     # 显示图片
     photo = ImageTk.PhotoImage(resize)
     showLabel.config(image=photo)
     showLabel.image = photo
     toImage.save('generator.png')
     img = img.resize((int(widthEntry.get()),int(heightEntry.get())), Image.ANTIALIAS).convert('RGBA')
     img.save("final.png")
     resize.save("resize.png")
    
    
    class MyThread(threading.Thread): # 继承父类threading.Thread
     def __init__(self, threadID, name, counter):
     threading.Thread.__init__(self)
     self.threadID = threadID
     self.name = name
     self.counter = counter
    
     def run(self): # 把要执行的代码写到run函数里面 线程在创建后会直接运行run函数
     generator()
    
    
    root = tkinter.Tk()
    root.title('generator')
    root.geometry('500x550')
    baseImageLabel = Label(root, text='')
    baseImageLabel.place(x=10, y=10)
    baseImageBtn = Button(root, text="选择底图", command=chooseBaseImagePath).place(x=10, y=30)
    ImagesLabel = Label(root, text='')
    ImagesLabel.place(x=10, y=60)
    ImagesBtn = Button(root, text="选择合成图文件夹", command=chooseImagesPath).place(x=10, y=80)
    
    v = tkinter.IntVar()
    v.set(0)
    Radiobutton(root, variable=v, text='默认', value=0, ).place(x=10, y=120)
    Radiobutton(root, variable=v, text='黑白', value=1, ).place(x=110, y=120)
    Radiobutton(root, variable=v, text='流年', value=2, ).place(x=210, y=120)
    Radiobutton(root, variable=v, text='旧电影', value=3, ).place(x=310, y=120)
    Radiobutton(root, variable=v, text='反色', value=4, ).place(x=410, y=120)
    
    scaleLabel = Label(root, text='透明度').place(x=10, y=170)
    scale = tkinter.Scale(root, from_=0, to=100, orient=tkinter.HORIZONTAL, command=resize)
    scale.set(30) # 设置初始值
    scale.pack(fill=tkinter.X, expand=1)
    scale.place(x=70, y=150)
    Label(root, text='宽(像素)').place(x=180, y=170)
    widthEntry = Entry(root, bd=1)
    widthEntry.place(x=230, y=173, width=100)
    Label(root, text='高(像素)').place(x=320, y=170)
    heightEntry = Entry(root, bd=1)
    heightEntry.place(x=370, y=173, width=100)
    
    generatorBtn = Button(root, text="生成", command=test).place(x=10, y=220)
    showLabel = Label(root)
    showLabel.place(x=100, y=220)
    root.mainloop()

    想了解更多编程学习,敬请关注php培训栏目!

    热心网友 时间:2022-04-06 05:04

    Pillow是Python里的图像处理库(PIL:Python Image Library),提供了了广泛的文件格式支持,强大的图像处理能力,主要包括图像储存、图像显示、格式转换以及基本的图像处理操作等。
    1)使用 Image 类
    PIL最重要的类是 Image class, 你可以通过多种方法创建这个类的实例;你可以从文件加载图像,或者处理其他图像, 或者从 scratch 创建。
    要从文件加载图像,可以使用open( )函数,在Image模块中:

    1
    2

    >>> from PIL import Image
    >>> im = Image.open("E:/photoshop/1.jpg")

    加载成功后,将返回一个Image对象,可以通过使用示例属性查看文件内容:

    1
    2
    3

    >>> print(im.format, im.size, im.mode)
    ('JPEG', (600, 351), 'RGB')
    >>>

    format 这个属性标识了图像来源。如果图像不是从文件读取它的值就是None。size属性是一个二元tuple,包含width和height(宽度和高度,单位都是px)。 mode 属性定义了图像bands的数量和名称,以及像素类型和深度。常见的modes 有 “L” (luminance) 表示灰度图像, “RGB” 表示真彩色图像, and “CMYK” 表示出版图像。
    如果文件打开错误,返回 IOError 错误。
    只要你有了 Image 类的实例,你就可以通过类的方法处理图像。比如,下列方法可以显示图像:

    1

    im.show()

    2)读写图像
    PIL 模块支持大量图片格式。使用在 Image 模块的 open() 函数从磁盘读取文件。你不需要知道文件格式就能打开它,这个库能够根据文件内容自动确定文件格式。要保存文件,使用 Image 类的 save() 方法。保存文件的时候文件名变得重要了。除非你指定格式,否则这个库将会以文件名的扩展名作为格式保存。
    加载文件,并转化为png格式:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    "Python Image Library Test"
    from PIL import Image
    import os
    import sys

    for infile in sys.argv[1:]:
    f,e = os.path.splitext(infile)
    outfile = f +".png"
    if infile != outfile:
    try:
    Image.open(infile).save(outfile)
    except IOError:
    print("Cannot convert", infile)

    save() 方法的第二个参数可以指定文件格式。
    3)创建缩略图
    缩略图是网络开发或图像软件预览常用的一种基本技术,使用Python的Pillow图像库可以很方便的建立缩略图,如下:

    1
    2
    3
    4
    5
    6
    7

    # create thumbnail
    size = (128,128)
    for infile in glob.glob("E:/photoshop/*.jpg"):
    f, ext = os.path.splitext(infile)
    img = Image.open(infile)
    img.thumbnail(size,Image.ANTIALIAS)
    img.save(f+".thumbnail","JPEG")

    上段代码对photoshop下的jpg图像文件全部创建缩略图,并保存,glob模块是一种智能化的文件名匹配技术,在批图像处理中经常会用到。
    注意:Pillow库不会直接解码或者加载图像栅格数据。当你打开一个文件,只会读取文件头信息用来确定格式,颜色模式,大小等等,文件的剩余部分不会主动处理。这意味着打开一个图像文件的操作十分快速,跟图片大小和压缩方式无关。
    4)图像的剪切、粘贴与合并操作
    Image 类包含的方法允许你操作图像部分选区,PIL.Image.Image.crop 方法获取图像的一个子矩形选区,如:

    1
    2
    3
    4

    # crop, paste and merge
    im = Image.open("E:/photoshop/lena.jpg")
    box = (100,100,300,300)
    region = im.crop(box)

    矩形选区有一个4元元组定义,分别表示左、上、右、下的坐标。这个库以左上角为坐标原点,单位是px,所以上诉代码复制了一个 200×200 pixels 的矩形选区。这个选区现在可以被处理并且粘贴到原图。

    1
    2

    region = region.transpose(Image.ROTATE_180)
    im.paste(region, box)

    当你粘贴矩形选区的时候必须保证尺寸一致。此外,矩形选区不能在图像外。然而你不必保证矩形选区和原图的颜色模式一致,因为矩形选区会被自动转换颜色。
    5)分离和合并颜色通道
    对于多通道图像,有时候在处理时希望能够分别对每个通道处理,处理完成后重新合成多通道,在Pillow中,很简单,如下:

    1
    2

    r,g,b = im.split()
    im = Image.merge("RGB", (r,g,b))

    对于split( )函数,如果是单通道的,则返回其本身,否则,返回各个通道。
    6)几何变换
    对图像进行几何变换是一种基本处理,在Pillow中包括resize( )和rotate( ),如用法如下:

    1
    2

    out = im.resize((128,128))
    out = im.rotate(45) # degree conter-clockwise

    其中,resize( )函数的参数是一个新图像大小的元祖,而rotate( )则需要输入顺时针的旋转角度。在Pillow中,对于一些常见的旋转作了专门的定义:

    1
    2
    3
    4
    5

    out = im.transpose(Image.FLIP_LEFT_RIGHT)
    out = im.transpose(Image.FLIP_TOP_BOTTOM)
    out = im.transpose(Image.ROTATE_90)
    out = im.transpose(Image.ROTATE_180)
    out = im.transpose(Image.ROTATE_270)

    7)颜色空间变换
    在处理图像时,根据需要进行颜色空间的转换,如将彩色转换为灰度:

    1
    2

    cmyk = im.convert("CMYK")
    gray = im.convert("L")

    8)图像滤波
    声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
    《舞蹈鉴赏》的答案 生活形态的舞蹈的称谓来源于什么 抖音商单任务是什么?抖音任务怎么取消? 抖音全民任务怎么取消?真的能赚钱吗? 巨量星图达人如何孵化?开通后有什么利弊? 彩礼对女生有多重要 50元5g全国流量模组包是什么 u盘文件夹删除怎么恢复 如何恢复u盘文件夹 u盘里的文件夹不小心删除了怎么恢复,5种方法教你轻松找回数据 python图片压缩到固定大小-python中如何压缩文件,并指定文件的压缩之后的大小。 请问可以用python实现将大图片变成小图片处理吗,这边要做一个图像识别,太大的分辨率运行慢 python中PLE调整图片大小,等比例压缩文件,怎么写代码 求教,用50寸的4K液晶电视机当显示器有什么不好 50寸等离子电视当显示器用 小叔子结婚,我同意用我家房子当婚房,一年后我受不了了怎么办? 用电视做电脑显示屏怎调整画面的清晰度 液晶电视能代替电脑显示屏吗,有什么利弊?效果如何? 用电视接笔记本当显示屏会增加显卡的负担吗 用东芝智能电视(50寸)当电脑显示屏,显示的字体大小可以调节。但是 50英寸的电视机能不能当做电脑显示器? 现在的电视能当显示器不,我在电脑城看人接的笔记本,在大约50寸的显示器上玩游戏,画面还很清晰。笔记 液晶电视当做电脑显示器 ‘有没有’用英语怎么说 总是想买东西怎么办? 长虹液晶电视能当电脑显示器用吗 请教,买台50寸4K电视当电脑显示器用,可以吗 用五十英寸左右电视做电脑显示器好不好 404 Not Found Python 读取文件夹将里面的图片处理成想要的大小并保存在个指定位置 python如何生成图片缩 内容运营应该怎么做效果更好, 马克华菲手表钢带怎么调星期 卡西欧钢带手表怎么调时间 lars larsen手表怎样调表带 请问钢带手表 表带调到多长算最合适? 微信红包封面在哪找? 对方给我发微信红包我点不开领不了是不是他的号被官方控制了 微信红包封面尺寸是多少 人寿保险合同的宽限期 合同在宽限期内的效力状态是怎样的? 人寿保险多久生效? 如何做好app产品需求分析 uc浏览器如何把当前浏览的网页截成一张长图 手机怎样截屏整个页面 uc浏览器怎么截长图(就是把网页中的部分保存为图片) 安卓手机版uc浏览器如何把网页整个截图呢 uc安卓版找不到截屏或者保存整个网页的功能 怎样使用手机uc浏览器保存页面