将映像存储在内存中,然后写入磁盘

时间:2020-05-05 18:13:25

标签: python opencv

此程序段剪切视频帧中按颜色识别的对象并将其保存到磁盘。
使用完整的保存路径和objectID区分不同的对象。因为我想将不同对象的图片存储在单独的文件夹中。 到目前为止,此方法运行良好。但是,对于高分辨率图像,连续的光盘刻录会完全冻结程序。

在程序结束时,我将寻求您的帮助,以将裁剪后的图像及其名称临时存储在内存中并将其写入磁盘。

我的意思是,只要程序忙于裁剪图像,就绕过cv.imwrite(os.path.join(path + cwd + str(objectID), fileName), crop_img)

path = os.getcwd()
cwd = "/Data/"

for (objectID, centroid) in objects.items():
      # draw both the ID of the object and the centroid of the
      # object on the output frame
      text = "ID {}".format(objectID)
      cv.putText(frame, text, (centroid[0], centroid[1] - 20),
                 cv.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)
      cv.circle(frame, (centroid[0], centroid[1]), 2, (255, 0, 0), -1)

      # coordinates for cropping
      ext_left = centroid[0] - 70
      ext_right = centroid[0] + 70
      ext_top = centroid[1] - 70
      ext_bot = centroid[1] + 70

      crop_img = frame[ext_top:ext_bot, ext_left:ext_right]

      createFolder(path + cwd + str(objectID))
      fileName = '%s.jpg' % (str(objectID) + str(uuid.uuid4()))
      try:
          cv.imwrite(os.path.join(path + cwd + str(objectID), fileName), crop_img)
      except:
          pass

1 个答案:

答案 0 :(得分:2)

您可以创建一个列表,并将每个裁剪后的图像添加到列表中,就像这样:

crop_imgs = []
for (objectID, centroid) in objects.items():
   ...
   crop_img = frame[ext_top:ext_bot, ext_left:ext_right]
   crop_imgs.append((objectID, crop_img))

我们附加一个objectID和图像本身的元组。如果愿意,也可以使用dict

然后在此处分开您的写作循环:

for (objectID, crop_img) in crop_imgs:
    createFolder(path + cwd + str(objectID))
    fileName = '%s.jpg' % (str(objectID) + str(uuid.uuid4()))
    try:
        cv.imwrite(os.path.join(path + cwd + str(objectID), fileName), crop_img)
    except:
        pass

但是,请考虑您的提案的弊端:

程序的整体运行时间将保持不变,但是现在您不会将中间结果写入磁盘。如果程序崩溃,您将丢失所有内容,并且无法重新开始就无法恢复。

与视频文件不同,图像将不压缩地存储在内存中。让可用内存闲置没有任何意义,但是如果您耗尽可用内存,则操作系统必须page将内存存入磁盘,这比在每个步骤中只写出压缩JPEG的速度都要慢。

通过这种方式,即使不修改代码,也可以使用RAM disk(这是仅存在于RAM中的虚拟文件系统),然后将结果复制到硬盘上。同样的注意事项。

通过使用threadingmultiprocessing库将已处理的视频帧添加到队列中,并让另一个线程/进程对JPEG进行编码,可能会提高速度。

另一个较小的改进:使用递增数字代替UUID。生成大量随机数可能很慢。