这是我数字图像处理的上机作业,下述源代码是在源文件view.cpp中截取
包含对图像的简单放大缩小功能,线性变换功能,生成直方图功能,锐化与sobel边缘处理
详细程序文件在这里(http:// pan.baidu.com/s/1pKRuIhX),
包含对图像的简单放大缩小功能,线性变换功能,生成直方图功能,锐化与sobel边缘处理
详细程序文件在这里(http:// pan.baidu.com/s/1pKRuIhX),
实验报告(http://pan.baidu.com/s/1hsPNtOg),注意配置opencv文件。
void CZhangyanImageView::OnIimageTxph()
{
// TODO: 在此添加命令处理程序代码
CSmoothDlg dlg;
if (dlg.DoModal())
{
// TODO: Add your command handler code here
double H[3][3];//申明模板变量
/* ={1 ,2 ,1 ,
2 ,4 ,2 ,
1 ,2 ,1 };*/
double K=dlg.m_nSmooth10;//H 与 K组合为8-领域平均法
H[0][0]=dlg.m_nSmooth1;// //申明模板变量赋值
H[0][1]=dlg.m_nSmooth2;
H[0][2]=dlg.m_nSmooth3;
H[1][0]=dlg.m_nSmooth4;
H[1][1]=dlg.m_nSmooth5;
H[1][2]=dlg.m_nSmooth6;
H[2][0]=dlg.m_nSmooth7;
H[2][1]=dlg.m_nSmooth8;
H[2][2]=dlg.m_nSmooth9;
CZhangyanImageDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
unsigned char * pBits=pDoc->m_pBits;
int nWidth=pDoc->imageWidth;
int nHeight=pDoc->imageHeight;
long lTotalR,lTotal;
int m,n;
double dValue;
double Value[3][3];
unsigned char * pOldBits=new unsigned char[nWidth*nHeight];//分配内存
CopyMemory(pOldBits,pBits ,nWidth*nHeight);//把图像复制到pOldBit
for(int i=0;i<nHeight;i++)
{
lTotalR=i*nWidth;
for(int j=0;j<nWidth;j++)
{
lTotal=lTotalR+j;
if(i==0||i==nHeight-1||j==0||j==nWidth-1)//边缘点不作处理,直接拷贝数据
{
pBits[lTotal]=pOldBits[lTotal];
}else//内部点作平滑处理,
{
Value[0][0]=pOldBits[lTotal-nWidth-1];
Value[0][1]=pOldBits[lTotal-nWidth-0];
Value[0][2]=pOldBits[lTotal-nWidth+1];
Value[1][0]=pOldBits[lTotal- 0 -1];
Value[1][1]=pOldBits[lTotal- 0 -0];
Value[1][2]=pOldBits[lTotal- 0 +1];
Value[2][0]=pOldBits[lTotal+nWidth-1];
Value[2][1]=pOldBits[lTotal+nWidth-0];
Value[2][2]=pOldBits[lTotal+nWidth+1];
dValue=0.0;
for(m=0;m<3;m++)
for(n=0;n<3;n++)
dValue=dValue+H[m][n]*Value[m][n];
dValue=dValue*K;
pBits[lTotal]=int(dValue+0.5);
}
}
}
Invalidate();
delete pOldBits;
}
}
BOOL WINAPI GradSharp(unsigned char *lpDIBBits, LONG lWidth, LONG lHeight, BYTE bThre)
{
// 指向源图像的指针
unsigned char* lpSrc;
unsigned char* lpSrc1;
unsigned char* lpSrc2;
// 循环变量
LONG i;
LONG j;
// 图像每行的字节数
LONG lLineBytes;
// 中间变量
BYTE bTemp;
// 计算图像每行的字节数
lLineBytes = (((lWidth * 8) + 31) / 32 * 4); // 每行 字节
for(i = 0; i < lHeight; i++)
{
// 每列
for(j = 0; j < lWidth; j++)
{
// 指向DIB第i行,第j个象素的指针
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;
// 指向DIB第i+1行,第j个象素的指针
lpSrc1 = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 2 - i) + j;
// 指向DIB第i行,第j+1个象素的指针
lpSrc2 = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j + 1;
bTemp = abs((*lpSrc)-(*lpSrc1)) + abs((*lpSrc)-(*lpSrc2));
// 判断是否小于阈值
if (bTemp < 255)
{
// 判断是否大于阈值,对于小于情况,灰度值不变。
if (bTemp >= bThre)
{
// 直接赋值为bTemp
*lpSrc = bTemp;
}
}
else
{
// 直接赋值为255
*lpSrc = 255;
}
}
}
// 返回
return TRUE;
}
void CZhangyanImageView::OnEnhaGradsharp()
{
// TODO: 在此添加命令处理程序代码
// TODO: Add your command handler code here
// 梯度锐化
CZhangyanImageDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
unsigned char * pBits=pDoc->m_pBits;
int nWidth=pDoc->imageWidth;
int nHeight=pDoc->imageHeight;
int nColorBits = pDoc->m_nColorBits;
if (nColorBits != 8)
{
// 提示用户
MessageBox("目前只支持256色位图的梯度锐化!", "系统提示" ,
MB_ICONINFORMATION | MB_OK);
// 返回
return;
}
// 阈值
BYTE bThre=10;
// 更改光标形状
BeginWaitCursor();
// 调用GradSharp()函数进行梯度板锐化
if(::GradSharp(pBits, nWidth, nHeight, bThre))
{
// 设置脏标记
pDoc->SetModifiedFlag(TRUE);
// 更新视图
pDoc->UpdateAllViews(NULL);
}
else
{
// 提示用户
MessageBox("分配内存失败!", "系统提示" , MB_ICONINFORMATION | MB_OK);
}
// 恢复光标
EndWaitCursor();
}
BOOL WINAPI Template(unsigned char * lpDIBBits, LONG lWidth, LONG lHeight,
int iTempH, int iTempW,
int iTempMX, int iTempMY,
FLOAT * fpArray, FLOAT fCoef)
{
// 指向复制图像的指针
unsigned char * lpNewDIBBits;
// 指向源图像的指针
unsigned char* lpSrc;
// 指向要复制区域的指针
unsigned char* lpDst;
// 循环变量
LONG i;
LONG j;
LONG k;
LONG l;
// 计算结果
FLOAT fResult;
// 图像每行的字节数
LONG lLineBytes;
// 计算图像每行的字节数
lLineBytes = (((lWidth * 8) + 31) / 32 * 4);
// 暂时分配内存,以保存新图像
lpNewDIBBits = new unsigned char[lLineBytes * lHeight] ;
// 判断是否内存分配失败
if (lpNewDIBBits == NULL)
{
// 分配内存失败
return FALSE;
}
// 初始化图像为原始图像
memcpy(lpNewDIBBits, lpDIBBits, lLineBytes * lHeight);
// 行(除去边缘几行)
for(i = iTempMY; i < lHeight - iTempH + iTempMY + 1; i++)
{
// 列(除去边缘几列)
for(j = iTempMX; j < lWidth - iTempW + iTempMX + 1; j++)
{
// 指向新DIB第i行,第j个象素的指针
lpDst = (unsigned char*)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j;
fResult = 0;
// 计算
for (k = 0; k < iTempH; k++)
{
for (l = 0; l < iTempW; l++)
{
// 指向DIB第i - iTempMY + k行,第j - iTempMX + l个象素的指针
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i + iTempMY - k)
+ j - iTempMX + l;
// 保存象素值
fResult += (* lpSrc) * fpArray[k * iTempW + l];
}
}
// 乘上系数
fResult *= fCoef;
// 取绝对值
fResult = (FLOAT ) fabs(fResult);
// 判断是否超过255
if(fResult > 255)
{
// 直接赋值为255
* lpDst = 255;
}
else
{
// 赋值
* lpDst = (unsigned char) (fResult + 0.5);
}
}
}
// 复制变换后的图像
memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);
delete lpNewDIBBits;
// 返回
return TRUE;
}
void CZhangyanImageView::OnEnhaSharp()
{
// TODO: 在此添加命令处理程序代码
// TODO: Add your command handler code here
// 图像锐化
// 梯度锐化
CZhangyanImageDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
unsigned char * pBits=pDoc->m_pBits;
int nWidth=pDoc->imageWidth;
int nHeight=pDoc->imageHeight;
int nColorBits = pDoc->m_nColorBits;
if (nColorBits != 8)
{
// 提示用户
MessageBox("目前只支持256色位图的梯度锐化!", "系统提示" ,
MB_ICONINFORMATION | MB_OK);
// 返回
return;
}
// 模板高度
int iTempH;
// 模板宽度
int iTempW;
// 模板系数
FLOAT fTempC;
// 模板中心元素X坐标
int iTempMX;
// 模板中心元素Y坐标
int iTempMY;
// 模板元素数组
FLOAT aValue[9];
// 更改光标形状
BeginWaitCursor();
// 设置拉普拉斯模板参数
iTempW = 3;
iTempH = 3;
fTempC = 1.0;
iTempMX = 1;
iTempMY = 1;
aValue[0] = -1.0;
aValue[1] = -1.0;
aValue[2] = -1.0;
aValue[3] = -1.0;
aValue[4] = 9.0;
aValue[5] = -1.0;
aValue[6] = -1.0;
aValue[7] = -1.0;
aValue[8] = -1.0;
// 调用Template()函数用拉普拉斯模板锐化DIB
if (::Template(pBits, nWidth, nHeight,
iTempH, iTempW, iTempMX, iTempMY, aValue, fTempC))
{
// 设置脏标记
pDoc->SetModifiedFlag(TRUE);
// 更新视图
pDoc->UpdateAllViews(NULL);
}
else
{
// 提示用户
MessageBox("分配内存失败!", "系统提示" , MB_ICONINFORMATION | MB_OK);
}
// 恢复光标
EndWaitCursor();
}
BOOL WINAPI SobelDIB(unsigned char * lpDIBBits, LONG lWidth, LONG lHeight)
{
// 指向缓存图像的指针
unsigned char * lpDst1;
unsigned char * lpDst2;
lWidth= (((lWidth * 8) + 31) / 32 * 4);
// 指向缓存DIB图像的指针
unsigned char * lpNewDIBBits1;
unsigned char * lpNewDIBBits2;
//循环变量
long i;
long j;
// 模板高度
int iTempH;
// 模板宽度
int iTempW;
// 模板系数
FLOAT fTempC;
// 模板中心元素X坐标
int iTempMX;
// 模板中心元素Y坐标
int iTempMY;
//模板数组
FLOAT aTemplate[9];
// 暂时分配内存,以保存新图像
lpNewDIBBits1 = new unsigned char[lWidth * lHeight];
if (lpNewDIBBits1 == NULL)
{
// 分配内存失败
return FALSE;
}
// 暂时分配内存,以保存新图像
// 锁定内存
lpNewDIBBits2 = new unsigned char[lWidth * lHeight];
if (lpNewDIBBits2 == NULL)
{
// 分配内存失败
return FALSE;
}
// 拷贝源图像到缓存图像中
lpDst1 = lpNewDIBBits1;
memcpy(lpNewDIBBits1, lpDIBBits, lWidth * lHeight);
lpDst2 = lpNewDIBBits2;
memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight);
// 设置Sobel模板参数
iTempW = 3;
iTempH = 3;
fTempC = 1.0;
iTempMX = 1;
iTempMY = 1;
aTemplate[0] = -1.0;
aTemplate[1] = -2.0;
aTemplate[2] = -1.0;
aTemplate[3] = 0.0;
aTemplate[4] = 0.0;
aTemplate[5] = 0.0;
aTemplate[6] = 1.0;
aTemplate[7] = 2.0;
aTemplate[8] = 1.0;
// 调用Template()函数
if (!Template(lpNewDIBBits1, lWidth, lHeight,
iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC))
{
return FALSE;
}
// 设置Sobel模板参数
aTemplate[0] = -1.0;
aTemplate[1] = 0.0;
aTemplate[2] = 1.0;
aTemplate[3] = -2.0;
aTemplate[4] = 0.0;
aTemplate[5] = 2.0;
aTemplate[6] = -1.0;
aTemplate[7] = 0.0;
aTemplate[8] = 1.0;
// 调用Template()函数
if (!Template(lpNewDIBBits2, lWidth, lHeight,
iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC))
{
return FALSE;
}
//求两幅缓存图像的最大值
for(j = 0; j <lHeight; j++)
{
for(i = 0;i <lWidth-1; i++)
{
// 指向缓存图像1倒数第j行,第i个象素的指针
lpDst1 = lpNewDIBBits1 + lWidth * j + i;
// 指向缓存图像2倒数第j行,第i个象素的指针
lpDst2 = lpNewDIBBits2 + lWidth * j + i;
if(*lpDst2 > *lpDst1)
*lpDst1 = *lpDst2;
}
}
// 复制经过模板运算后的图像到源图像
memcpy(lpDIBBits, lpNewDIBBits1, lWidth * lHeight);
delete lpNewDIBBits2;
delete lpNewDIBBits1;
// 返回
return TRUE;
}
void CZhangyanImageView::OnEdgeSobel()
{
// TODO: 在此添加命令处理程序代码
// 梯度锐化
CZhangyanImageDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
unsigned char * pBits=pDoc->m_pBits;
int nWidth=pDoc->imageWidth;
int nHeight=pDoc->imageHeight;
int nColorBits = pDoc->m_nColorBits;
if (nColorBits != 8)
{
// 提示用户
MessageBox("目前只支持256色位图的梯度锐化!", "系统提示" ,
MB_ICONINFORMATION | MB_OK);
// 返回
return;
}
//Sobel边缘检测运算
// 调用SobelDIB()函数对DIB进行边缘检测
if (SobelDIB(pBits, nWidth, nHeight))
{
// 设置脏标记
pDoc->SetModifiedFlag(TRUE);
// 更新视图
pDoc->UpdateAllViews(NULL);
}
else
{
// 提示用户
MessageBox("分配内存失败!", "系统提示" , MB_ICONINFORMATION | MB_OK);
}
// 恢复光标
EndWaitCursor();
}
源代码