为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

mfc空间几何变换之图像平移、镜像、旋转、缩放详解

2021-11-07 5页 doc 4MB 78阅读

用户头像 个人认证

ysdg83

从事建筑公司质量、技术

举报
mfc空间几何变换之图像平移、镜像、旋转、缩放详解-.--可修编.HYPERLINK"http://blog.csdn.net/eastmount/article/details/46345299"MFC空间几何变换之图像平移、镜像、旋转、缩放详解一.图像平移    前一篇文章讲述了图像点运算(基于像素的图像变换),这篇文章讲述的是图像几何变换:在不改变图像容的情况下对图像像素进行空间几何变换的处理方式。     点运算对单幅图像做处理,不改变像素的空间位置;代数运算对多幅图像做处理,也不改变像素的空间位置;几何运算对单幅图像做处理,改变像素的空间位置,几何运算包括两个...
mfc空间几何变换之图像平移、镜像、旋转、缩放详解
-.--可修编.HYPERLINK"http://blog.csdn.net/eastmount/article/details/46345299"MFC空间几何变换之图像平移、镜像、旋转、缩放详解一.图像平移    前一篇文章讲述了图像点运算(基于像素的图像变换),这篇文章讲述的是图像几何变换:在不改变图像容的情况下对图像像素进行空间几何变换的处理方式。     点运算对单幅图像做处理,不改变像素的空间位置;代数运算对多幅图像做处理,也不改变像素的空间位置;几何运算对单幅图像做处理,改变像素的空间位置,几何运算包括两个独立的算法:空间变换算法和灰度级插值算法。    空间变换操作包括简单空间变换、多项式卷绕和几何校正、控制栅格插值和图像卷绕,这里主要讲述简单的空间变换,如图像平移、镜像、缩放和旋转。主要是通过线性代数中的齐次坐标变换。    图像平移坐标变换如下:    运行效果如下图所示,其中BMP图片(0,0)像素点为左下角。    其代码核心算法:    1.在对话框中输入平移坐标(x,y)m_xPY=x,m_yPY=y    2.定义Place=dlg.m_yPY*m_nWidth*3示当前m_yPY行需要填充为黑色    3.新建一个像素矩阵 ImageSize=newunsignedchar[m_nImage]    4.循环整个像素矩阵处理        for(inti=0;i=Place&&countWidth=Place&&countWidth>=dlg.m_xPY*3){//图像像素平移区域             ImageSize[i]=m_pImage[m_pImagePlace];//原(0,0)像素赋值过去             m_pImagePlace++; countWidth++;             if(countWidth==m_nWidth*3){ //一行填满 m_pImagePlace走到(0,1)                number++; m_pImagePlace=number*m_nWidth*3;            }          }       }     5.写文件绘图fwrite(ImageSize,m_nImage,1,fpw)    第一步:在ResourceView资源视图中,添加Menu子菜单如下:(注意ID号)    第二步:设置平移对话框。将试图切换到ResourceView界面--选中Dialog,右键鼠标新建一个Dialog,并新建一个名为IDD_DIALOG_PY。编辑框(X)IDC_EDIT_PYX和(Y)IDC_EDIT_PYY,确定为默认按钮。设置成下图对话框:    第三步:在对话框资源模板空白区域双击鼠标—Createanewclass创建一个新类--命名为CImagePYDlg。会自动生成它的.h和.cpp文件。打开类向导(CtrlW),选择类名:CImagePYDlg添加成员变量如下图所示,同时在MessageMaps中生成ID_JHBH_PY实现函数。     第四步:在CImageProcessingView.cpp中添加头文件#include"ImagePYDlg.h",并实现平移。[cpp] HYPERLINK"http://blog.csdn.net/eastmount/article/details/46345299"\o"viewplain"viewplain HYPERLINK"http://blog.csdn.net/eastmount/article/details/46345299"\o"copy"copy/********************************************************/  /* 图像空间几何变换:图像平移 ID_JHBH_PY(几何变换-平移)  /* 使用平移对话框:CImagePYDlg dlg                      /* 算法:f(x,y)=f(x+x0,y+y0)图像所有点平移,空的补黑'0'  /* 注意该图像平移方法只是从左上角(0,0)处开始平移         /* 其他方向原理相同 自己去实现                            /********************************************************/    void CImageProcessingView::OnJhbhPy()   {      if(numPicture==0) {          AfxMessageBox("载入图片后才能空间平移!",MB_OK,0);          return;      }      //定义采样对话框也是用来空间变换平移的坐标      CImagePYDlg dlg;           if( dlg.DoModal()==IDOK ) //显示对话框      {          //采样坐标最初为图片的自身像素          if( dlg.m_xPY>m_nWidth || dlg.m_yPY>m_nHeight ) {              AfxMessageBox("图片平移不能为超过原图长宽!",MB_OK,0);              return;          }          AfxMessageBox("图片空间变换-平移!",MB_OK,0);            //打开临时的图片 读写文件          FILE *fpo = fopen(BmpName,"rb");          FILE *fpw = fopen(BmpNameLin,"wb+");          fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);          fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);          fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);          fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);          fread(m_pImage,m_nImage,1,fpo);            /************************************************************/          /* 图片空间变换-平移                                                 /* 坐标(dlg.m_xPY,dlg.m_yPY)表示图像平移的坐标                 /* 先用Plave计算出平移后的起始坐标,其他的坐标赋值为'0'黑色          /* 然后依次平移坐标,空的赋为黑色,否则填充                          /************************************************************/                    /******************************************************************/          /* 严重错误1:数组变量赋值相等                                             /* 在View.h中定义变量 BYTE *m_pImage 读入图片数据后的指针                  /* 建立临时变量数组,让它平移变换 unsigned char *ImageSize                  /* ImageSize=m_pImage(错误)                                                /* 会导致ImageSize赋值变换时m_pImage也产生了变换,所以输出全为黑色          /*     因为它俩指向了相同的数组地址                                        /* 解决方法:使用下面C++的new方法动态分配或for循环i=m_nImage赋值           /******************************************************************/            /*临时变量存储的像素与m_pImage相同,便于处理图像*/          unsigned char *ImageSize;                ImageSize=new unsigned char[m_nImage];  //new和delete有效的进行动态存的分配和释放            int Place;                    //建立临时坐标 记录起始坐标(0,0)平移过来的位置          int m_pImagePlace;            //原始图像平移为(0,0) 图像把它平移到Place位置          unsigned char black;          //填充黑色='0'             /************************************************************/          /* for(int i=0 ; i=Place && countWidth=Place && countWidth>=dlg.m_xPY*3)              {                  ImageSize[i]=m_pImage[m_pImagePlace];                       m_pImagePlace++;                  countWidth++;                  if(countWidth==m_nWidth*3)                  {                      number++;                      m_pImagePlace=number*m_nWidth*3;                  }              }          }                    fwrite(ImageSize,m_nImage,1,fpw);            fclose(fpo);          fclose(fpw);          numPicture = 2;          level=200;        //200表示几何变换          Invalidate();      }     }      同时在ShowBitmap中添加level标记重新绘制图片,代码如下:[cpp] HYPERLINK"http://blog.csdn.net/eastmount/article/details/46345299"\o"viewplain"viewplain HYPERLINK"http://blog.csdn.net/eastmount/article/details/46345299"\o"copy"copyelse        //图像几何变换  if(level=200)  {      m_hBitmapChange = (HBITMAP) LoadImage(NULL,BmpNameLin,IMAGE_BITMAP,0,0,          LR_LOADFROMFILE|LR_DEFAULTSIZE|LR_CREATEDIBSECTION);  }      运行时需要注意一点:BMP图像在处理过程中可能会出现一些斜线,而平移(40,60)位移量时可能出现如下。他是因为BMP有个非常重要的规定,要求每一扫描的字节数据必须能被4整除,也就是Dword对齐(长度4字节),如果图像的一行字节数不能被4整除,就需要在每行末尾不起0达到。    例如一行像素为97字节,我们就需要补3个字节吗,数值可以是0,但是我们在BMP格式的信息头里说明了其宽度,所以补齐后对我们没有影响,所以后面补若干个字节的0即可直到被4整除。     通过后面的图像缩放后,我从学做了一遍这个补齐的缩放。代码如下,能够实现完美平移。nice啊~[cpp] HYPERLINK"http://blog.csdn.net/eastmount/article/details/46345299"\o"viewplain"viewplain HYPERLINK"http://blog.csdn.net/eastmount/article/details/46345299"\o"copy"copy void CImageProcessingView::OnJhbhPy()   {      if(numPicture==0) {          AfxMessageBox("载入图片后才能空间平移!",MB_OK,0);          return;      }      //定义采样对话框也是用来空间变换平移的坐标      CImagePYDlg dlg;           if( dlg.DoModal()==IDOK ) //显示对话框      {          //采样坐标最初为图片的自身像素          if( dlg.m_xPY>m_nWidth || dlg.m_yPY>m_nHeight ) {              AfxMessageBox("图片平移不能为超过原图长宽!",MB_OK,0);              return;          }          AfxMessageBox("图片空间变换-平移!",MB_OK,0);            //打开临时的图片 读写文件          FILE *fpo = fopen(BmpName,"rb");          FILE *fpw = fopen(BmpNameLin,"wb+");          fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);          fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);            int num;            //记录每行多余的图像素数个数          int sfSize;         //补齐后的图像大小          //重点:图像的每行像素都必须是4的倍数:1*1的图像为 r g b 00H           if(m_nWidth*3%4!=0)          {              num=(4-m_nWidth*3%4);              sfSize=(m_nWidth*3+num)*m_nHeight; //每行多number个          }          else          {              num=0;              sfSize=m_nWidth*m_nHeight*3;          }          //注意:假如最后一行像素不足,我默认处理为完整的一行,不足补00H          //总之处理后的图像总是m*n且为4倍数,每行都完整存在            /*更改文件头信息 定义临时文件头结构变量*/          BITMAPFILEHEADER bfhsf;          BITMAPINFOHEADER bihsf;                 bfhsf=bfh;          bihsf=bih;          bfhsf.bfSize=sfSize+54;               fwrite(&bfhsf,sizeof(BITMAPFILEHEADER),1,fpw);          fwrite(&bihsf,sizeof(BITMAPINFOHEADER),1,fpw);          fread(m_pImage,m_nImage,1,fpo);            CString str;          str.Format("补齐=%d",num);          AfxMessageBox(str);            /*临时变量存储的像素与sfSize相同 new和delete有效的进行动态存的分配和释放*/          unsigned char *ImageSize;                ImageSize=new unsigned char[sfSize];              int Place;                    //建立临时坐标 记录起始坐标(0,0)平移过来的位置            int m_pImagePlace;            //原始图像平移为(0,0) 图像把它平移到Place位置            unsigned char black=0;        //填充黑色='0'            unsigned char other=0;        //补码00H='\0'            Place=dlg.m_yPY*(m_nWidth*3+num); //前m_yPY行都要填充为黑色                    m_pImagePlace=0;                  //图像处事位置为(0,0),把该点像素平移过去           int countWidth=0;                 //记录每行的像素个数,满行时变回0          int number=0;                     //数字记录使用的像素行数,平移时使用            for(int i=0 ; i=Place && countWidth=Place && countWidth>=dlg.m_xPY*3)                {                    ImageSize[i]=m_pImage[m_pImagePlace];                         m_pImagePlace++;                    countWidth++;                    if(countWidth==m_nWidth*3)                    {                        if(num==0)                      {                          countWidth=0;                          number++;                            m_pImagePlace=number*m_nWidth*3;                       }                      else //num为补0                      {                          for(int j=0;j
类似补齐即可。二.图像镜像1.水平镜像翻转    其变换矩阵如下:                 X=width-X0-1 (width为图像宽度)                 Y=Y0    打开类向导,在CImageProcessingView中添加IDs为ID_JHBH_FZ,生成函数,代码如下:[cpp] HYPERLINK"http://blog.csdn.net/eastmount/article/details/46345299"\o"viewplain"viewplain HYPERLINK"http://blog.csdn.net/eastmount/article/details/46345299"\o"copy"copy /* 几何变换 图像翻转:自己对这个功能比较感兴趣,做个图像反转 */  void CImageProcessingView::OnJhbhFz()   {      if(numPicture==0) {          AfxMessageBox("载入图片后才能空间反转!",MB_OK,0);          return;      }      AfxMessageBox("图片空间变换-反转图像!",MB_OK,0);        //打开临时的图片      FILE *fpo = fopen(BmpName,"rb");      FILE *fpw = fopen(BmpNameLin,"wb+");      fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);      fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);      fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);      fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);      fread(m_pImage,m_nImage,1,fpo);            /*new和delete有效的进行动态存的分配和释放*/      unsigned char *ImageSize;            ImageSize=new unsigned char[m_nImage];          int countWidth=0;        //记录每行的像素个数,满行时变回0      int Place;               //记录图像每行的位置,便于图像反转      int number=0;            //数字记录使用的像素行数      Place=m_nWidth*3-1;        //翻转矩阵: y=y0 x=width-x0-1      for(int i=0 ; i=0 && XPlace<=m_nWidth) && (YPlace>=0 && YPlace<=m_nHeight) )              {                  Place=YPlace*m_nWidth*3+XPlace*3;                  //在图像围赋值为该像素                  if(Place+2
/
本文档为【mfc空间几何变换之图像平移、镜像、旋转、缩放详解】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索