调整图像亮度brightness,对比度contrast,饱和度saturation方法整理

简单的实现方案
数据格式:YUV
参考链接2中采用CxImage(关于CxImage,参考:转贴 CxImage类库使用说明 - 走在路上 - 博客频道 - CSDN.NET)库提供的处理方法,采用查表法处理效率很高。粘贴部分处理代码

CxImage\ximadsp.cpp
/**
 * Changes the brightness and the contrast of the image.
 * \param brightness: can be from -255 to 255, if brightness is negative, the image becomes dark.
 * \param contrast: can be from -100 to 100, the neutral value is 0.
 * \return true if everything is ok
 */
bool CxImage ::Light (long brightness , long contrast )
{
       if (! pDib) return false;
       float c=(100 + contrast)/100.0f;
       brightness+=128;

       BYTE cTable[256]; //<nipper>
       for ( int i=0; i<256; i++) {
             cTable[ i] = ( BYTE) max(0, min(255,( int)(( i-128)* c + brightness + 0.5f)));
      }

       return Lut( cTable);
}

/**
 * Changes the saturation of the image.
 * \param saturation: can be from -100 to 100, positive values increase the saturation.
 * \param colorspace: can be 1 (HSL) or 2 (YUV).
 * \return true if everything is ok
 */
bool CxImage ::Saturate (const long saturation , const long colorspace )
{
...
for (int i =0;i <256;i ++) {
    cTable[ i] = (BYTE)max(0,min (255,(int )((i -128)*(100 + saturation)/100.0f + 128.5f)));
}
...
}


通过如下处理,就可以得到处理后图像了
// Y分量,在对图像亮度和对比度进行调节后,通过查表 m_YTable获得新的Y 值
// pdst为转换后的图像,pbufy为原图像的Y分量
for ( int height=0; height< m_frameHeight; height ++)
{
     for ( int width=0; width< m_frameWidth; width ++)
     {
         *pdst++ = cTable[*pbufy++];
     }
}


其他方案:
方案1. 基于Dirextx利用像素着色器实现图像的亮度,饱和度操作

该文提供一个源代码,编译时需要D3D相关的lib库。该程序将对图像处理的细节交个了D3D,通过设置一个D3DXMATRIX结构体完成亮度饱和度等的操作。
优点:通过D3D实现,图片处理速度快效率高。
缺点:需要了解D3D相关的知识,学习成本较大。

方案2. 使用DirectDraw色彩控制IDirectDrawColorControl
原理与DirectX类似,因为我做的项目其2D图像渲染是使用DirectDraw实现的,很自然的想到了使用这个方法,但要非常注意的是,你的显卡要能够支持IDirectDrawColorControl,也就是说DirectDraw能够提供相应capacity,很遗憾的是我的显卡并不支持该特性,你可以用如下代码测试是否该功能:
// initializes a direct draw struct
#define DDRAW_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }

// create IDirectDraw interface 7.0 object and test for error
if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)))
     return(0);

DDCAPS hel_caps, hal_caps;

// initialize the structures
DDRAW_INIT_STRUCT(hel_caps);
DDRAW_INIT_STRUCT(hal_caps);

if (FAILED(lpdd->GetCaps(&hal_caps, &hel_caps)))
      return(0);

if (hal_caps.dwCaps2 & DDCAPS2_COLORCONTROLPRIMARY)
      OutputDebugString(_T("Supports primary surface contains color controls\n"));

if (hal_caps.dwCaps2 & DDCAPS2_COLORCONTROLOVERLAY)
      OutputDebugString(_T("Supports overlay surface contains color controls\n"));

if (hal_caps.dwCaps2 & DDCAPS2_PRIMARYGAMMA)
      OutputDebugString(_T("Supports loadable gamma ramps for the primary surface\n"));

同样的,你需要对DirectDraw有必要的了解,如果是使用GDI来负责图像的绘制,那么DirectX和DirectDraw的方案并不适合。

方案3 使用GDI+中的ColorMatrix

在WPF中结合Emgu CV库来使用Slider控制图像亮度对比度饱和度,你需要做的是: 1. 首先,安装Emgu CV库,它是开源的.NET版OpenCV实现。可以从GitHub或其他NuGet源获取并添加到项目中。 2. 创建一个`Window`或用户界面元素,添加三个`Slider`控件分别对应亮度(Brightness)、对比度Contrast)和饱和度Saturation)。例如: ```xaml <StackPanel> <Label Content="Brightness:" /> <Slider x:Name="brightnessSlider" Minimum="-255" Maximum="255" ValueChanged="BrightnesSlider_ValueChanged"/> <Label Content="Contrast:" /> <Slider x:Name="contrastSlider" Minimum="0" Maximum="200" ValueChanged="ContrastSlider_ValueChanged"/> <Label Content="Saturation:" /> <Slider x:Name="saturationSlider" Minimum="0" Maximum="200" ValueChanged="SaturationSlider_ValueChanged"/> </StackPanel> ``` 3. 编写事件处理器`ValueChanged`,在这个方法里,读取Slider的当前值,并使用Emgu CV的相关函数调整图像。这里假设你有一个`BitmapImage`对象`img`: ```csharp private void BrightnessSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { double brightnessValue = brightnessSlider.Value; // ... 调整亮度操作 } private void ContrastSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { double contrastValue = contrastSlider.Value; // ... 调整对比度操作 } private void SaturationSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { double saturationValue = saturationSlider.Value; // ... 调整饱和度操作 } // 调整函数示例(可能需要你自己实现) public void AdjustImage(BitmapImage img, int brightness, int contrast, int saturation) { Mat matImage = CvInvoke.Imread(img.UriSource.ToString()); // 使用Emgu CV的方法调整图像(例如Mat.CvtColor() for颜色转换,AddWeighted() for亮度对比度饱和度) // 然后保存调整后的图像为BitmapImage } ``` 请注意,以上代码仅提供了一个基础框架,具体的图像处理方法需要参考Emgu CV文档进行调整
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值