数字图像处理

这是我数字图像处理的上机作业,下述源代码是在源文件view.cpp中截取
包含对图像的简单放大缩小功能,线性变换功能,生成直方图功能,锐化与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();
    
}

源代码


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值