且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

《Visual C++数字图像模式识别技术详解(第2版)》一2.3 实践知识拓展

更新时间:2022-09-30 17:38:52

2.3 实践知识拓展

由于图像处理算法很多,如图像特效显示、图像变换、图像平滑、图像增强、图像分割等。这些算法都是本章所设计的ImageDib类所无法实现的。解决的方法有两个,一个是在ImageDib类中直接添加成员函数来实现这些算法,但这势必导致ImageDib类变得冗长和效率低下;另一个办法就是利用Visual C++提供的派生类来实现这些算法。
ImageDib类的派生类设计原则如下:让ImageDib类处理基本的图像处理功能。如图像读取、显示和存储。而将需要处理的算法定义为ImageDib类的派生类。由于派生类对ImageDib基类中的保护或公有成员可以直接使用,不需要声明,因此,在派生类中仅仅定义各种处理图像数据的函数即可。这样可使不同处理功能归结在不同的ImageDib派生类中,结构简洁。
ImageDib类的派生类具有如下功能:
1)由于该类是从ImageDib类派生而来的,因此具有ImageDib类的所有功能。
2)ImageDib类的派生类又扩充了一些功能,这些功能随图像处理算法的不同而不同。在编程中需要将图像处理算法函数写在该类中。每个处理算法编写成从ImageDib类派生出的类的函数,因此,函数中可以直接使用ImageDib类中的变量和函数,不必加以声明和定义。
例如:定义ImageDib基类的图像反色变换派生类ImageTransform如下:

class ImageTransform:public ImageDib
{
       public: 
            unsigned char * m_pImgDataOut;            //存储图像处理后数据
            ImageTransform();
            ~ImageTransform();
            Void Transform();                        //图像反色变换 
};

而图像反色变换处理实现函数如下:

ImageTransform::Transform()
{
      m_nBitCount;
      m_imgWidth;
      m_imgHeight;
      //每行像素占字节数,必须为4的倍数
      int lineByte=(m_imgWidth*m_nBitCount/8+3)/4*4;
      //申请空间,存放变换后结果
      m_pImgDataOut=new unsigned char[lineByte*m_imgHeight];
      //循环变量,图像的坐标
      int i,j;
      //每像素占字节数
      int pixelByte=m_nBitCount/8;
      //循环变量,遍历每个像素的每个分量,比如彩色图像的3个分量
      int k;
      //求反转
      for(i=0;i<m_imgHeight;i++){
            for(j=0;j<m_imgWidth;j++){
                  for(k=0;k<pixelByte;k++)
                        *(m_pImgDataOut+i*lineByte+j*pixelByte+k)
                        =255-*(m_pImgData+i*lineByte+j*pixelByte+k);
            }
      }
}

在此函数中,待处理的图像数据及其图像属性完全来自于基类ImageDib,即基类中指向图像数据区的指针m_pImgData、图像宽m_imgWidth、图像高m_imgHeight和每像素所占位数m_nBitCount。而派生类ImageTransform则仅实现具体图像处理算法Transform(),并把处理结果存入指针变量m_pImgDataOut所指的存储区中。这样,不论基类ImageDib加载的是什么样的图像,派生类ImageTransform都可以顺利实现自己的图像处理功能。