科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件基于VC.NET的GDI+ 编程之CImage

基于VC.NET的GDI+ 编程之CImage

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

CImage是MFC和ATL共享的新类,它能从外部磁盘中调入一个JPEG、GIF、BMP和PNG格式的图像文件加以显示

作者:adding 来源:yesky 2007年11月16日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
柔化和锐化处理

  在图像处理中,我们通常用一些数学手段,对图像进行除去噪声、强调或抽取轮廓特征等图像空间的变换。所谓"图像空间的变换"是借助于一个称之为模板的局部像素域来完成的,不同的模板具有不同的图像效果。

  1. 柔化

  图像的柔化是除去图像中点状噪声的一个有效方法。所谓柔化,是指使图像上任何一个像素与其相邻像素的颜色值的大小不会出现陡突的一种处理方法。设在一个3 x 3的模板中其系数为:



  中间有底纹的表示中心元素,即用那个元素作为处理后的元素。很明显,上述模板(称之为Box模板)是将图像上每个像素用它近旁(包括它本身)的9个像素的平均值取代。这样处理的结果在除噪的同时,也降低图像的对比度,使图像的轮廓模糊。为了避免这一缺陷,我们对各点引入加权系数,将原来的模板改为:



  新的模板可一方面除去点状噪声,同时能较好地保留原图像的对比度,因此该模板得到了广泛的应用。由于这个模板是通过二维高斯(Gauss)函数得到的,故称为高斯模板。

  2. 锐化

  锐化和柔化恰恰相反,它通过增强高频分量减少图像中的模糊,因此又称为高通滤波。锐化处理在增强图像边缘效果的同时增加了图像的噪声。常用的锐化模板是拉普拉斯模板:



  用此模板处理后的图像,轮廓线条将明显得到增强。轮廓线以外的部分将变得较暗,而轮廓线部分将变得比较明亮。

  使用程序对模板进行运算时,要考虑到溢出点的处理。所谓溢出点,指的是大于255或小于0的点。处理时,可令大于255的点取255,而小于0的点取其正值。

  3. 实现代码

  实现柔化和锐化时,我们先调用CImage::GetPixel来依次读取相应的像素,然后用柔化和锐化模板进行处理,最后调用CImage::SetPixel函数将处理后的像素写回到CImage对象中。具体的代码如下:

void FilterImage(CImage* image, int nType)
{
 if (image->IsNull())
  return;
 int smoothGauss[9] = {1,2,1,2,4,2,1,2,1}; // 高斯模板
 int sharpLaplacian[9] = {-1,-1,-1,-1,9,-1,-1,-1,-1}; // 拉普拉斯模板

 int opTemp[9];
 float aver; // 系数
 if ( nType > 1) nType = 0;
 switch( nType ){
  case 0: // 高斯模板
   aver = (float)(1.0/16.0);
   memcpy( opTemp, smoothGauss, 9*sizeof(int));
   break;
  case 1: // 拉普拉斯模板
   aver = 1.0;
   memcpy( opTemp, sharpLaplacian, 9*sizeof(int));
   break;
 }

 int i,j;

 int nWidth = image->GetWidth();
 int nHeight = image->GetHeight();

 for (i = 1; i < nWidth-1; i++){
  for (j = 1; j < nHeight-1; j++){

   int rr = 0, gg = 0, bb = 0;
   int index = 0;

   for (int col = -1; col <= 1; col++){
    for (int row = -1; row <= 1; row++){
     COLORREF clr = image->GetPixel( i+row, j+col);
     rr += GetRValue(clr) * opTemp[index];
     gg += GetGValue(clr) * opTemp[index];
     bb += GetBValue(clr) * opTemp[index];
     index++;
    }
   }
  
   rr = (int)(rr*aver);
   gg = (int)(gg*aver);
   bb = (int)(bb*aver);

   // 处理溢出点
  if ( rr > 255 ) rr = 255;
  else if ( rr < 0 ) rr = -rr;
  if ( gg > 255 ) gg = 255;
  else if ( gg < 0 ) gg = -gg;
  if ( bb > 255 ) bb = 255;
  else if ( bb < 0 ) bb = -bb;

  // 错位重写以避免前一个像素被新的像素覆盖
  image->SetPixel( i-1, j-1, RGB(rr,gg,bb));
  }
 }
}

图7.22是使用上述代码将某个图像处理后的结果。


    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章