图像平滑和锐化
以下的操作均要在GDI+下进行操作,如果GDI+显示图片有问题,请访问:vs2010 MFC使用GDI+显示图片
图像平滑:
最简单的平滑滤波是将原图中的一个像素的灰度值和它周围邻近8个像素的灰度值相加,然后求平均值(除以9)作为新图中改像素的灰度值。它采用模板计算的思想,模板操作实现了一种邻域操作,即某个像素点的结果不仅与本像素灰度有关,而且与其邻域点的像素值有关。
图像锐化:
由于图像模糊的实质是图像受到平均或积分运算造成的,所以为了图像中的任何方向伸展的边缘和轮廓变得清晰,可以对图像进行逆运算如微分运算,从而使图像清晰化。
使用GDI+进行图像平滑和锐化
1.创立一个头文件“ImgEnhance.h”,同时生成“ImgEnhance.cpp”,在ImgEnhance.h中定义变量和定义函数,在ImgEnhance.cpp中写函数。
2.在头文件中定义构造函数,析构函数,Bitmap
变量,Byte
变量,图像的宽 m_Width
,图像的高m_Height
,平滑和锐化函数ImageSmoothingSharping(double* pTemp, int sz,Bitmap*& pBitmap)
#pragma once
class CImgEnhance
{
public:
CImgEnhance(Bitmap* pCurBitmap);
~CImgEnhance(void);
Bitmap* m_pCurBitmap;
BYTE* m_pGrayData;
int m_Width;
int m_Height;
bool ImageSmoothingSharping(double* pTemp, int sz,Bitmap*& pBitmap);//平滑和锐化
private:
bool GrayData2Bitmap(BYTE* pGrayData,Bitmap*& pBitmap); // BYTE类型转化成Bitmap类型
};
2.在ImgEnhance.cpp改写构造函数
CImgEnhance::CImgEnhance(Bitmap* pCurBitmap)
{
m_pCurBitmap = pCurBitmap;
m_Width = m_pCurBitmap->GetWidth();
m_Height = m_pCurBitmap->GetHeight();
BYTE* scan0;
int stride;
BitmapData* pBitmapData = new BitmapData();
Rect rc(0,0,m_Width,m_Height);
m_pCurBitmap->LockBits(&rc,ImageLockModeRead | ImageLockModeWrite,
PixelFormat24bppRGB,pBitmapData);
scan0 = (BYTE* )pBitmapData->Scan0;
stride = pBitmapData->Stride;
m_pGrayData = new BYTE[m_Width * m_Height];
for(int i = 0; i < m_Height; i++){
for(int j = 0; j < m_Width; j++){
m_pGrayData[i * m_Width + j] = (scan0[i * stride + 3 * j]
+ scan0[i * stride + 3 * j + 1] + scan0[i * stride + 3 * j + 2]) / 3;
}
}
m_pCurBitmap->UnlockBits(pBitmapData);
}
3.修改析构函数
CImgEnhance::~CImgEnhance(void)
{
if(NULL != m_pGrayData){
delete[] m_pGrayData;
}
}
4.这里需要写一个把Byte类转化成Bitmap类的函数 GrayData2Bitmap,函数如下:
bool CImgEnhance::GrayData2Bitmap(BYTE* pGrayData,Bitmap*& pBitmap)// BYTE类型转化成Bitmap类型
{
if(NULL == pGrayData){
return false;
}
if(NULL != pBitmap){
delete pBitmap;
pBitmap = NULL;
}
pBitmap = new Bitmap(m_Width, m_Height,PixelFormat24bppRGB);
BYTE* scan0;
int stride;
BitmapData* pBitmapData = new BitmapData();
Rect rc(0,0,m_Width,m_Height);
pBitmap->LockBits(&rc,ImageLockModeRead | ImageLockModeWrite,
PixelFormat24bppRGB,pBitmapData);
scan0 = (BYTE* )pBitmapData->Scan0;
stride = pBitmapData->Stride;
for(int i = 0; i < m_Height; i++){
for(int j = 0; j < m_Width; j++){
scan0[i * stride + 3 * j] = pGrayData[i * m_Width + j];
scan0[i * stride + 3 * j + 1] = pGrayData[i * m_Width + j];
scan0[i * stride + 3 * j + 2] = pGrayData[i * m_Width + j];
}
}
pBitmap->UnlockBits(pBitmapData);
}
5.在ImgEnhance.cpp
完成ImageSmoothingSharping()
函数
bool CImgEnhance::ImageSmoothingSharping(double* pTemp, int sz,Bitmap*& pBitmap){
BYTE* pOlData = new BYTE[m_Height * m_Width];
memcpy(pOlData, m_pGrayData, m_Height * m_Width * sizeof(BYTE));
int i2,j2;
int sz2 = 2 * sz + 1;
double tmp;
for(int i = 0; i < m_Height; i++){
for(int j = 0; j < m_Width; j++){
m_pGrayData[i * m_Width + j] = 0;
tmp = 0;
for(int i1 = -sz; i1 <= sz; i1++){
for(int j1 = -sz; j1 <= sz; j1++){
i2 = i + i1;
j2 = j + j1;
if(i2 < 0 || i2 >= m_Height || j2 < 0 || j2 >= m_Width)
continue;
tmp += (pOlData[i2 * m_Width + j2] * pTemp[(i1 + sz) * sz2 + j1 + sz]);
}
}
m_pGrayData[i * m_Width + j] = (BYTE) fabs(tmp);
}
}
GrayData2Bitmap(m_pGrayData,pBitmap);
return true;
}
6.添加“图像平滑”“图像锐化”,并添加添加事件处理程序,跳转到代码区
图像平滑:
CImageDoc* pDoc = GetDocument();
if(NULL == pDoc)
return;
if(NULL == pDoc->m_pCurBitmap)
return;
CImgEnhance alg(pDoc->m_pCurBitmap);
double temp[] = {1.0/9,1.0/9,1.0/9,1.0/9,1.0/9,1.0/9,1.0/9,1.0/9,1.0/9};//图像平滑的模板
alg.ImageSmoothingSharping(temp,1,pDoc->m_pSecondBitmap);
this->Invalidate();
图像锐化:
CImageDoc* pDoc = GetDocument();
if(NULL == pDoc)
return;
if(NULL == pDoc->m_pCurBitmap)
return;
CImgEnhance alg(pDoc->m_pCurBitmap);
double temp[] = {0,-1,0,-1,0,1,0,1,0}; //图像锐化的模板
alg.ImageSmoothingSharping(temp,1,pDoc->m_pSecondBitmap);
this->Invalidate();
7.结果显示
图像平滑:
图像锐化: