网站创建二级域名深圳十大广告公司
网站创建二级域名,深圳十大广告公司,网站模板免费下载网页模板,怎样做影视网站不侵权图形学实验: 生成中间帧
给定初始图片和结束图片#xff0c;生成中间的N帧#xff0c;使得首尾自然过渡
开发环境
开发环境#xff1a;macOS Mojave 10.14.6开发软件#xff1a;PyCharm 2019.1.3开发语言#xff1a;python
如何运行
将项目文件夹拷贝到本地环境运行s…图形学实验: 生成中间帧给定初始图片和结束图片生成中间的N帧使得首尾自然过渡开发环境开发环境macOS Mojave 10.14.6开发软件PyCharm 2019.1.3开发语言python如何运行将项目文件夹拷贝到本地环境运行src/GenerateIntermediateFrames.py在Resources/Result/目录下可查看到生成的中间帧图片framexx.png: 为中间帧图片其中xx为该帧编号result.gif: 为该文件夹中所有帧图片生成的gif图片(方便观察处理结果)可使用自定义图片替换Resources/Origin/目录下的原始图片并且请修改src/GenerateIntermediateFrames.py-main()函数中path_cat和path_tiger的路径实验结果测试用例一原图生成的中间帧(转化为gif)测试用例二考虑到机器性能和生成动图大小图片有压缩原图生成的中间帧(转化为gif)具体实现读取图片使用cv2.imread()将图片读取成矩阵读取原始图片 def readOriginImg(path_cat, path_tiger): I_cat cv2.imread(path_cat) I_tiger cv2.imread(path_tiger) return I_cat, I_tiger# 读取的图片数据结构 [[[255 255 255] [255 255 255] [255 255 255] ... ... [ 84 103 112] [103 122 128] [167 178 181]]]生成中间帧(线性插值算法)取两图片最大的长宽作为目标图片的长宽# 取两图片最大的长宽作为目标图片的长宽 width, height max(I_cat.shape[0], I_tiger.shape[0]), max(I_cat.shape[1], I_tiger.shape[1])直接使用三维数组构建 (N2)widthheight 三纬结果矩阵result_frames [[[0 for _ in range(width)] for _ in range(height)] for _ in range(N2)]使用三重循环进行中间帧生成for k in range(0, N2): # 帧循环 t k/(1N) # 对二维图片矩阵遍历 for x in range(width): for y in range(height): result_frames[k][x][y] (1-t)*I_cat[x][y] t*I_tiger[x][y] # 线性插值公式使用numpy数组将矩阵写出成图片将矩阵写出成图片 def writeResultFrames(result_frames, dirname, multi_threadFalse): for index, frame in enumerate(result_frames): filename frame str(index) .png直接写出else: cv2.imwrite(dirname filename, np.float32(frame))使用多线程处理复杂任务将矩阵保存成图片 - 线程类 class FrameHandler(Thread): def __init__(self, dirname, filename, frame): super().__init__() self._dirname dirname self._filename filename self._frame frame def run(self): imwrite(self._dirnameself._filename, np.float32(self._frame))if multi_thread: frame_thread FrameHandler(dirname, filename, frame) frame_thread.start() frame_thread.join()将一组帧图片保存为Gif对结果目录中的所有文件进行过滤(只读入生成的中间帧)对读入的中间帧按照先后进行排序调用image.mimsave()方法将一组帧图片保存为Gif Resources/Result/目录下有多张图片 图片格式: framexx.png import os import imageio def myImage2Gif(dirname): frames list(filter(lambda x: x[0:5] frame and x[-4:] .png, os.listdir(dirname))) # 将不符合命名要求的图片过滤掉(MacOS)会默认创建一些文件 frames.sort(keylambda x: int(x[5:-4])) # 按照图片编号进行排序 imgs [] for frame in frames: img Image.open(dirname frame) imgs.append(img) imgs[0].save(dirname result.gif, save_allTrue, append_imagesimgs, duration300)实验分析使用普通三维数组和numpy数组的效率差异start time() # 生成指定数量的中间帧 result_frames generateFrame(I_cat, I_tiger, N) end time() print(end-start)该测试使用的是测试用例一生成的中间帧数量N 100仅测试generateFrame()函数的时间用于反映两种算法对于处理图片矩阵生成中间帧的效率差异使用普通三维数组结果数据结构的定义result_frames [[[0 for _ in range(width)] for _ in range(height)] for _ in range(N 2)]线性插值公式的使用result_frames[k][x][y] (1 - t) * I_cat[x][y] t * I_tiger[x][y]耗时16.906198024749756 s使用numpy数组结果数据结构的定义result_frames np.zeros((N 2, width, height, 3)) # 对于图片矩阵中的每一个像素进行数值运算线性插值公式的使用result_frames[k] (1 - t) * I_cat t * I_tiger # 直接对于图片矩阵进行矩阵运算耗时0.0948951244354248 s从耗时中可以明显的看到使用numpy数组对于性能的提升提升倍数达到了惊人的178倍这提示我将来凡事观察到数值元算可以转换为直接对矩阵进行运算时要果断采用numpy库相关函数进行科学计算效率会得到很大的提升使用多线程与直接写出的效率差异start time() # 将结果矩阵写出成图片 writeResultFrames(result_frames, path_result, multi_threadTrue) end time() print(end - start)该测试使用的是测试用例一生成的中间帧数量N 1000仅测试writeResultFrames()函数的时间通过传入参数multi_thread不同的值用于反映两种算法对于将矩阵写出成图片的效率差异直接写出耗时2.9145750999450684 s使用多线程耗时3.5594019889831543 s按道理采用多线程应该会提高效率但是将数据量从100上升到1000仍是直接写出效率更高猜想可能是使用的原始图片像素太小且生成的中间帧数量还是不够巨大无法发挥出多线程的效率反而多线程的算法中要花很多时间在函数调用和类的创建上此外还可能跟我把线程封装成类并且独立写在一个.py文件中让主文件调用有关。在系统调用中浪费太多时间反而在真正能发挥多线程性能时数据量又不是很大导致效果并不好。遇到的问题 解决方案python构建三维数组初始时结果数组的定义如下result_frames [[0 for _ in range(width)] for _ in range(height)] * (N2)测试该数组的结构如下觉得没有任何不妥[[[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]]]但是下一步进行中间帧生成后写出的结果矩阵却怎么也不对生成的图片非常奇怪仔细找了很久也没发现有任何不妥于是读了很多篇关于python多维数组的文章最终通过如下的测试终于找到了问题所在测试代码如下遍历三位数组的每一个元素从小到大递增的赋值理论上最终数组中应该是从023的数字index 0 for k in range(0,N2): for x in range(height): for y in range(width): print(k,x,y) result_frames[k][x][y] index index 1 print(result_frames)测试结果如下[[[18, 19], [20, 21], [22, 23]], [[18, 19], [20, 21], [22, 23]], [[18, 19], [20, 21], [22, 23]], [[18, 19], [20, 21], [22, 23]]]从测试中可以看到数组的第二三纬度的值每次都会同时修改导致[[18, 19], [20, 21], [22, 23]]这组值反复出现终于找到问题的所在找到准确问题后在网上进一步了解发现时python深拷贝浅拷贝的问题在创建数组中的*(N2)造成了对上一层两维数组的浅拷贝修改方法result_frames [[[0 for _ in range(width)] for _ in range(height)] for _ in range(N 2)] # 或直接使用numpy数组 result_frames np.zeros((N 2, width, height, 3))原始图片尺寸不匹配在最开始的程序中如果开始的两张图片尺寸不同则会报错ValueError: operands could not be broadcast together with shapes (826,661,3) (640,640,3)是由于python中广播机制的存在导致无法对尺寸不匹配的矩阵进行运算所以必须在程序中对矩阵进行尺寸的重定义是的不同尺寸的矩阵可以进行运算修改方法取两图片最大的长宽作为目标图片的长宽width, height max(I_cat.shape[0], I_tiger.shape[0]), max(I_cat.shape[1], I_tiger.shape[1])分别将两张图片进行尺寸的重新调整I_cat np.resize(I_cat, (width, height, 3)) I_tiger np.resize(I_tiger, (width, height, 3))将一组帧图片保存为Gif生成的N2张图片十分不便于观察自然过渡的效果因此打算使用python将所有图片转换成一个gif查阅了python库函数发现大致有三种方法可以实现一组图片转gifimageio.mimsave()images2gif库中的writeGif()PIL.Image库中的save()分别使用三种方法试验之后发现第一种方法效率有点低下在合并10几张图片时无任何问题但合并很多张图片容易卡死造成无法生成gif图片第二种方法该库是python2中的库不再支持python3将/Library/Frameworks/Python.framework/Versions/3.7/lib/images2gif中的for im in images: palettes.append( getheader(im)[1] )替换成for im in images: palettes.append( im.palette.getdata()[1])仍然会出现问题第三种方法有时候会只在首位两张图片之间闪烁最终使用第三种方法将duration设置为300效果较好同时由于我的架构是生成所有中间帧图片再转换为gif所以要读取整个结果文件夹中的文件如果直接读取顺序错乱这样制作的动图无法观察到变化[frame52.png, frame46.png, frame91.png, frame85.png, frame84.png, frame90.png, frame47.png, frame53.png, frame79.png, ..., frame77.png]对文件列表进行排序但是有一些macOS系统自带的文件并且排序是按照字符串的字典序排序这样也同样是无法使用的[.DS_Store, frame0.png, frame1.png, frame10.png, frame100.png,... ]首先对数据进行清洗将无关的文件过滤掉frames list(filter(lambda x: x[0:5] frame and x[-4:] .png, os.listdir(dirname)))按照图片标号进行排序自己创建排序函数的keyframes.sort(keylambda x: int(x[5:-4]))项目结构. ├── README.md ├── Resources │ ├── Origin │ │ ├── cat.png │ │ ├── her1.jpeg │ │ ├── her2.jpeg │ │ └── tiger.png │ └── Result │ ├── catResult.gif │ └── herResult.gif ├── doc │ └── 生成中间帧实验文档.pdf └── src ├── FrameHandler.py ├── GenerateIntermediateFrames.py └── myImage2Gif.py♻️ 资源大小13.6MB➡️资源下载https://download.csdn.net/download/s1t16/87404308注更多内容可关注微信公众号【神仙别闹】如当前文章或代码侵犯了您的权益请私信作者删除