当前位置:文档之家› 常用图像处理算法

常用图像处理算法

8种常用图像处理算法(函数)------以下所有函数均放在p下1.图像镜像void CCimageProcessingView::OnGeomTrpo(){//获取指向文档的指针CCimageProcessingDoc* pDoc = GetDocument();//指向DIB的指针LPSTR lpDIB;//锁定DIBlpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());//设置光标状态为等待状态BeginWaitCursor();//调用VertMirror函数镜像图象if (VertMirror(lpDIB)){//设置文档修改标记pDoc->SetModifiedFlag(TRUE);//更新所有视图pDoc->UpdateAllViews(NULL);}else{//提示信息MessageBox("实现图象镜像失败!");}//解除锁定::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());//结束光标等待状态EndWaitCursor();}* 函数名称:** VertMirror()** 参数:** LPSTR lpDIB //指向源DIB图像指针** 返回值:** BOOL //镜像成功返回TRUE,否则返回FALSE。

** 说明:** 该函数用来实现DIB图像的垂直镜像。

*BOOL WINAPI VertMirror(LPSTR lpDIB){//原图象宽度LONG lWidth;//原图象高度LONG lHeight;//原图象的颜色数WORD wNumColors;//原图象的信息头结构指针LPBITMAPINFOHEADER lpbmi;//指向原图象和目的图象的像素的指针LPBYTE lpSrc,lpDst;//平移后剩余图像在源图像中的位置(矩形区域)CRect rectSrc;//指向原图像像素的指针LPBYTE lpDIBBits;//指向复制图像像素的指针LPBYTE lpNewDIBBits;//内存句柄HLOCAL h;//循环变量LONG i;//图像每行的字节数LONG lLineBytes;//获取图象的信息头结构的指针lpbmi=(LPBITMAPINFOHEADER)lpDIB;//找到图象的像素位置lpDIBBits=(LPBYTE)::FindDIBBits(lpDIB);//获取图象的宽度lWidth=::DIBWidth(lpDIB);//获取图象的高度lHeight=::DIBHeight(lpDIB);//获取图象的颜色数wNumColors=::DIBNumColors(lpDIB);//计算图像每行的字节数lLineBytes = WIDTHBYTES(lWidth *(lpbmi->biBitCount)); // 暂时分配内存,以保存新图像h= LocalAlloc(LHND, lLineBytes);// 分配内存失败,直接返回if (!h)return FALSE;// 锁定内存lpNewDIBBits = (LPBYTE)LocalLock(h);//如果是256色位图或真彩色位图if(wNumColors==256||wNumColors==0){//平移图像,每次移动一行for(i = 0; i<lHeight/2; i++){//指向原图象倒数第i行像素起点的指针lpSrc =(LPBYTE)lpDIBBits + lLineBytes * i;//目标区域同样要注意上下倒置的问题lpDst =(LPBYTE)lpDIBBits+lLineBytes * (lHeight-i-1) ;//备份一行memcpy(lpNewDIBBits, lpDst, lLineBytes);//将倒数第i行像素复制到第i行memcpy(lpDst, lpSrc, lLineBytes);//将第i行像素复制到第i行memcpy(lpSrc, lpNewDIBBits, lLineBytes);}}else{AfxMessageBox("只支持256色和真彩色位图");// 释放内存LocalUnlock(h);LocalFree(h);return false;}// 释放内存LocalUnlock(h);LocalFree(h);// 返回return TRUE;}2.旋转图像(含对话框这里对话框需要自己建立)void CCimageProcessingView::OnGeomRota(){//获取指向文档的指针CCimageProcessingDoc* pDoc = GetDocument();//指向DIB的指针LPSTR lpDIB;//锁定DIBlpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());// 缩放比率int iRotaAngle;// 创建对话框CDlgGeoRota dlgPara;// 初始化变量值dlgPara.m_iRotaAngle = 90;// 显示对话框,提示用户设定旋转角度if (dlgPara.DoModal() != IDOK){// 返回return;}// 获取用户设定的平移量iRotaAngle = dlgPara.m_iRotaAngle;// 删除对话框delete dlgPara;//创建新DIBHDIB hNewDIB=NULL;//设置光标状态为等待状态BeginWaitCursor();//调用RotateDIB函数旋转DIB图象hNewDIB=(HDIB)::RotateDIB(lpDIB,iRotaAngle); //旋转成功if (hNewDIB){//替换原来的DIB图象为新的DIBpDoc->ReplaceHDIB(hNewDIB);//更新DIB图象的大小和调色板pDoc->InitDIBData();//设置文档修改标记pDoc->SetModifiedFlag(TRUE);//调节滚动视图大小SetScrollSizes(MM_TEXT,pDoc->GetDocSize()); //更新所有视图pDoc->UpdateAllViews(NULL);}else{//提示信息MessageBox("实现图象旋转失败!");}//解除锁定::GlobalUnlock((HGLOBAL) pDoc->GetHDIB()); //结束光标等待状态EndWaitCursor();}** 函数名称:** RotateDIB ()** 参数:** LPSTR lpDIB //指向源DIB图像指针** int iAngle* 说明:** 该函数用来实现DIB图像的旋转。

*************************************************************************/ HGLOBAL WINAPI RotateDIB(LPSTR lpDIB,int iAngle){//原图象宽度LONG lWidth;//原图象高度LONG lHeight;//旋转后图象宽度LONG lNewWidth;//旋转后图象高度LONG lNewHeight;//原图象的颜色数WORD wNumColors;//原图象的信息头结构指针LPBITMAPINFOHEADER lpbmi,lpbmi0;//指向原图象和目的图象的像素的指针LPBYTE lpSrc,lpDst;//指向原图像像素的指针LPBYTE lpDIBBits;//指向旋转后图像(像素)的指针LPBYTE lpNewDIBBits;LPSTR lpNewDIB;//旋转后新的DIB句柄HDIB hDIB;//循环变量LONG i,j,i0,j0;//原图像每行的字节数LONG lLineBytes;//旋转后图像每行的字节数LONG lNewLineBytes;//旋转角度的弧度double fArcAngle;//旋转角度的正弦和余弦float fSin,fCos;//旋转前图象四个角的坐标(以图象中心为坐标系原点)float fSrcX1,fSrcY1,fSrcX2,fSrcY2;float fSrcX3,fSrcY3,fSrcX4,fSrcY4;//旋转后图象四个角的坐标(以图象中心为坐标系原点)float fDstX1,fDstY1,fDstX2,fDstY2;float fDstX3,fDstY3,fDstX4,fDstY4;//两个中间量float f1,f2;//找到图象的像素位置lpDIBBits=(LPBYTE)::FindDIBBits(lpDIB);//获取图象的宽度lWidth=::DIBWidth(lpDIB);//获取图象的高度lHeight=::DIBHeight(lpDIB);//获取图象的颜色数wNumColors=::DIBNumColors(lpDIB);//获取指向原位图信息头结构的指针lpbmi0=(LPBITMAPINFOHEADER)lpDIB;//计算原图像每行的字节数lLineBytes = WIDTHBYTES(lWidth *(lpbmi0->biBitCount)); //将旋转角度从度转换到弧度fArcAngle =(iAngle*PI)/180.0;//计算旋转角度的正弦fSin = (float) sin(fArcAngle);//计算旋转角度的余弦fCos = (float) cos(fArcAngle);//计算原图的四个角的坐标(以图像中心为坐标系原点)fSrcX1 = (float) (- (lWidth - 1) / 2);fSrcY1 = (float) ( (lHeight - 1) / 2);fSrcX2 = (float) ( (lWidth - 1) / 2);fSrcY2 = (float) ( (lHeight - 1) / 2);fSrcX3 = (float) (- (lWidth - 1) / 2);fSrcY3 = (float) (- (lHeight - 1) / 2);fSrcX4 = (float) ( (lWidth - 1) / 2);fSrcY4 = (float) (- (lHeight - 1) / 2);//计算新图四个角的坐标(以图像中心为坐标系原点)fDstX1 = fCos * fSrcX1 + fSin * fSrcY1;fDstY1 = -fSin * fSrcX1 + fCos * fSrcY1;fDstX2 = fCos * fSrcX2 + fSin * fSrcY2;fDstY2 = -fSin * fSrcX2 + fCos * fSrcY2;fDstX3 = fCos * fSrcX3 + fSin * fSrcY3;fDstY3 = -fSin * fSrcX3 + fCos * fSrcY3;fDstX4 = fCos * fSrcX4 + fSin * fSrcY4;fDstY4 = -fSin * fSrcX4 + fCos * fSrcY4;//计算旋转后的图像实际宽度lNewWidth = (LONG) ( max( fabs(fDstX4 - fDstX1),fabs(fDstX3 - fDstX2) ) + 0.5);//计算旋转后的图像高度lNewHeight = (LONG) ( max( fabs(fDstY4 - fDstY1),fabs(fDstY3 - fDstY2) ) + 0.5);//计算旋转后图像每行的字节数lNewLineBytes = WIDTHBYTES(lNewWidth * lpbmi0->biBitCount);//计算两个常数f1 = (float) (-0.5 * (lNewWidth - 1) * fCos - 0.5 * (lNewHeight - 1) * fSin + 0.5 * (lWidth - 1));f2 = (float) ( 0.5 * (lNewWidth - 1) * fSin - 0.5 * (lNewHeight - 1) * fCos + 0.5 * (lHeight - 1));//暂时分配内存,以保存新图像hDIB=(HDIB)::GlobalAlloc(GHND, lNewHeight*lNewLineBytes+*(LPDWORD)lpDIB+::PaletteSize(lpDIB));//分配内存失败,直接返回if (!hDIB)return NULL;//锁定内存lpNewDIB = (LPSTR)::GlobalLock((HGLOBAL)hDIB);//复制DIB信息头和调色板memcpy(lpNewDIB,lpDIB,*(LPDWORD)lpDIB+::PaletteSize(lpDIB));//获取图象的信息头结构的指针lpbmi=(LPBITMAPINFOHEADER)lpNewDIB;//更新DIB图象的高度和宽度lpbmi->biWidth=lNewWidth;lpbmi->biHeight=lNewHeight;//找到新DIB像素的起始位置lpNewDIBBits=(LPBYTE)::FindDIBBits(lpNewDIB);//如果是256色位图if(wNumColors==256){//旋转后图像每行for(i = 0; i<lNewHeight; i++){//旋转后图象每列for(j=0;j<lNewWidth;j++){//指向图象第i行第j个像素的指针lpDst =(LPBYTE)lpNewDIBBits + lNewLineBytes * (lNewHeight-1-i)+j; //计算每个像素点在原图象中的坐标i0 = (LONG) (-((float) j) * fSin + ((float) i) * fCos + f2 + 0.5); j0 = (LONG) ( ((float) j) * fCos + ((float) i) * fSin + f1 + 0.5); // 判断是否在源图象范围之内if( (j0 >= 0) && (j0 < lWidth) && (i0 >= 0) && (i0 < lHeight)){// 指向源DIB图象第i0行,第j0个象素的指针lpSrc = (LPBYTE)lpDIBBits + lLineBytes * (lHeight - 1 - i0) + j0; // 复制象素*lpDst = *lpSrc;}else{// 对于源图中没有的象素,直接赋值为255* ((LPBYTE)lpDst) = 255;}}}}//如果是24位真彩色位图else if(wNumColors==0){//旋转后图像每行for(i = 0; i<lNewHeight; i++){//旋转后图象每列for(j=0;j<lNewWidth;j++){//指向图象第i行第j个像素的指针lpDst =(LPBYTE)lpNewDIBBits + lNewLineBytes * (lNewHeight-1-i)+3*j; //计算每个像素点在原图象中的坐标i0 = (LONG) (-((float) j) * fSin + ((float) i) * fCos + f2 + 0.5); j0 = (LONG) ( ((float) j) * fCos + ((float) i) * fSin + f1 + 0.5); // 判断是否在源图象范围之内if( (j0 >= 0) && (j0 < lWidth) && (i0 >= 0) && (i0 < lHeight)){// 指向源DIB图象第i0行,第j0个象素的指针lpSrc = (LPBYTE)lpDIBBits + lLineBytes * (lHeight - 1 - i0) + 3*j0; // 复制象素memcpy(lpDst,lpSrc,3);}else{// 对于源图中没有的象素,直接赋值为255memset(lpDst,255,3);}}}}else{AfxMessageBox("只支持256色和真彩色位图");// 释放内存GlobalUnlock(hDIB);GlobalFree(hDIB);return NULL;}// 返回return hDIB;}3.图像缩放(对话框自己建立)void CCimageProcessingView::OnGeomZoom(){// TODO: Add your command handler code here// 图像缩放// 获取文档CCimageProcessingDoc* pDoc = GetDocument();// 指向DIB的指针LPSTR lpDIB;// 锁定DIBlpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB()); // 缩放比率float fXZoomRatio;float fYZoomRatio;// 创建对话框CDlgGeoZoom dlgPara;// 初始化变量值dlgPara.m_XZoom = 0.5;dlgPara.m_YZoom = 0.5;// 显示对话框,提示用户设定平移量if (dlgPara.DoModal() != IDOK){// 返回return;}// 获取用户设定的平移量fXZoomRatio = dlgPara.m_XZoom;fYZoomRatio = dlgPara.m_YZoom;// 删除对话框delete dlgPara;// 创建新DIBHDIB hNewDIB = NULL;// 更改光标形状BeginWaitCursor();// 调用ZoomDIB()函数转置DIBhNewDIB = (HDIB) ZoomDIB(lpDIB, fXZoomRatio, fYZoomRatio);// 判断缩放是否成功if (hNewDIB != NULL){// 替换DIB,同时释放旧DIB对象pDoc->ReplaceHDIB(hNewDIB);// 更新DIB大小和调色板pDoc->InitDIBData();// 设置脏标记pDoc->SetModifiedFlag(TRUE);// 重新设置滚动视图大小SetScrollSizes(MM_TEXT, pDoc->GetDocSize());// 更新视图pDoc->UpdateAllViews(NULL);}else{// 提示用户MessageBox("分配内存失败!", "系统提示" , MB_ICONINFORMATION | MB_OK);}// 解除锁定::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());// 恢复光标EndWaitCursor();}/************************************************************************* ** 函数名称:* ZoomDIB()** 参数:* LPSTR lpDIB - 指向源DIB的指针* float fXZoomRatio - X轴方向缩放比率* float fYZoomRatio - Y轴方向缩放比率** 返回值:* HGLOBAL - 缩放成功返回新DIB句柄,否则返回NULL。

相关主题