【问题标题】:Extract metadata from a Video/Image从视频/图像中提取元数据
【发布时间】:2014-03-14 05:19:38
【问题描述】:

我正在从我的计算机上查看和保存的 IP 摄像机获取 MJPEG 流。我如何做的代码可以在here 找到。答案解释了如何从流中提取图像并保存它们。

为了提取图像,我使用答案中列出的方法并保存它,我只是使用 OpenCV 将图像放入 avi 容器中。代码如下。

writer=cv.CreateVideoWriter("video1.avi", cv.CV_FOURCC('X', '2', '6', '4'), fps, (320,240))
cv_image = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8),cv2.CV_LOAD_IMAGE_COLOR)bitmap=cv.CreateImageHeader((cv_image.shape[1], cv_image.shape[0]), cv.IPL_DEPTH_8U, 3)
cv.SetData(bitmap, cv_image.tostring(), cv_image.dtype.itemsize * 3 * cv_image.shape[1])
cv.WriteFrame(writer, bitmap)

这里的位图是我正在显示并放入 avi 容器中的图像。

由于图像来自 IP 摄像机,它必须有一些元数据,例如摄像机插入的时间戳。

问题:如何提取元数据?

我想到了两种方法:

  1. 从视频中提取帧,然后访问它们以访问时间戳。
  2. 从视频本身中提取时间戳。

我该如何进行?我使用哪种方法?我正在使用 Python 和 Opencv,并且正在使用 Windows 7。

我还阅读了 this 之类的与我正在尝试做的事情相关的内容。它没有解决我的问题。

【问题讨论】:

    标签: python opencv video metadata ip-camera


    【解决方案1】:

    如果有任何元数据附加到(单个图像)文件,opencv 将丢弃它,不幸的是。

    另外,mjpeg 协议本身没有任何时间戳(它只是一个与图像交错的 http-multi-part-form [与电子邮件附件非常相似],所以内容类型和内容长度就是你的全部到达那里[并且只有在您使用 http1.1 时才这样做])。

    很抱歉给出否定的答案,但您必须研究除 opencv 之外的图像处理工具。

    【讨论】:

    • 我对它们的功能并不完全熟悉,但我不能使用 urllib 和 httplib 之类的库来访问传入的数据包,然后在提取图像时使用我在该图像中拥有的元数据?
    • httplib 和 urllib 都不关心 'image-metadata'
    • 我不知道他们能不能做到。他们可以执行的功能。他们中的任何一个都可以检查正在接收的数据包的内容吗?
    • 简单的回答:没有。同样,您需要一个不同的 image-processing 库来处理它
    • 啊,好吧。你对其他库有什么想法吗?
    【解决方案2】:

    我很幸运能通过ffmpeg 访问视频元数据。

    例如,

    ffmpeg -i video_file.mp4
    

    打印出这样的信息:

      Metadata:
        major_brand     : mp42
        minor_version   : 0
        compatible_brands: isommp42
        creation_time   : 2019-02-25T00:00:07.000000Z
        location        : +XX.XXXX+XXX.XXXX/
        location-eng    : +XX.XXXX+XXX.XXXX/
      Duration: 00:16:28.86, start: 0.000000, bitrate: 7331 kb/s
        Stream #0:0(eng): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 1920x1080, 7236 kb/s, SAR 1:1 DAR 16:9, 10.91 fps, 30 tbr, 90k tbn, 180k tbc (default)
        Metadata:
          creation_time   : 2019-02-25T00:00:07.000000Z
          handler_name    : VideoHandle
        Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, mono, fltp, 96 kb/s (default)
        Metadata:
          creation_time   : 2019-02-25T00:00:07.000000Z
          handler_name    : SoundHandle
    

    有ffmpeg 的python 包装器,例如ffmpeg-python。我个人只是用一个shell脚本提取了我需要的信息(creation_time),当然可以通过subprocess模块调用。

    【讨论】:

      【解决方案3】:

      对于 Java,您可以使用 Metadata Extractor。此外,您可以使用 ImageMagick 和 Exiflib,它们都是优秀的(优秀的定义为高度稳定、健壮和积极开发的)库,但这些都是命令行工具。对于 imagemagick,您可以找到其他语言绑定。

      【讨论】:

      • 仅供参考:我从来没有找到一个好的库(非 bash)来编写元数据。在 MetadataExtractor 上添加对写入的支持存在问题,但添加此功能的工作量太大。
      【解决方案4】:

      我还需要从视频中获取元数据,而 OpenCV 无法做到。

      我发现 this 和 this 似乎可以获取元数据。

      不过我还没有测试过。

      【讨论】:

      • 如果您尝试对其进行测试,我们将获得更多信息。现在链接部分已过时
      【解决方案5】:

      如 Martin Drohmann 所说,对于视频元数据,请使用 ffmpeg。

      对于图像元数据(称为“EXIF”):

      OpenCV 将丢弃图像元数据;例如,cv2.imread('bear.jpg') 将生成像素强度的 3 维 numpy 数组(第三维是 R、G、B 通道)。

      所以要提取 EXIF 数据,可以使用 Python 的替代图像处理库,它非常流行,称为 pillow。

      首先,在命令行,安装pillow:pip install pillow。

      然后就可以从bear.jpg提取EXIF数据了:

      import PIL.Image
      from PIL.ExifTags import TAGS
      from pprint import pprint
      
      image = PIL.Image.open('bear.jpg')
      
      # Get the exif data and map to the correct tags
      exif_data = {
                      PIL.ExifTags.TAGS[k]: v
                      for k,v in image._getexif().items()
                      if k in PIL.ExifTags.TAGS
                  }
      
      pprint(exif_data)
      

      这将显示 EXIF 数据:

      {'ExposureBiasValue': (0, 3),
       'ExposureTime': (1, 40),
       'FNumber': (280, 100),
       'ISOSpeedRatings': 100,
       ...
      }
      

      有关 EXIF 的完整信息,请参阅https://exiv2.org/tags.html。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-01-30
        • 2015-11-22
        • 2012-05-16
        • 1970-01-01
        • 2013-01-09
        • 2013-05-14
        相关资源
        最近更新 更多