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

上传人:b****1 文档编号:15052486 上传时间:2023-06-30 格式:DOCX 页数:45 大小:4.66MB
下载 相关 举报
mfc空间几何变换之图像平移镜像旋转缩放详解.docx_第1页
第1页 / 共45页
mfc空间几何变换之图像平移镜像旋转缩放详解.docx_第2页
第2页 / 共45页
mfc空间几何变换之图像平移镜像旋转缩放详解.docx_第3页
第3页 / 共45页
mfc空间几何变换之图像平移镜像旋转缩放详解.docx_第4页
第4页 / 共45页
mfc空间几何变换之图像平移镜像旋转缩放详解.docx_第5页
第5页 / 共45页
mfc空间几何变换之图像平移镜像旋转缩放详解.docx_第6页
第6页 / 共45页
mfc空间几何变换之图像平移镜像旋转缩放详解.docx_第7页
第7页 / 共45页
mfc空间几何变换之图像平移镜像旋转缩放详解.docx_第8页
第8页 / 共45页
mfc空间几何变换之图像平移镜像旋转缩放详解.docx_第9页
第9页 / 共45页
mfc空间几何变换之图像平移镜像旋转缩放详解.docx_第10页
第10页 / 共45页
mfc空间几何变换之图像平移镜像旋转缩放详解.docx_第11页
第11页 / 共45页
mfc空间几何变换之图像平移镜像旋转缩放详解.docx_第12页
第12页 / 共45页
mfc空间几何变换之图像平移镜像旋转缩放详解.docx_第13页
第13页 / 共45页
mfc空间几何变换之图像平移镜像旋转缩放详解.docx_第14页
第14页 / 共45页
mfc空间几何变换之图像平移镜像旋转缩放详解.docx_第15页
第15页 / 共45页
mfc空间几何变换之图像平移镜像旋转缩放详解.docx_第16页
第16页 / 共45页
mfc空间几何变换之图像平移镜像旋转缩放详解.docx_第17页
第17页 / 共45页
mfc空间几何变换之图像平移镜像旋转缩放详解.docx_第18页
第18页 / 共45页
mfc空间几何变换之图像平移镜像旋转缩放详解.docx_第19页
第19页 / 共45页
mfc空间几何变换之图像平移镜像旋转缩放详解.docx_第20页
第20页 / 共45页
亲,该文档总共45页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

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

《mfc空间几何变换之图像平移镜像旋转缩放详解.docx》由会员分享,可在线阅读,更多相关《mfc空间几何变换之图像平移镜像旋转缩放详解.docx(45页珍藏版)》请在冰点文库上搜索。

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

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

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

          if(i

          elseif(i>=Place&&countWidth

             ImageSize[i]=black; countWidth++; continue;

          }

          elseif(i>=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] viewplain copy

1./********************************************************/  

2./* 图像空间几何变换:

图像平移 ID_JHBH_PY(几何变换-平移)  

3./* 使用平移对话框:

CImagePYDlg dlg                      

4./* 算法:

f(x,y)=f(x+x0,y+y0)图像所有点平移,空的补黑'0'  

5./* 注意该图像平移方法只是从左上角(0,0)处开始平移         

6./* 其他方向原理相同 自己去实现                            

7./********************************************************/  

8.  

9.void CImageProcessingView:

:

OnJhbhPy()   

10.{  

11.    if(numPicture==0) {  

12.        AfxMessageBox("载入图片后才能空间平移!

",MB_OK,0);  

13.        return;  

14.    }  

15.    //定义采样对话框也是用来空间变换平移的坐标  

16.    CImagePYDlg dlg;       

17.    if( dlg.DoModal()==IDOK ) //显示对话框  

18.    {  

19.        //采样坐标最初为图片的自身像素  

20.        if( dlg.m_xPY>m_nWidth || dlg.m_yPY>m_nHeight ) {  

21.            AfxMessageBox("图片平移不能为超过原图长宽!

",MB_OK,0);  

22.            return;  

23.        }  

24.        AfxMessageBox("图片空间变换-平移!

",MB_OK,0);  

25.  

26.        //打开临时的图片 读写文件  

27.        FILE *fpo = fopen(BmpName,"rb");  

28.        FILE *fpw = fopen(BmpNameLin,"wb+");  

29.        fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);  

30.        fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);  

31.        fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);  

32.        fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);  

33.        fread(m_pImage,m_nImage,1,fpo);  

34.  

35.        /************************************************************/  

36.        /* 图片空间变换-平移                                         

37.        /* 坐标(dlg.m_xPY,dlg.m_yPY)表示图像平移的坐标         

38.        /* 先用Plave计算出平移后的起始坐标,其他的坐标赋值为'0'黑色  

39.        /* 然后依次平移坐标,空的赋为黑色,否则填充                  

40.        /************************************************************/  

41.          

42.        /******************************************************************/  

43.        /* 严重错误1:

数组变量赋值相等                                     

44.        /* 在View.h中定义变量 BYTE *m_pImage 读入图片数据后的指针          

45.        /* 建立临时变量数组,让它平移变换 unsigned char *ImageSize          

46.        /* ImageSize=m_pImage(错误)                                        

47.        /* 会导致ImageSize赋值变换时m_pImage也产生了变换,所以输出全为黑色  

48.        /*     因为它俩指向了相同的数组地址                                

49.        /* 解决方法:

使用下面C++的new方法动态分配或for循环i=m_nImage赋值   

50.        /******************************************************************/  

51.  

52.        /*临时变量存储的像素与m_pImage相同,便于处理图像*/  

53.        unsigned char *ImageSize;        

54.        ImageSize=new unsigned char[m_nImage];  //new和delete有效的进行动态存的分配和释放  

55.  

56.        int Place;                    //建立临时坐标 记录起始坐标(0,0)平移过来的位置  

57.        int m_pImagePlace;            //原始图像平移为(0,0) 图像把它平移到Place位置  

58.        unsigned char black;          //填充黑色='0'   

59.  

60.        /************************************************************/  

61.        /* for(int i=0 ; i

62.        /* for(int j=0 ; j

63.        /* 不能使用的上面的因为可能图像的最后一行没有完整的一行像素  

64.        /* 这样会出现exe报错,使用m_nImage读写所有像素比较正确        

65.        /************************************************************/  

66.  

67.        Place=dlg.m_yPY*m_nWidth*3;   //前m_yPY行都要填充为黑色            

68.        black=0;                       //颜色为黑色  

69.        m_pImagePlace=0;               //图像处事位置为(0,0),把该点像素平移过去   

70.        int countWidth=0;              //记录每行的像素个数,满行时变回0  

71.        int number=0;                  //数字记录使用的像素行数,平移时使用  

72.  

73.        for(int i=0 ; i

74.        {  

75.            /*如果每行的像素填满时清为0*/  

76.            if(countWidth==m_nWidth*3) {  

77.                countWidth=0;  

78.            }  

79.              

80.            /*第一部分:

到平移后像素位置前面的所有像素点赋值为黑色*/  

81.            if(i

82.                ImageSize[i]=black;     //赋值为黑色  

83.                continue;  

84.            }  

85.              

86.            /*第二部分:

平移区域的左边部分赋值为黑色*/  

87.            else if(i>=Place && countWidth

88.                ImageSize[i]=black;     //赋值为黑色  

89.                countWidth++;  

90.                continue;  

91.            }  

92.      

93.            /****************************/  

94.            /* 各部分如图所示:

           

95.            /* 000000000000000000000000  

96.            /* 000000000000000000000000  

97.            /* 0000000.................  

98.            /* 0000000................. 

99.            /* 0000000.................  

100.            /* 0000000................. 

101.            /* 点表示像素部分,0为黑色    

102.            /****************************/  

103.  

104.            /* 重点错误提示:

由于bmp图像显示是从左下角开始存储(0,0)点所以输出图像为 */  

105.            /* bmp图像是从左下角到右上角排列的 */  

106.  

107.            /****************************/  

108.            /* 各部分如图所示:

           

109.            /* 0000000.................  

110.            /* 0000000.................  

111.            /* 0000000................. 

112.            /* 0000000.................  

113.            /* 000000000000000000000000  

114.            /* 000000000000000000000000  

115.            /* 点表示像素部分,0为黑色    

116.            /****************************/  

117.          

118.            /*第三部分:

图像像素平移区域*/  

119.            else if(i>=Place && countWidth>=dlg.m_xPY*3)  

120.            {  

121.                ImageSize[i]=m_pImage[m_pImagePlace];       

122.                m_pImagePlace++;  

123.                countWidth++;  

124.                if(countWidth==m_nWidth*3)  

125.                {  

126.                    number++;  

127.                    m_pImagePlace=number*m_nWidth*3;  

128.                }  

129.            }  

130.        }  

131.          

132.        fwrite(ImageSize,m_nImage,1,fpw);    

133.        fclose(fpo);  

134.        fclose(fpw);  

135.        numPicture = 2;  

136.        level=200;        //200表示几何变换  

137.        Invalidate();  

138.    }     

139.}  

    同时在ShowBitmap中添加level标记重新绘制图片,代码如下:

[cpp] viewplain copy

1.else        //图像几何变换  

2.if(level=200)  

3.{  

4.    m_hBitmapChange = (HBITMAP) LoadImage(NULL,BmpNameLin,IMAGE_BITMAP,0,0,  

5.        LR_LOADFROMFILE|LR_DEFAULTSIZE|LR_CREATEDIBSECTION);  

6.}  

    运行时需要注意一点:

BMP图像在处理过程中可能会出现一些斜线,而平移(40,60)位移量时可能出现如下。

他是因为BMP格式有个非常重要的规定,要求每一扫描的字节数据必须能被4整除,也就是Dword对齐(长度4字节),如果图像的一行字节数不能被4整除,就需要在每行末尾不起0达到标准。

    例如一行像素为97字节,我们就需要补3个字节吗,数值可以是0,但是我们在BMP格式的信息头里说明了其宽度,所以补齐后对我们没有影响,所以后面补若干个字节的0即可直到被4整除。

 

    通过后面的图像缩放后,我从学做了一遍这个补齐的缩放。

代码如下,能够实现完美平移。

nice啊~

[cpp] viewplain copy 

1.void CImageProcessingView:

:

OnJhbhPy()   

2.{  

3.    if(numPicture==0) {  

4.        AfxMessageBox("载入图片后才能空间平移!

",MB_OK,0);  

5.        return;  

6.    }  

7.    //定义采样对话框也是用来空间变换平移的坐标  

8.    CImagePYDlg dlg;       

9.    if( dlg.DoModal()==IDOK ) //显示对话框  

10.    {  

11.        //采样坐标最初为图片的自身像素  

12.        if( dlg.m_xPY>m_nWidth || dlg.m_yPY>m_nHeight ) {  

13.            AfxMessageBox("图片平移不能为超过原图长宽!

",MB_OK,0);  

14.            return;  

15.        }  

16.        AfxMessageBox("图片空间变换-平移!

",MB_OK,0);  

17.  

18.        //打开临时的图片 读写文件  

19.        FILE *fpo = fopen(BmpName,"rb");  

20.        FILE *fpw = fopen(BmpNameLin,"wb+");  

21.        fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);  

22.        fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);  

23.  

24.        int num;            //记录每行多余的图像素数个数  

25.        int sfSize;         //补齐后的图像大小  

26.        //重点:

图像的每行像素都必须是4的倍数:

1*1的图像为 r g b 00H   

27.        if(m_nWidth*3%4!

=0)  

28.        {  

29.            num=(4-m_nWidth*3%4);  

30.            sfSize=(m_nWidth*3+num)*m_nHeight; //每行多number个  

31.        }  

32.        else  

33.        {  

34.            num=0;  

35.            sfSize=m_nWidth*m_nHeight*3;  

36.        }  

37.        //注意:

假如最后一行像素不足,我默认处理为完整的一行,不足补00H  

38.        //总之处理后的图像总是m*n且为4倍数,每行都完整存在  

39.  

40.        /*更改文件头信息 定义临时文件头结构变量*/  

41.        

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 法律文书

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2