前言
在本文中,我们将学习长时间曝光摄影技术,以及如何使用Python和OpenCV(开源计算机视
觉库)对其进行仿真。
需要完整的代码的滴滴我哈往期文章都有哦~
正文
1)小科普——什么是“长时间曝光“?
长时间曝光,时间曝光或慢速快门摄影涉及使用长时间快门速度来清晰地捕获图像的静止元
素,同时使运动元素模糊。长时间曝光摄影可以捕捉到传统摄影无法捕捉到的一个元素:较长
的时间。
因此,长时间曝光是一种出色的摄影技术,包括创建可显示时间效果的图像,这是普通摄影无
法捕获的。对于初学者来说,这种技术并不容易,因为它需要一种有条理的方法来捕获图像。
幸运的是,我们可以用图像处理来模拟这种技术。为此,我们可以使用一个视频(基本上是一
系列图像)来计算基于所有视频帧的平均图像。
2)依赖库
在本教程中,我们将使用Python 3和OpenCV。我们将使用OpenCV,因为它是一个著名的开
源计算机视觉库,其中提供了许多处理图像和视频的功能。在本教程中,我们将使用OpenCV
来操纵视频及其帧。下图优雅地说明了为什么要使用Python:
此外,我们将使用其他两个Python软件包:
-
单击:提供命令行界面(CLI)。
-
tqdm:在终端上显示一个优雅的进度栏。
我们还将使用Pipenv轻松创建和管理虚拟环境。
3)环境
使用项目根目录中提供的Pipfile,我们可以使用Pipenv通过以下命令创建,安装依赖项并激活
虚拟环境:
pip install pipenv # if not installed yetpipenv install --devpipenv shell
4)主程序代码
让我们开始看“入口点”。这是一个CLI命令,我们应该在其中传递一些参数:
-
video_path:本地计算机中视频的路径。
-
image_path:输出图像的路径和文件名。
-
step / -s(可选):用于获取帧的步骤。这是一个可选参数,默认值为1。
@cli.command() @click.argument("video_path", nargs=1, type=str) @click.argument("image_path", nargs=1, type=str) @click.option( "--step", "-s", default=1, type=int, show_default=True, help="Step used to get the frames.", ) def local_video(video_path, image_path, step): """Apply the long exposure algorithm to a local video.""" long_exposure = LongExposure(video_path, image_path, step) long_exposure()
它使用单击修饰符来提供漂亮的命令行界面。如果你们仍然不知道单击,我们建议你们看一下
该程序包。这使我们可以像这样调用Python脚本:
python src/long_exposure.py local-video video.mp4 image.png -s 5
如果你们对如何使用有疑问,可以通过help标志来调用它:
python src/long_exposure.py --help
现在,让我们谈谈LongExposure类。这是项目的主类,它在其__init__中接收以下参数:
-
video:本地计算机中的视频路径。
-
output_image_path:必须在其中保存输出图像的路径/文件名。
-
step:用于忽略某些帧的步骤(默认为1)。这对于长视频非常有用。
class LongExposure: def init(self, video, output_image_path, step=1): self.video = video self.output_image_path = output_image_path self.step = step
平均器的方法仅仅是一个Clojure的是用来递增地计算平均图像,因为我们正在消耗视频帧逐个。
@staticmethod
def averager():
"""Calculate the average using a clojure."""
count = 0
total = 0.0
def average(value):
nonlocal count, total
count += 1
total += value
return total / count
return average
由于这是一个可调用的类,因此__call__方法是该类的主要方法,它主要负责:
-
加载视频;
-
通过视频帧进行迭代以计算平均图像(针对每个颜色通道);
-
合并颜色通道;以及
-
将映像保存在磁盘上。
def call(self): logging.info("Processing video %r with step %r", self.video, self.step)
# Open a pointer to the video file stream = cv2.VideoCapture(self.video) # Get the total frames to be used by the progress bar total_frames = int(stream.get(cv2.CAP_PROP_FRAME_COUNT)) r, g, b = None, None, None r_avg, g_avg, b_avg = self.averager(), self.averager(), self.averager() for count in tqdm(range(total_frames)): # Split the frame into its respective channels _, frame = stream.read() if count % self.step == 0: # Get the current RGB b_curr, g_curr, r_curr = cv2.split(frame.astype("float")) r, g, b = r_avg(r_curr), g_avg(g_curr), b_avg(b_curr) # Merge the RGB averages together and write the output image to disk avg = cv2.merge([b, g, r]).astype("uint8") logging.info("Saving image as %r", self.output_image_path) cv2.imwrite(self.output_image_path, avg) # Release the stream pointer stream.release()
请注意,cv2来自OpenCV,而tqdm(在循环中)仅用于显示进度条。如你们所见,这里没有
魔术,代码非常简单,几乎可以自己解释。现在,让我们看看结果。
我已使用以下YouTube视频应用长时间曝光效果:
总结
好啦,今天的文章内容到这里就正是结束了哈,想了解更多OpenCV的小知识,记得关注小编
啦,每日更新期待你的三连~
需要完整的代码的滴滴我哈往期文章都有哦~
🔨推荐往期文章——
项目1.0 玫瑰花(内含多份源码)
【Turtle玫瑰汇总】温柔且浪漫至极——“玫瑰的花期到了“
项目1.1 雪花(内含多份源码)
Turtle系列:下雪了,下雪了、最漂亮的雪景在这里....太美了
项目 2.1 樱花将灿,冬尽风暖
漫天樱花表白小程序:“樱花将灿,冬尽风暖“一樱花和你我都想念~(内含多份源码)
项目 2.2 源码合集(表白)
Turtle系列:小人发射爱心、文字表白、一箭穿心你想要的都在这个小程序哦~(超值)
项目2.3 魔法阵合集
【Turtle合集】火遍抖音的五款魔法阵终于被我找到了(初代萌王,童年的小樱回来了)
🎄文章汇总——
汇总合集 Python—2022 |已有文章汇总 | 持续更新,直接看这篇就够了
(更多内容+源码都在✨文章汇总哦!!欢迎阅读喜欢的文章🎉~)