基于DirectDraw的Gamma calibrator机制之探讨

【OpenCV4】图像的伽玛矫正gamma fit 伽玛补偿 gamma calibration详解 gamma曲线 gamma 补偿的作用 gamma 补偿可以增加图片像素低的部分的对比度,减小图片像素高的部分的对比度。 也就是图片黑的地方可以看得更清晰,图片亮的地方会变得更模糊。 OpenCV 代码 #include<iostream> #include<opencv2/opencv.hpp> #include<vector> using namespace cv; using namespace std; int main() { cv::Mat img 阅读详情

基于DirectDraw的Gamma calibrator机制之探讨


一.问题的提出

Gamma calibrator基于动态gamma ramp技术。为系统提供动态gamma ramp支持,基于以下应用的需要:
1. 游戏程序的设计者可以为用户提供一致的视觉效果,而不论用户使用什么系统。
2. 随着电子商务的迅猛发展,商家和用户都迫切需要在Internet上看到货物样品的真实色彩。
3. 谁都希望,显示器上图像的色彩尽可能地和输出的色彩相近。

基于以上需要,具有Microsoft Windows Logo的硬件产品都需要提供动态gamma ramp支持(参见"Adapter supports downloadable RAMDAC entries for image color matching",网址: www.microsoft.com/hwdev/xpapers/pc98/14grfx98.htm)。只要显示卡及其驱动程序支持动态gamma ramp,buffer frame中所有象素的RGB值就可以被校正值取代。

为了在Windows95, Windows98和Windows2000中支持动态gamma ramp,DirectDraw中提供了IDirectDrawGammaControl接口。此接口允许程序设计者处理gamma ramp,使得象素的RGB值在被送到DAC显示之前得到校正。

本来,Win32 API中有两个函数(即SetDeviceGammaRamp/GetDeviceGammaRamp)可以用来获取和设置gamma ramp。但它们较之DirectDraw接口有以下局限:
1. SetDeviceGammaRamp不允许设置所有可能的gamma ramp值。它会检查gamma ramp,如果太复杂会拒绝执行。
2. SetDeviceGammaRamp目前不支持gamma calibrator。
3. 调用SetDeviceGammaRamp的程序关闭后不会自动进行清理操作,除非将gamma ramp恢复到设置前的值。

与以上第二点相反,除了可以获取和设置gamma ramp外,DirectDraw接口允许gamma ramp被校正(calibrated),这就需要安装一个gamma calibrator。


二.分析

据我所知,到目前为止,DirectDraw注册和使用Gamma calibrator的机制尚未最终确定,只有一个过渡方案。此方案只用短短一句话进行了描述:calibrator在系统注册表中的某个key中注册自身;当应用程序需要校正gamma ramp的时候,DirectDraw调用这个calibrator。

至于具体实现细节,到目前我没发现任何文档。

基于此,我对DirectDraw调用calibrator的机制进行了分析和猜测,发现如下:

1)Calibrator中必须实现一个名为CalibrateGammaRamp的输出函数,Gamma calibration的操作即在此函数中实现。
2)Calibrator必须将自身所在的安装路径注册在系统注册表的如下key中:
  HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/DirectDraw/GammaClibrator
3)客户程序通过调用IDirectDrawGammaControl::SetGammaRamp来间接触发calibrator。
SetGammaRamp的原型为:
  HRESULT SetGammaRamp(DWORD dwFlags, LPGAMMARAMP lpRampData)
DwFlag表示是否需要进行gamma calibration。若这个参数设为DDSGR_CALIBRATE,系统将会请求calibrator来调整gamma ramp,从而达到校正显示效果的目的。若不需要校正,将这个参数设为0。LpRampData是DDGAMMARAMP结构的地址,此结构包含R,G,B三色素的gamma ramp值。
设置dwFlags参数为DDSGR_CALIBRATE并调用SetGammaRamp后,DirectDraw会自动根据calibrator的注册信息找到calibrator的路径,并调用calibrator的CalibrateGammaRamp输出函数,从而实现gamma calibration。

三.实现

我写了两段测试程序来检验Gamma calibrator的实现机制。calibrator.cpp编译链接后生成calibrator.dll, 即gamma calibrator程序;test.cpp则生成test.exe,即客户程序,它调用calibrator。

1. calibrator
calibrator本身的结构很简单,它只需要实现三个函数(甚至一个,即CalibrateGammaRamp,其它两个可以在安装程序中或手工实现)。
1)CalibrateGammaRamp输出函数。其声明如下:
 extern "C" __declspec(dllexport) HRESULT CalibrateGammaRamp(D3DGAMMARAMP* pRamp)
其中输入参数pRamp为当前的gamma ramp值(也即,客户程序调用SetGammaRamp时设置的值)。出于测试的目的,在我的calibrator中没有利用这个初始值,而是重新设置了gamma ramp,并夸张地将所有的R(Red)值设置为0,以方便地看到测试效果。

 HDC hDC = ::GetDC(NULL);
 if (!hDC)
  return E_FAIL;

 WORD RamdacTable[3*256];

 GetDeviceGammaRamp(hDC, RamdacTable);

 for (int i = 0; i < 3; ++i)
  for (int j = 0; j < 256; ++j)
   if ( i == 0)
    RamdacTable[i] = 0;
   else
    RamdacTable[i*256+j] = j*256;

 if(!SetDeviceGammaRamp( hDC, RamdacTable))
 {
  BOOL bReason = GetLastError();
  ::MessageBox(NULL, "SetDeviceGampRamp failed!", "Error", NULL);
 }

 ::ReleaseDC(NULL, hDC);

2)为了让DLL可以register和unregister自己的安装路径,输出两个函数DllRegisterServer和DllUnregisterServer,以供regsvr32程序调用。这两个函数的实现和COM DLL中的写法一致,这里不再赘述。注意信息要注册到HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/DirectDraw/GammaClibrator键之下。


2. 客户程序

客户程序必须支持DirectDraw,才能调用calibrator。
1)首先,创建一个Direct3D object:
    LPDIRECT3D8 g_pD3D;
 g_pD3D = ::Direct3DCreate8(D3D_SDK_VERSION)
2)获得当前显示模式:
 D3DDISPLAYMODE d3ddm;
 g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm)
3)创建Direct3D device:
 LPDIRECT3DDEVICE8       g_pd3dDevice = NULL;
 g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
    D3DDEVTYPE_HAL,
    hWnd,
    D3DCREATE_SOFTWARE_VERTEXPROCESSING,
    &d3dpp,
    &g_pd3dDevice )
4)检测设备是否支持gamma calibration:
 D3DCAPS8 d3dcap;
 if( FAILED( g_pd3dDevice->GetDeviceCaps( &d3dcap ) ) )
 {
  ::MessageBox(NULL, "GetDeviceCaps", "Failed", NULL); 
  return E_FAIL;
 }
 if( !( d3dcap.Caps2 & D3DCAPS2_CANCALIBRATEGAMMA ) )
 {
  ::MessageBox(NULL, "Your machine doesn't support gamma Calibrator", "Warnning", NULL);
  return E_FAIL;
 }
5)设置gamma ramp:
 D3DGAMMARAMP d3dgamaramp;
 ... // 初始化d3dgamaramp

 // 设置gamma ramp,同时请求calibration
 g_pd3dDevice->SetGammaRamp( D3DSGR_CALIBRATE , &d3dgamaramp);


四.结论
由于没看到M$关于gamma calibration的正式文档,以上机制纯属自己的猜测。测试程序虽能work,但终究只是猜测,不知尚有多少规范没有实现。而且,在win2000下,DirectDraw对gamma calibration的支持似乎不够。再者,M$声称,目前DirectDraw和gamma calibrator的通信机制以及calibrator注册自身的方法只是一个过渡方案,将来会改变。鉴于以上原因,特写此文,以请对gamma calibration有研究者不吝赐教。

FOC控制必看:单/双/三电阻电流采样方案全对比(附NXP实战避坑指南) 本文深入对比了FOC控制中单电阻、双电阻和三电阻电流采样方案的优劣与适用场景,重点剖析了采样时序、窗口与ADC转换的工程挑战。针对NXP平台,提供了解决采样窗口过窄的实战方案与配置指南,帮助工程师根据成本与性能需求做出最优选择,并规避常见设计陷阱。 阅读详情

相关推荐

华为路由器静态路由配置实战:从零搭建企业级网络环境(含常见错误排查)

本文以真实企业组网案例为基础,详细解析华为路由器静态路由的实战配置流程。内容涵盖从网络拓扑规划、IP地址分配到具体的`ip route-static`命令配置,并重点讲解了缺省路由、浮动路由等进阶应用。文章还提供了系统化的排错指南,帮助网络工程师规避回程路由缺失、子网掩码错误等常见问题,是掌握企业级网络搭建与维护的实用指南。

weixin_29313817的博客 90

gamma校正_BoxIO+色彩管理软件校正第三方监视器

使用BoxIO搭配LightSpace CMS色彩管理软件校正第三方监视器硬件需求:第三方监视器X-Rite i1Display Pro OEM尊正BoxIO软件需求:LightSpace CMS色彩管理软件IP Remote控制助手准备工作:将第三方监视器开机,将监视器恢复到默认状态然后尽可能的找到跟监视器色彩管理相关的设置,将其关闭。尽量让监视器在一个原始的状态下去做第三方校正,这样...

weixin_39714275的博客 2791

机器学习预测股票收益(一)之随机森林模型

机器学习预测股票收益(一)前言一、导入库和数据二、处理数据以及计算特征变量三、使用随机森林回归预测股票收益1.构建训练集和测试集2.查看预测结果四、根据预测结果构建long-short投资组合1.定义投资组合函数2.定义绩效分析函数五、引入Fama-French Factor六、投资组合表现1.超额收益表现2.多因子回归总结 前言 本文将使用Python整理1927-2020年所有美国上市公司股票数据。根据历史收益以及交易量,使用随机森林,支持向量机以及神经网络等机器学习方法预测股票收益。最优结果构建的资产

weixin_47174968的博客 1万+

【图形学】我理解的伽马校正(Gamma Correction)

https://blog.youkuaiyun.com/candycat1992/article/details/46228771/

weixin_40710375的博客 640

VASPKIT绘制平面平均电荷差分密度

平面平均密度差(planar-averaged electron density difference)是密度差的衍生。密度差是个三维空间函数,经常通过绘制平面图、等值面图方式图形化考察。虽然这两种图很直观,但平面图会受到截面选取的影响,而等值面图会受到等值面数值(isovalue)选取的影响,因此都有一定任意性,也不容易定量讨论。对于电子转移有比较明确方向的情况,可以绘制平面平均密度差曲线,由此可以清楚地考察垂直于选取的方向上每个截面上的密度差积分值,在定量讨论、对比上比较便利。

weixin_43948934的博客 1万+

保姆级图解:HKMG工艺中的‘覆盖层’(Cap Layer)到底怎么调阈值电压?

本文深入解析了HKMG工艺中覆盖层(Cap Layer)如何精准调控阈值电压的关键技术。通过原子级精度的ALD工艺和材料选择,覆盖层在半导体制造中扮演着隐形调节器的角色,直接影响晶体管的电气特性。文章详细介绍了La2O3和Al2O3等材料的特性对比、ALD工艺的原子级控制,以及实战调试中的关键步骤和问题排查方法。

weixin_27032989的博客 497

使用 SetDeviceGammaRamp 调整屏幕亮度

使用 SetDeviceGammaRamp 调整屏幕亮度

zgl7903的专栏 4299

STM32的DMA模块及Protues仿真实验

(一)DMA简介      DMA(Direct Memory Access,直接存储器访问), 用于在外设与存储器之间以及存储器与存储器之间提供高速数据传输。可以在无需任何 CPU 操作的情况下通过 DMA 快速移动数据。这样节省的 CPU 资源可 供其它操作使用。      STM32F407共有两个 DMA 控制器,总共有 16 个数据流(每个控制器 8 个),每一个 DMA 控制器都用于管理 一个或多

weixin_45930204的博客 2850

DX学习笔记之Surfaces

声明:本文完全翻译自DX SDK Documentation 一个surface代表了显存中的一块线性区域,通常在显卡的显存中,尽管surface也可以存在系统内存中。surface是被IDirect3DSurface9接口管理的。  1. front buffer:一块矩形内存,会被graphics adapter翻译并在显示屏上显示。在D3D中,程序从来不会直接往front buf

十年磨一剑 5147

机器人运动不流畅?手把手教你用ACCSET调整ABB/FANUC点位加速度

本文针对ABB和FANUC工业机器人运动不流畅、拐角抖动、到位震颤等常见问题,提供了详细的解决方案。核心在于使用ACCSET指令(ABB)或ACC选项(FANUC)调整机器人的点位加速度与减速度参数。文章通过实战案例与系统化调试流程,手把手指导工程师优化运动性能,实现平稳、精准的机器人运动控制。

gpu4optimizer的博客 285

Jasper Report使用JSON数据源创建报表

最近在做一个项目小功能,表单结案要生成PDF报表。 起初,想用HTML模板(art-template模板引擎)编写,利用浏览器的打印功能保存成pdf文件下载。但是HTML编写好的模板,页码、页眉、页脚设置有坑,表单内容中的表格较多,表格不能设置跨页,导致跨页的表格内容与页眉重叠,没能解决这个问题。 于是,转战研究Jasper report生成报表,用更加专业的报表生成工具来做。刚开始,也是跌跌撞撞,遇到了很多问题,因为觉得没有退路了,必须要用这个搞出来,所以就硬着头皮去找各种资料。 主要使用的json

xiaogege2012的专栏 3321

基于DirectDraw的Gamma calibrator机制之探讨 (转)

基于DirectDraw的Gamma calibrator机制之探讨 (转)[@more@]基于DirectDraw的Gamma calibrator机制之探讨 一.问题的提出 Gamma calibrator基于动态gam...

csd3176的博客 173

SAP_PP模块跑完 MRP,MD04 里却看不到“计划订单”?排查这 3 个最容易被忽略的主数据参数

MRP 是 SAP 逻辑最严密的模块之一,它绝不会随机罢工。当 MD04 里看不到计划订单时,请不要怀疑系统的计算能力。99% 的情况,都是因为我们给系统下达了矛盾的指令:一边告诉它“我有需求”,一边却通过主数据告诉它“不要计划”、“不要触发”或者“我是冻结的”。掌握这 3 个排查点,你就能在 5 分钟内解决大部分“MRP 失灵”的悬案,成为用户眼中的“系统神医”。

我小时候很黑的博客 601

setDeviceGammaRamp调节 gamma ramp用法

C++代码: 优快云版本:  代码:API函数原形如下():BOOL WINAPI GetDeviceGammaRamp(  HDC hDC,  LPVOID lpRamp); BOOL WINAPI SetDeviceGammaRamp(  HDC hDC,  LPVOID lpRamp);其中lpRamp指向的是一个3x256的WORD型数组,内部存放的是需要Gamma校正的梯度,范

9140

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Gamma correction 伽马校准及 matlab 实现

用以调整图像光照强度的非线性操作,其数学形式为:Vout=AVγin Vin:非负实数值,比如为图像像素; AA:某一常数,通常情况下取值为 1,输入输出的范围一般为 [0, 1]; γ<1\gamma < 1:光照强度变强,称为 gamma compression γ>1\gamma > 1:光照强

2万+

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

理解gamma校正

UNDERSTANDING GAMMA CORRECTION Gamma is an important but seldom understood characteristic of virtually all digital imaging systems. It defines the relationship between a pixel's numerical value and

vola的专栏 7367

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

色彩校正中的 gamma 值是什么?

作者:韩世麟 链接:https://www.zhihu.com/question/27467127/answer/37555901 来源:知乎 著作权归作者所有,转载请联系作者获得授权。 我打算抛开计算机图像、显示器发展史等因素,从逻辑上推出一个“广义的Gamma”,这样其实是触及了问题的本质。把人对画面的认知,和Gamma出现的必然性都推理出来。 先上结论: “广义G

xishuang_gongzi的专栏 6350

gamma校准

设备为了适应人眼设定的调节图片和显示效果的参数叫做gamma。 不同gamma值的效果展示 import cv2 import numpy as np import matplotlib.pyplot as plt gamma1 = 0.4 gamma2 = 2.5 # 读取图片 imgIn = cv2.imread('D:\\code\\2.jpg', 0) imgIn = imgIn.astype(float) / 255 # gamma校准 out1 = imgIn ** gamma1 out

sunny 537

VC++调节显示器的亮度SetDeviceGammaRamp

出处:http://www.nirsoft.net/vc/change_screen_brightness.html SetDeviceGammaRamp API函数位于Gdi32.ll中,接收一个256*3 RGB值的数组。增加这个数组中的值会使屏幕更亮,而减少这些值会使屏幕变暗。可以通过增加或减少的红/绿/蓝成分的值来显示影响。例如:在所有RGB值中增加蓝色分量将增加整个显示的蓝色。下面的类封...

weixin_33726313的博客 1219

12[红+绿+蓝+Alpha]

第十二集 红+绿+蓝+Alpha   红绿蓝组成了绚烂的颜色世界, 当红绿蓝遇到Alpha后, 这个颜色世界又多了一份神秘.   神秘的Alpha, 我们可以简单的认为它和红, 绿, 蓝一样, 是组成色彩的一种属性, 用来表示透明度.   Directx Graphics中的色彩一般使用"RGB"格式表示, RGB格式有三种原色 --- red(红), gre

5477

Gamma校正原理及实现

gamma校正原理:   假设图像中有一个像素,值是 200 ,那么对这个像素进行校正必须执行如下步骤:    1. 归一化 :将像素值转换为  0 ~ 1  之间的实数。 算法如下 : ( i + 0. 5)/256  这里包含 1 个除法和 1 个加法操作。对于像素  A  而言  , 其对应的归一化值为  0. 783203 。    2. 预补偿 :根据公式  , 求出像素归一化

linqianbi的博客 8万+

Gamma校正及其实现

图2中左图为原图,中图为gamma = 1/2.2在校正结果,原图中左半侧的灰度值较高,右半侧的灰度值较低,经过gamma = 1/2.2校正后(中图),左侧的对比度降低(见胡须),右侧在对比度提高(明显可以看清面容),同时图像在的整体灰度值提高。 右图为gamma = 2.2在校正结果,校正后,左侧的对比度提高(见胡须),右侧在对比度降低(面容更不清楚了),同时图像在的整体灰度值降低。

lichengyu的专栏 3万+

linux驱动开发:用户空间操作LCD显示简单的图片

上一章我们简单介绍了LCD的一些基本原理。当然更深奥的还有,比如gamma,dither,HUE,satuation.OSD等等. 我们知道我们是用framebuffer来实现显示的. 显存:framebuffer.由DDRAM中划去一部分内存供显存使用. 从而操作lcd相当于操作显存. lcd控制器(s5pv210里面有lcd控制器)会周期的获取framebuffer中的数据。经...

boyemachao的专栏 1430

循环嵌套(多层 for 循环)

表:order(订单表,order_id, user_id)、user(用户表,user_id, user_name)✅ 优化:先查所有订单,拿到所有 user_id 批量 in 查询,内存 join。✅ 优化:先把优惠券转 HashMap,单层循环查找(hash 查找 O (1))SQL 只有 2 次,O (1) 数据库查询,内存遍历 O (n)。需求:查询所有订单列表,同时带出每个订单对应的用户名称。需求:订单列表、优惠券列表,把订单匹配对应的优惠券名称。复杂度:O (M+N),非常快。

weixin_43732943的博客 191
上一篇: Java Tip: 实现Command模式
下一篇: More Exceptional C++ 中文版试读(译序及目录)
lostmouse
博客等级 码龄26年 22粉丝 63原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值