
展开全部
.旋转图像(含对话框 这里对话框需要自己建立)
void CCimageProcessingView::OnGeomRota()
{
//获取指向文档的指针
CCimageProcessingDoc* pDoc = GetDocument();
//指向DIB的指针
LPSTR lpDIB;
//锁定DIB
lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());
// 缩放比率
int iRotaAngle;
// 创建对话框
CDlgGeoRota dlgPara;
// 初始化变量值
dlgPara.m_iRotaAngle = 90;
// 显示对话框,提示用户设定旋转角度
if (dlgPara.DoModal() != IDOK)
{
// 返回
return;
}
// 获取用户设定的平移量
iRotaAngle = dlgPara.m_iRotaAngle;
// 删除对话框
delete dlgPara;
//创建新DIB
HDIB hNewDIB=NULL;
//设置光标状态为等待状态
BeginWaitCursor();
//调用RotateDIB函数旋转DIB图象
hNewDIB=(HDIB)::RotateDIB(lpDIB,iRotaAngle);
//旋转成功
if (hNewDIB)
{
//替换原来的DIB图象为新的DIB
pDoc->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
{
// 对于源图中没有的象素,直接赋值为255
memset(lpDst,255,3);
}
}
}
}
else
{
AfxMessageBox("只支持256色和真彩色位图");
// 释放内存
GlobalUnlock(hDIB);
GlobalFree(hDIB);
return NULL;
}
// 返回
return hDIB;
}
void CCimageProcessingView::OnGeomRota()
{
//获取指向文档的指针
CCimageProcessingDoc* pDoc = GetDocument();
//指向DIB的指针
LPSTR lpDIB;
//锁定DIB
lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());
// 缩放比率
int iRotaAngle;
// 创建对话框
CDlgGeoRota dlgPara;
// 初始化变量值
dlgPara.m_iRotaAngle = 90;
// 显示对话框,提示用户设定旋转角度
if (dlgPara.DoModal() != IDOK)
{
// 返回
return;
}
// 获取用户设定的平移量
iRotaAngle = dlgPara.m_iRotaAngle;
// 删除对话框
delete dlgPara;
//创建新DIB
HDIB hNewDIB=NULL;
//设置光标状态为等待状态
BeginWaitCursor();
//调用RotateDIB函数旋转DIB图象
hNewDIB=(HDIB)::RotateDIB(lpDIB,iRotaAngle);
//旋转成功
if (hNewDIB)
{
//替换原来的DIB图象为新的DIB
pDoc->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
{
// 对于源图中没有的象素,直接赋值为255
memset(lpDst,255,3);
}
}
}
}
else
{
AfxMessageBox("只支持256色和真彩色位图");
// 释放内存
GlobalUnlock(hDIB);
GlobalFree(hDIB);
return NULL;
}
// 返回
return hDIB;
}
参考资料: http://blog.vbgood.com/index.php/1834/action_viewspace_itemid_174.html

2024-08-07 广告
OpenCV标定板是东莞市大凡光学科技有限公司在相机标定中常用的工具。它通常由黑白格点按一定规则排列在平面上组成,如棋盘格或圆形格等。在相机标定时,将标定板置于不同位置和姿态下拍摄图像,利用OpenCV库中的函数检测标定板上的角点或圆心,进...
点击进入详情页
本回答由东莞大凡提供
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询