《Visual C++实践与提高数字图像处理与工程应用篇》第五章学习笔记.docx
- 文档编号:11197301
- 上传时间:2023-02-25
- 格式:DOCX
- 页数:29
- 大小:24.77KB
《Visual C++实践与提高数字图像处理与工程应用篇》第五章学习笔记.docx
《《Visual C++实践与提高数字图像处理与工程应用篇》第五章学习笔记.docx》由会员分享,可在线阅读,更多相关《《Visual C++实践与提高数字图像处理与工程应用篇》第五章学习笔记.docx(29页珍藏版)》请在冰豆网上搜索。
《VisualC++实践与提高数字图像处理与工程应用篇》第五章学习笔记
第五章图像的几何变换
数字图像平移
图像平移函数
/*************************************************************************
*函数名称:
Translation(LPSTRlpSrcStartBits,longlWidth,longlHeight,longlXOffset,
longlYOffset,longlLineBytes,longlDstLineBytes)
*函数参数:
*LPSTRlpSrcStartBits,指向源DIB起始像素的指针
*longlWidth,DIB图象的宽度
*longlHeight,DIB图象的高度
*longlXOffset,X方向偏移量
*longlYOffset,Y方向偏移量
*longlLineBytes,DIB图象的行字节数,为4的倍数
*longlDstLineBytes,临时DIB图象的行字节数,为4的倍数
*函数类型:
BOOL
*函数功能:
该函数用来平移DIB图象
************************************************************************/
BOOLTranslation(LPSTRlpSrcStartBits,longlWidth,longlHeight,
longlXOffset,longlYOffset,longlLineBytes,longlDstLineBytes)
{
longi;//行循环变量
longj;//列循环变量
LPSTRlpSrcDIBBits;//指向源像素的指针
LPSTRlpDstDIBBits;//指向临时图象对应像素的指针
LPSTRlpDstStartBits;//指向临时图象对应像素的指针
HLOCALhDstDIBBits;//临时图象句柄
hDstDIBBits=LocalAlloc(LHND,lWidth*lDstLineBytes);//分配临时内存
lpDstStartBits=(char*)LocalLock(hDstDIBBits);//锁定内存
if(hDstDIBBits==NULL)//判断是否内存分配
returnFALSE;//分配内存失败
for(i=0;i { for(j=0;j { lpDstDIBBits=(char*)lpDstStartBits+lLineBytes*(lHeight-1-i) +j;//指向新DIB第i行,第j个像素的指针 if((j-lYOffset>=0)&&(j-lYOffset (i-lXOffset>=0)&&(i-lXOffset { lpSrcDIBBits=(char*)lpSrcStartBits+lLineBytes*(lHeight-1- (i-lXOffset))+(j-lYOffset);//指向源DIB第i0行,第j0个像素的指针 *lpDstDIBBits=*lpSrcDIBBits;//复制像素 } else { *((unsignedchar*)lpDstDIBBits)=255;//源图中没有的像素,赋为255 } } } memcpy(lpSrcStartBits,lpDstStartBits,lLineBytes*lHeight);//复制图象 LocalUnlock(hDstDIBBits);//释放内存 LocalFree(hDstDIBBits); returnTRUE; } 该函数调用函数CDImagePorcessView视图类的 //图像平移 voidCDImageProcessView: : OnTranslation() { //TODO: Addyourcommandhandlercodehere CDImageProcessDoc*pDoc=GetDocument(); //////////////////////////////////////////////////////////////////////////////////////////////// longlSrcLineBytes;//图象每行的字节数 longlSrcWidth;//图象的宽度和高度 longlSrcHeight; LPSTRlpSrcDib;//指向源图象的指针 LPSTRlpSrcStartBits;//指向源像素的指针 longlDstLineBytes;//新图象每行的字节数 lpSrcDib=(LPSTR): : GlobalLock((HGLOBAL)pDoc->GetHObject());//锁定DIB if(pDoc->m_dib.GetColorNum(lpSrcDib)! =256)//判断是否是8-bpp位图 { AfxMessageBox("对不起,不是256色位图! ");//警告 : : GlobalUnlock((HGLOBAL)pDoc->GetHObject());//解除锁定 return;//返回 }//判断是否是8-bpp位图,不是则返回 lpSrcStartBits=pDoc->m_dib.GetBits(lpSrcDib);//找到DIB图象像素起始位置 lSrcWidth=pDoc->m_dib.GetWidth(lpSrcDib);//获取图象的宽度 lSrcHeight=pDoc->m_dib.GetHeight(lpSrcDib);//获取图象的高度 lSrcLineBytes=pDoc->m_dib.GetReqByteWidth(lSrcWidth*8);//计算图象每行的字节数 ///////////////////////////////////////////////////////////////////////////////////////////////// lDstLineBytes=pDoc->m_dib.GetReqByteWidth(lSrcHeight*8);//计算新图象每行的字节数 CDlgTranTranPara;//创建对话框 if(TranPara.DoModal()! =IDOK)//显示对话框,提示用户设定量 return; inttemver=TranPara.m_verOff; inttemhor=TranPara.m_horOff; if(Translation(lpSrcStartBits,lSrcWidth,lSrcHeight,//调用Translation()函数平移DIB temver,temhor,lSrcLineBytes,lDstLineBytes)) { pDoc->SetModifiedFlag(TRUE);//设置脏标记 pDoc->UpdateAllViews(NULL);//更新视图 : : GlobalUnlock((HGLOBAL)pDoc->GetHObject());//解除锁定 } else { AfxMessageBox(_T("分配内存失败! ")); }//警告 } 数字图像旋转 图像旋转函数 /************************************************************************* *函数名称: Rotate(LPSTRlpSrcDib,LPSTRlpSrcStartBits,longlWidth,longlHeight, longlLineBytes,WORDpalSize,longlDstWidth, longlDstHeight,longlDstLineBytes,floatfSina,floatfCosa) *函数参数: *LPSTRlpSrcDib,指向源DIB的指针 *LPSTRlpSrcStartBits,指向源DIB的起始像素的指针 *longlWidth,源DIB图象宽度 *longlHeight,源DIB图象高度 *longlLineBytes,源DIB图象字节宽度(4的倍数) *WORDpalSize,源DIB图象调色板大小 *longlDstWidth,目标图象宽度 *longlDstHeight,目标DIB图象高度 *longlDstLineBytes,目标DIB图象行字节数(4的倍数) *floatfSina,旋转角的余弦,说明: 为了避免两次求取正余弦,这里作为两个函数参数来用 *floatfCosa,旋转角的正弦 *函数类型: HGLOBAL *函数功能: 用来旋转DIB图象 ************************************************************************/ HGLOBALRotate(LPSTRlpSrcDib,LPSTRlpSrcStartBits,longlWidth,longlHeight, longlLineBytes,WORDpalSize,longlDstWidth, longlDstHeight,longlDstLineBytes,floatfSina,floatfCosa) { floatvarFloat1;//浮点参数变量1 floatvarFloat2;//浮点参数变量2 LPSTRlpDstDib;//指向临时图象的指针 longi;//行循环变量 longj;//列循环变量 longi1;//行循环变量 longj1;//列循环变量 LPSTRlpSrcDIBBits;//指向源像素的指针 LPSTRlpDstDIBBits;//指向临时图象对应像素的指针 LPSTRlpDstStartBits;//指向临时图象对应像素的指针 LPBITMAPINFOHEADERlpbmi;//指向BITMAPINFOHEADER结构的指针 varFloat1=(float)(-0.5*(lDstWidth-1)*fCosa-0.5*(lDstHeight-1)*fSina//将经常用到的两个常数事先求出,以便作为常数使用 +0.5*(lDstWidth-1)); varFloat2=(float)(0.5*(lDstWidth-1)*fSina-0.5*(lDstHeight-1)*fCosa +0.5*(lDstHeight-1)); HGLOBALhDIB=(HGLOBAL): : GlobalAlloc(GHND,lDstLineBytes*lDstHeight+*(LPDWORD)lpSrcDib+palSize);//分配内存,以保存新DIB if(hDIB==NULL)//判断是否是有效的DIB对象 { returnFALSE;//不是,则返回 } lpDstDib=(char*): : GlobalLock((HGLOBAL)hDIB);//锁定内存 memcpy(lpDstDib,lpSrcDib,*(LPDWORD)lpSrcDib+palSize);//复制DIB信息头和调色板 lpbmi=(LPBITMAPINFOHEADER)lpDstDib;//获取指针 lpbmi->biHeight=lDstHeight;//更新DIB中图象的高度和宽度 lpbmi->biWidth=lDstWidth; lpDstStartBits=lpDstDib+*(LPDWORD)lpDstDib +palSize;//求像素起始位置,作用如同: : FindDIBBits(gCo.lpSrcDib),这里尝试使用了这种方法,以避免对全局函数的调用 for(i=0;i { for(j=0;j { lpDstDIBBits=(char*)lpDstStartBits+lDstLineBytes*(lDstHeight-1-i)+j;//指向新DIB第i行,第j个像素的指针 i1=(long)(-((float)j)*fSina+((float)i)*fCosa+varFloat2+0.5);//计算该像素在源DIB中的坐标 j1=(long)(((float)j)*fCosa+((float)i)*fSina+varFloat1+0.5); if((j1>=0)&&(j1 {//判断是否在源图内 lpSrcDIBBits=(char*)lpSrcStartBits+lLineBytes*(lHeight-1-i1)+j1;//指向源DIB第i0行,第j0个像素的指针 *lpDstDIBBits=*lpSrcDIBBits;//复制像素 } else { *((unsignedchar*)lpDstDIBBits)=255;//源图中不存在的像素,赋为255 } } } returnhDIB; } 该函数调用函数CDImagePorcessView视图类的 //图像旋转 voidCDImageProcessView: : OnRotation() { //TODO: Addyourcommandhandlercodehere CDImageProcessDoc*pDoc=GetDocument(); //////////////////////////////////////////////////////////////////////////////////////////////// longlSrcLineBytes;//图象每行的字节数 longlSrcWidth;//图象的宽度和高度 longlSrcHeight; LPSTRlpSrcDib;//指向源图象的指针 LPSTRlpSrcStartBits;//指向源像素的指针 longlDstWidth;//临时图象的宽度和高度 longlDstHeight; lpSrcDib=(LPSTR): : GlobalLock((HGLOBAL)pDoc->GetHObject());//锁定DIB if(pDoc->m_dib.GetColorNum(lpSrcDib)! =256)//判断是否是8-bpp位图 { AfxMessageBox("对不起,不是256色位图! ");//警告 : : GlobalUnlock((HGLOBAL)pDoc->GetHObject());//解除锁定 return;//返回 }//判断是否是8-bpp位图,不是则返回 lpSrcStartBits=pDoc->m_dib.GetBits(lpSrcDib);//找到DIB图象像素起始位置 lSrcWidth=pDoc->m_dib.GetWidth(lpSrcDib);//获取图象的宽度 lSrcHeight=pDoc->m_dib.GetHeight(lpSrcDib);//获取图象的高度 lSrcLineBytes=pDoc->m_dib.GetReqByteWidth(lSrcWidth*8);//计算图象每行的字节数 longlDstLineBytes; ///////////////////////////////////////////////////////////////////////////////////////////////// CDlgRotRotPara;//创建对话框 if(RotPara.DoModal()! =IDOK)//显示对话框,设定旋转角度 { return; } DWORDpalSize=pDoc->m_dib.GetPalSize(lpSrcDib); floatfRotateAngle=(float)AngleToRadian(RotPara.m_rotAngle);//将旋转角度从度转换到弧度 floatfSina=(float)sin((double)fRotateAngle);//计算旋转角度的正余弦 floatfCosa=(float)cos((double)fRotateAngle); floatfSrcX1,fSrcY1,fSrcX2,fSrcY2,fSrcX3,fSrcY3,fSrcX4,fSrcY4;//旋转前四个角的坐标(以图象中心为坐标系原点) floatfDstX1,fDstY1,fDstX2,fDstY2,fDstX3,fDstY3,fDstX4,fDstY4;//旋转后四个角的坐标(以图象中心为坐标系原点) fSrcX1=(float)(-(lSrcWidth-1)/2);//计算原图的四个角的坐标 fSrcY1=(float)((lSrcHeight-1)/2); fSrcX2=(float)((lSrcWidth-1)/2); fSrcY2=(float)((lSrcHeight-1)/2); fSrcX3=(float)(-(lSrcWidth-1)/2); fSrcY3=(float)(-(lSrcHeight-1)/2); fSrcX4=(float)((lSrcWidth-1)/2); fSrcY4=(float)(-(lSrcHeight-1)/2); fDstX1=fCosa*fSrcX1+fSina*fSrcY1;//计算新图四个角的坐标 fDstY1=-fSina*fSrcX1+fCosa*fSrcY1; fDstX2=fCosa*fSrcX2+fSina*fSrcY2; fDstY2=-fSina*fSrcX2+fCosa*fSrcY2; fDstX3=fCosa*fSrcX3+fSina*fSrcY3; fDstY3=-fSina*fSrcX3+fCosa*fSrcY3; fDstX4=fCosa*fSrcX4+fSina*fSrcY4; fDstY4=-fSina*fSrcX4+fCosa*fSrcY4; lDstWidth=(long)(max(fabs(fDstX4-fDstX1),fabs(fDstX3-fDstX2))+0.5);//计算旋转后的图象实际宽度 lDstLineBytes=pDoc->m_dib.GetReqByteWidth(lDstWidth*8);//计算新图象每行的字节数 lDstHeight=(long)(max(fabs(fDstY4-fDstY1),fabs(fDstY3-fDstY2))+0.5);//计算旋转后的图象高度 HGLOBALhDstDIB=NULL;//创建新DIB hDstDIB=(HGLOBAL)Rotate(lpSrcDib,lpSrcStartBits,lSrcWidth,lSrcHeight,lSrcLineBytes, palSize,lDstWidth,lDstHeight,lDstLineBytes,fSina,fCosa);//调用Rotate()函数旋转DIB if(hDstDIB! =NULL)//判断旋转是否成功 { pDoc->UpdateObject(hDstDIB);//替换DIB,同时释放旧DIB对象 pDoc->SetDib();//更新DIB大小和调色板 pDoc->SetModifiedFlag(TRUE);//设置脏标记 pDoc->UpdateAllViews(NULL);//更新视图 : : GlobalUnlock((HGLOBAL)pDoc->GetHObject());//解除锁定 } else { AfxMessageBox(_T("分配内存失败! ")); }//警告 } 数字图像缩放 图像缩放函数 /************************************************************************* *函数名称: Zoom(LPSTRlpSrcDib,LPSTRlpSrcStartBits,longlWidth,longlHeight, longlLin
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Visual C+实践与提高数字图像处理与工程应用篇 Visual C+实践与提高数字图像处理与工程应用篇第五章