从编码图像和视频中提取 DCT 系数

2023-11-27

有没有一种方法可以轻松地从编码图像和视频中提取 DCT 系数(和量化参数)?任何解码器软件都必须使用它们来解码块 DCT 编码的图像和视频。所以我很确定解码器知道它们是什么。有没有办法将它们暴露给使用解码器的人?

我正在实现一些直接在 DCT 域中工作的视频质量评估算法。目前,我的大部分代码都使用 OpenCV,因此如果有人知道使用该框架的解决方案,那就太好了。我不介意使用其他库(也许是 libjpeg,但这似乎仅适用于静态图像),但我主要关心的是尽可能少地执行特定于格式的工作(我不想重新发明轮子并编写我自己的解码器)。我希望能够打开 OpenCV 可以打开的任何视频/图像(H.264、MPEG、JPEG 等),并且如果它是块 DCT 编码的,以获得 DCT 系数。

在最坏的情况下,我知道我可以编写自己的块 DCT 代码,通过它运行解压缩的帧/图像,然后我会回到 DCT 域。这并不是一个优雅的解决方案,我希望我能做得更好。

目前,我使用相当常见的 OpenCV 样板来打开图像:

IplImage *image = cvLoadImage(filename);
// Run quality assessment metric

我用于视频的代码同样简单:

CvCapture *capture = cvCaptureFromAVI(filename);    
while (cvGrabFrame(capture))
{
    IplImage *frame = cvRetrieveFrame(capture);
    // Run quality assessment metric on frame
}
cvReleaseCapture(&capture);

在这两种情况下,我都会得到一个 3 通道IplImageBGR 格式。有什么方法可以得到 DCT 系数吗?


好吧,我读了一些书,我原来的问题似乎是一厢情愿的例子。

基本上,不可能从 H.264 视频帧中获取 DCT 系数,原因很简单:H.264不使用DCT。它使用不同的变换(整数变换)。接下来,该变换的系数不一定会逐帧变化 - H.264 更智能,因为它将帧分割成切片。应该可以通过特殊的解码器获得这些系数,但我怀疑 OpenCV 是否会向用户公开它。

对于 JPEG 来说,情况要乐观一些。正如我所怀疑的那样,libjpeg为您公开 DCT 系数。我编写了一个小应用程序来证明它可以工作(源代码在最后)。它使用每个块的 DC 项生成一个新图像。由于 DC 项等于块平均值(经过适当缩放后),因此 DC 图像是输入 JPEG 图像的下采样版本。

EDIT:源中的固定缩放比例

原始图像(512 x 512):

jpeg image

DC 图像 (64x64):luma Cr Cb RGB

DC luma DC Cb DC Cr DC RGB

来源(C++):

#include <stdio.h>
#include <assert.h>

#include <cv.h>    
#include <highgui.h>

extern "C"
{
#include "jpeglib.h"
#include <setjmp.h>
}

#define DEBUG 0
#define OUTPUT_IMAGES 1

/*
 * Extract the DC terms from the specified component.
 */
IplImage *
extract_dc(j_decompress_ptr cinfo, jvirt_barray_ptr *coeffs, int ci)
{
    jpeg_component_info *ci_ptr = &cinfo->comp_info[ci];
    CvSize size = cvSize(ci_ptr->width_in_blocks, ci_ptr->height_in_blocks);
    IplImage *dc = cvCreateImage(size, IPL_DEPTH_8U, 1);
    assert(dc != NULL);

    JQUANT_TBL *tbl = ci_ptr->quant_table;
    UINT16 dc_quant = tbl->quantval[0];

#if DEBUG
    printf("DCT method: %x\n", cinfo->dct_method);
    printf
    (
        "component: %d (%d x %d blocks) sampling: (%d x %d)\n", 
        ci, 
        ci_ptr->width_in_blocks, 
        ci_ptr->height_in_blocks,
        ci_ptr->h_samp_factor, 
        ci_ptr->v_samp_factor
    );

    printf("quantization table: %d\n", ci);
    for (int i = 0; i < DCTSIZE2; ++i)
    {
        printf("% 4d ", (int)(tbl->quantval[i]));
        if ((i + 1) % 8 == 0)
            printf("\n");
    }

    printf("raw DC coefficients:\n");
#endif

    JBLOCKARRAY buf =
    (cinfo->mem->access_virt_barray)
    (
        (j_common_ptr)cinfo,
        coeffs[ci],
        0,
        ci_ptr->v_samp_factor,
        FALSE
    );
    for (int sf = 0; (JDIMENSION)sf < ci_ptr->height_in_blocks; ++sf)
    {
        for (JDIMENSION b = 0; b < ci_ptr->width_in_blocks; ++b)
        {
            int intensity = 0;

            intensity = buf[sf][b][0]*dc_quant/DCTSIZE + 128;
            intensity = MAX(0,   intensity);
            intensity = MIN(255, intensity);

            cvSet2D(dc, sf, (int)b, cvScalar(intensity));

#if DEBUG
            printf("% 2d ", buf[sf][b][0]);                        
#endif
        }
#if DEBUG
        printf("\n");
#endif
    }

    return dc;

}

IplImage *upscale_chroma(IplImage *quarter, CvSize full_size)
{
    IplImage *full = cvCreateImage(full_size, IPL_DEPTH_8U, 1);
    cvResize(quarter, full, CV_INTER_NN);
    return full;
}

GLOBAL(int)
read_JPEG_file (char * filename, IplImage **dc)
{
  /* This struct contains the JPEG decompression parameters and pointers to
   * working space (which is allocated as needed by the JPEG library).
   */
  struct jpeg_decompress_struct cinfo;

  struct jpeg_error_mgr jerr;
  /* More stuff */
  FILE * infile;        /* source file */

  /* In this example we want to open the input file before doing anything else,
   * so that the setjmp() error recovery below can assume the file is open.
   * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
   * requires it in order to read binary files.
   */

  if ((infile = fopen(filename, "rb")) == NULL) {
    fprintf(stderr, "can't open %s\n", filename);
    return 0;
  }

  /* Step 1: allocate and initialize JPEG decompression object */

  cinfo.err = jpeg_std_error(&jerr);

  /* Now we can initialize the JPEG decompression object. */
  jpeg_create_decompress(&cinfo);

  /* Step 2: specify data source (eg, a file) */

  jpeg_stdio_src(&cinfo, infile);

  /* Step 3: read file parameters with jpeg_read_header() */

  (void) jpeg_read_header(&cinfo, TRUE);
  /* We can ignore the return value from jpeg_read_header since
   *   (a) suspension is not possible with the stdio data source, and
   *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
   * See libjpeg.txt for more info.
   */

  /* Step 4: set parameters for decompression */

  /* In this example, we don't need to change any of the defaults set by
   * jpeg_read_header(), so we do nothing here.
   */

  jvirt_barray_ptr *coeffs = jpeg_read_coefficients(&cinfo);

  IplImage *y    = extract_dc(&cinfo, coeffs, 0);
  IplImage *cb_q = extract_dc(&cinfo, coeffs, 1);
  IplImage *cr_q = extract_dc(&cinfo, coeffs, 2);

  IplImage *cb = upscale_chroma(cb_q, cvGetSize(y));
  IplImage *cr = upscale_chroma(cr_q, cvGetSize(y));

  cvReleaseImage(&cb_q);
  cvReleaseImage(&cr_q);

#if OUTPUT_IMAGES
  cvSaveImage("y.png",   y);
  cvSaveImage("cb.png", cb);
  cvSaveImage("cr.png", cr);
#endif

  *dc = cvCreateImage(cvGetSize(y), IPL_DEPTH_8U, 3);
  assert(dc != NULL);

  cvMerge(y, cr, cb, NULL, *dc);

  cvReleaseImage(&y);
  cvReleaseImage(&cb);
  cvReleaseImage(&cr);

  /* Step 7: Finish decompression */

  (void) jpeg_finish_decompress(&cinfo);
  /* We can ignore the return value since suspension is not possible
   * with the stdio data source.
   */

  /* Step 8: Release JPEG decompression object */

  /* This is an important step since it will release a good deal of memory. */
  jpeg_destroy_decompress(&cinfo);

  fclose(infile);

  return 1;
}

int 
main(int argc, char **argv)
{
    int ret = 0;
    if (argc != 2)
    {
        fprintf(stderr, "usage: %s filename.jpg\n", argv[0]);
        return 1;
    }
    IplImage *dc = NULL;
    ret = read_JPEG_file(argv[1], &dc);
    assert(dc != NULL);

    IplImage *rgb = cvCreateImage(cvGetSize(dc), IPL_DEPTH_8U, 3);
    cvCvtColor(dc, rgb, CV_YCrCb2RGB);

#if OUTPUT_IMAGES
    cvSaveImage("rgb.png", rgb);
#else
    cvNamedWindow("DC", CV_WINDOW_AUTOSIZE); 
    cvShowImage("DC", rgb);
    cvWaitKey(0);
#endif

    cvReleaseImage(&dc);
    cvReleaseImage(&rgb);

    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从编码图像和视频中提取 DCT 系数 的相关文章

  • 如何检测图像中对象的实例?

    我有一张包含几个特定对象的图像 我想检测这些物体在该图像中的位置 为此 我有一些模型图像 其中包含我想要检测的对象 这些图像在我想要检测的对象实例周围得到了很好的裁剪 这是一个例子 在这张大图里 我想检测此模型图像中表示的对象 自从你最初发
  • 在 iPad 上使用 OpenCV 避免碰撞

    我正在开展一个项目 需要使用 OpenCV 实现碰撞避免 这是在 iOS 上完成的 iOS 5 及以上版本即可 项目目标 这个想法是将 iPad 安装在汽车仪表板上并启动应用程序 应用程序应该从相机中抓取帧并进行处理 以检测汽车是否会与任何
  • 在opencv中发现凸性缺陷? [根据给定的输入图像崩溃..]

    我有一个计算图像凸包的程序 我正在尝试使用此信息来计算fingers存在于输入图像中 从一些冲浪中我发现做到这一点的方法 数手指 是 寻找轮廓 凸包 凸性缺陷 但我在使用凸性缺陷函数时遇到了麻烦 它编译得很好 但在运行时程序会因某些输入图像
  • 如何将 OpenCV 等待键与 Chaquopy 一起使用

    我正在尝试使用 Chaquopy 将计算机视觉应用程序移植到 Android 当我尝试运行脚本时 以下行中出现以下错误 cv2 waitKey 100 打印到嵌入式 python 控制台的错误是 java chaquopy CQPEnv c
  • 图像处理编程

    我想知道是否有任何方法可以使用某种编程语言检测图像中对象的位置 例如 如果我有一个球的图像 每 100 毫秒更新一次 是否可以通过某些程序使用某些东西来获取球的坐标 看一下OpenCV http opencv willowgarage co
  • 如何解决 Python 'Pyzbar' 库的导入错误?

    我刚刚开始熟悉 Pyzbar 库 但是当使用decode方法我得到一个错误 这是代码 import cv2 import numpy as np import pyzbar code image cv2 imread C Users Ace
  • bitblt 在 Windows 10 版本 1703 上失败 (15063.138)

    使用 Visual Studio 2017 vc141 以下代码应该从前游戏窗口获取屏幕截图 但现在它返回黑色和空白图像 唯一的游戏问题 尝试过 OpenGL 和 Vulkan ogl 返回黑色 vulkan 返回白色 在升级到 Windo
  • 如何使用 OpenCV 检测图像帧中的对象?

    我正在使用 Raspberry Pi 开发一个漫游器 它将清扫房间并捡起掉落在地上的物体 为了检测物体 我使用了在流动站操作开始时拍摄的参考图像 以及每 10 秒单击一次的图像 新图像 为了确定图像帧是否发生变化 我在参考图像和新图像之间进
  • 在 C、C++ 中实现腐蚀、膨胀

    我对二值图像的膨胀是如何完成的有理论上的了解 AFAIK 如果我的 SE 结构元素 是这样的 0 1 1 1 在哪里 代表中心 我的图像 二进制是这样的 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0
  • brew 链接 jpeg 问题

    我正在尝试安装opencv在 Mac OSX Lion 上 brew install opencv 我收到以下错误 以及其他一些类似的错误 Error The linking step did not complete successful
  • opencv createsamples没有错误,但是没有找到样本

    我在用着this http coding robin de 2013 07 22 train your own opencv haar classifier html教程 我正在根据我的正面图像创建大量样本 我正在使用 Windows 这是
  • Opencv matchTemplate 和 np.where():仅保留唯一值

    继带有马里奥硬币的 opencv 教程 https opencv python tutroals readthedocs io en latest py tutorials py imgproc py template matching p
  • 如何在给定目标大小的情况下在 python 中调整图像大小,同时保留纵横比?

    首先 我觉得这是一个愚蠢的问题 对此感到抱歉 目前 我发现计算最佳缩放因子 目标像素数的最佳宽度和高度 同时保留纵横比 的最准确方法是迭代并选择最佳缩放因子 但是必须有更好的方法来做到这一点 一个例子 import cv2 numpy as
  • 来自 OpenCV 的外部参数

    我正在使用 OpenCV 来校准立体相机对 我拍摄了各种校准照片 并且使用 cv2 calibrateCamera 对内在参数进行了令人满意的拟合 然而 目前尚不清楚如何获取外部参数 该函数仅返回cameraMatrix 尽管它很有用 但实
  • Python:opencv warpPerspective 既不接受 2 个也不接受 3 个参数

    我发现单应矩阵如下特征匹配 单应性教程 https docs opencv org 3 4 1 d1 de0 tutorial py feature homography html using M mask cv2 findHomograp
  • 在加载“cv2”二进制扩展期间检测到递归

    我有一个小程序 在 pyinstaller 编译后返回 opencv 错误 但无需编译即可工作 我在 Windows 10 上使用 Python 3 8 10 Program 导入 pyautogui将 numpy 导入为 np导入CV2
  • 如何计算图像中的 RGB 或 HSV 通道组合?

    我使用 python opencv 加载形状为 30 100 3 的图像 现在想要按颜色计算所有颜色的频率 我不是指单个通道 而是指通道组合 含义 3 个频道列表 例如 255 0 0 表示红色 255 255 0 表示黄色 100 100
  • Tesseract 是否会忽略扫描文档中的任何非文本区域?

    我正在使用 Tesseract 但我不知道它是否忽略任何非文本区域并仅针对文本 我是否必须删除任何非文本区域作为预处理步骤以获得更好的输出 Tesseract 有一个非常好的算法来检测文本 但它最终会给出误报匹配 理想情况下 您应该在将图像
  • 曲线/路径骨架二值图像处理

    我正在尝试开发一个可以处理图像骨架的路径 曲线的代码 我想要一个来自两点之间骨架的点向量 该代码在添加一些点后结束 我没有找到解决方案 include opencv2 highgui highgui hpp include opencv2
  • OpenCV 仅围绕大轮廓绘制矩形?

    第一次发帖 希望我以正确的方式放置代码 我正在尝试检测和计算视频中的车辆 因此 如果您查看下面的代码 我会在阈值处理和膨胀后找到图像的轮廓 然后我使用 drawContours 和矩形在检测到的轮廓周围绘制一个框 我试图在 drawCont

随机推荐

  • 设置 blob 的过期限制

    我使用 Azure Storage 来存储信息 例如缓存机制 因此 对于给定的输入 我是第一次执行该工作 之后我会将结果保存在缓存中以供进一步使用 当我需要使用相同的给定输入解决问题时 我将直接从存储中获取已经准备好的解决方案 这一切都已实
  • 使用队列的异步持久客户端协议类

    我正在尝试了解 Python 3asyncio模块 特别是使用传输 协议 API 我想创建一个发布 订阅模式 并使用asyncio Protocol类来创建我的客户端和服务器 目前 我已经启动并运行了服务器 并侦听传入的客户端连接 客户端能
  • Microsoft.Build.Utilities.FileTracker 引发异常错误。发生在不同的项目中

    最近在 Win7 64 位中使用 Visual Studio 2010 Ultimate C 编译任何项目时都会出现以下错误 解决方法是添加
  • 如何使用 python 电子邮件获取解码附件文件名?

    我使用以下代码来提取附件的文件名 import email utils msg email message from string self request body http docs python org 2 library email
  • JNI。如何从 jobject 获取 jstring 并将其转换为 char*

    这是我到目前为止所拥有的 我传递一个有 2 个字段的对象 String 和 Integer 作为参数 我想发送信息来在C部分中处理它 这在这一点上并不重要 我在 jstring 声明中收到投诉 JNIEXPORT jint JNICALL
  • 将 Laravel 集合排序到 ID 数组

    是否可以使用单独的 ID 数组来订购关系集合 同时仍然通过关系进行访问 设置是Checklist有很多ChecklistItems 以及相关项的所需顺序作为属性存在Checklist item order 它只是按用户所需顺序排列的数字 I
  • 更改运行 netbeans 的 java 平台

    我正在使用 Netbeans 6 7 我在安装 Netbeans 之前首先安装了 Java 1 5 当我安装 Netbeans 时 它采用 Java 1 5 作为默认版本 然后我在我的机器上安装了Java 1 6 我不仅需要将特定项目的 N
  • 如何在用户密码中添加盐?

    我正在使用简单md5 password 格式 但我想加盐 那么我该怎么做呢 这是我的代码 if success data firstname firstname data lastname lastname data username us
  • 如何将新的本地分支推送到远程 Git 存储库并对其进行跟踪?

    我如何能 从另一个分支创建本地分支 通过git branch or git checkout b 推送本地分支 到远程存储库 即发布 但使其 可追踪 以便git pull and git push将工作 在 Git 1 7 0 及更高版本中
  • 如何消除错误“'.'”为 MEAN 堆栈运行“npm install”时,不被识别为内部或外部命令?

    从mean io 下载mean stck zip 是否安装了 npm 几分钟后我收到一个错误 请看截图 我该怎么办 npm http 200 https registry npmjs org event emitter event e mi
  • 如何替换图像的颜色?

    我想替换图像的颜色 例如 将所有蓝色变为红色 形状不会变形 当我尝试这个时 我可以通过迭代每个像素来交换颜色 但是交换区域的形状变成平面形状 示例1输入 http www tutorialwiz com tutorials changing
  • Android 从右到左菜单项

    我有一个幻灯片菜单 如图一所示 我需要将其项目标题从右到左对齐 就像幻灯片二一样 我尝试了重力 右但没有用 这是我的代码 menu menu
  • 如何使用 Android 获得最准确的时间?

    我真的不认为这个问题是重复的 类似问题的大多数答案都说使用 System currentTimeMillis 作为最准确的时间 但我注意到并排的两个 Android 设备可能会彼此相差 5 秒或更长时间 或者 更重要的是 实时 我相信 cu
  • “VM初始化期间发生错误;使用 -Xmx3G 无法为对象堆保留足够的空间”

    首先 我有一个 8GB 内存的盒子 所以我怀疑总内存是问题所在 该应用程序在 6GB 或更少内存的机器上运行良好 我试图在 Eclipse 中的运行配置中的 VM Arguments 下使用 Xmx3G 保留 3GB 空间 每次我尝试保留超
  • 如何减小应用程序 (.apk) 的大小

    Help 当我在手机上安装应用程序进行测试时 它显示出巨大的大小 11 35 MB 这是一个非常简单的应用程序 可让用户浏览有趣的事实 我能想到的唯一原因是 drawable 中有 14 个 JPEG 文件 它们用作有趣事实的背景图像 这些
  • 使用不同的值更新多行

    我在我的 MySQL 数据库 users 中得到了这张表 它具有字段 id 和 value 现在我想更新lots of该表中的行带有singleSQL 查询 但许多行应该得到不同的值 目前 我正在使用这个 UPDATE users SET
  • 是否可以在服务器端运行 jQuery?

    我正在研究网页抓取 已经实现了AJAX分页 由于网站是用asp开发的 即扩展名为 aspx的页面 我尝试提交分页表单以从首页以外的其他页面获取数据 但没有取得任何成功 请看这里我用过的代码从所有实现 AJAX 分页的 ASP NET 页面中
  • asp.net MVC 部分视图控制器操作

    我对 Web 应用程序开发非常陌生 我想我应该从最新的技术开始 所以我尝试立即学习 ASP NET 以及 MVC 框架 对于 MVC 专业人士来说 这可能是一个非常简单的问题 我的问题是分部视图是否应该有关联的操作 如果是这样 每当普通页面
  • .NET Xbox 真实帐户 API

    是否有 NET API 可用于从您的 Xbox Live 帐户获取数据 我真正感兴趣的是谁在线 但消息也很酷 某种事件驱动的用户登录通知会很棒 但如果需要的话我会进行轮询 查看Xbox 社区开发者计划
  • 从编码图像和视频中提取 DCT 系数

    有没有一种方法可以轻松地从编码图像和视频中提取 DCT 系数 和量化参数 任何解码器软件都必须使用它们来解码块 DCT 编码的图像和视频 所以我很确定解码器知道它们是什么 有没有办法将它们暴露给使用解码器的人 我正在实现一些直接在 DCT