是否可以对图像应用h.264压缩?

问题描述 投票:0回答:2

目前,我正在对单个图像应用 h.264 压缩。
如下图所示,我想基于 h.264 压缩该图像,并进行 40 个恒定量化。

enter image description here 但是,任何地方都没有相关功能,例如基于 Python 的库(opencv、ffmpeg)。

此外,还没有适用于单图像和结构良好的h.264算法的github。

那么,有没有 github 实现或库可以做到这一点?

提前致谢。

image image-processing deep-learning h.264 data-augmentation
2个回答
3
投票

在某些情况下(例如学术目的)对单帧视频进行编码确实有意义。

有一种名为 HEIF 的现有图像格式基于 HEVC (H.265) 编解码器,但对于 H.264,您必须对视频文件进行编码。

您可以使用FFmpeg命令行工具来创建单帧视频文件:

ffmpeg -i input.png -vcodec libx264 -qp 40 -pix_fmt yuv420p single_frame.mp4

(假设您的输入图像是

input.png
)。

-qp 40
参数应用恒定量化 40。

qp(qp)
设置恒定量化率控制方法参数

请参阅:libx264 文档

注:
由于它是单个框架,因此框架类型将是

I-Frame


如果您更喜欢基本 H.264 流(没有 MP4 容器),您可以使用:

ffmpeg -i input.png -vcodec libx264 -qp 40 -pix_fmt yuv420p single_frame.264

FFmpeg 有 Python 绑定,例如 ffmpeg-python
您可以使用它来编码表示原始视频帧的 NumPy 数组。
您还可以使用 FFmpeg 子进程的管道作为以下示例。


您可以在 GitHub 中找到 H.264 编码器的源代码(例如这里)。
据我所知,源代码是用 C 实现的。

在不查看来源的情况下,我认为您不会将它们视为“结构良好”。


0
投票

您想要对单个图像进行 H.264 编码的原因很少。 Jpeg 可能就是您想要的。但我有一个项目,我正在为视频构建超分辨率模型,并且视频压缩伪影不断增强,就好像它们是实际边缘一样。因此,我必须想出一种方法来对单个图像进行 H.264 视频编码,以训练它修复伪影而不是增强伪影。

compress_image_h264 采用 numpy 数组图像(h、w、c)和压缩量(建议 25-50)并输出压缩版本。
结果在返回之前被复制,因为我遇到了返回“不可写”数组的问题,并且复制修复了它。

def compress_image_h264(image, amount):
    # Encode the image to PNG format
    _, png_data = cv2.imencode('.png', image)

    # Use ffmpeg to compress the image using H.264 codec and MKV container
    ffmpeg_command = [
        'ffmpeg',
        '-y',                        # Overwrite output files without asking
        '-i', 'pipe:0',              # Input from stdin
        '-vcodec', 'libx264',        # Use H.264 codec
        '-qp', str(amount),          # Quality parameter
        '-pix_fmt', 'yuv420p',       # Pixel format
        '-f', 'matroska',            # Use MKV container
        'pipe:1'                     # Output to stdout
    ]

    result = subprocess.run(
        ffmpeg_command,
        input=png_data.tobytes(),    # Pass PNG data to stdin
        stdout=subprocess.PIPE,      # Capture stdout
        stderr=subprocess.PIPE       # Capture stderr for debugging
    )

    if result.returncode != 0:
        print("FFmpeg error during compression:", result.stderr.decode())
        raise RuntimeError("FFmpeg compression failed")

    # Get the compressed data from stdout
    compressed_data = result.stdout

    return np.copy(decompress_image_h264(compressed_data, image.shape[1], image.shape[0]))
def decompress_image_h264(compressed_data, width, height):
    # Use ffmpeg to decompress the image from H.264 to raw format
    ffmpeg_command = [
        'ffmpeg',
        '-i', 'pipe:0',              # Input from stdin
        '-f', 'rawvideo',            # Output raw video format
        '-pix_fmt', 'bgr24',         # Pixel format
        'pipe:1'                     # Output to stdout
    ]

    result = subprocess.run(
        ffmpeg_command,
        input=compressed_data,       # Pass compressed data to stdin
        stdout=subprocess.PIPE,      # Capture stdout
        stderr=subprocess.PIPE       # Capture stderr for debugging
    )

    if result.returncode != 0:
        print("FFmpeg error during decompression:", result.stderr.decode())
        raise RuntimeError("FFmpeg decompression failed")

    # Get the raw image data from stdout
    raw_image_data = result.stdout

    # Ensure we have enough data to reshape into the desired format
    expected_size = width * height * 3
    if len(raw_image_data) != expected_size:
        print("Unexpected raw image data size:", len(raw_image_data))
        raise ValueError(f"Cannot reshape array of size {len(raw_image_data)} into shape ({height},{width},3)")

    # Convert the raw data to a numpy array
    frame = np.frombuffer(raw_image_data, dtype=np.uint8).reshape((height, width, 3))

    return frame
© www.soinside.com 2019 - 2024. All rights reserved.