📄 imagetestdoc.cpp
字号:
// imagetestDoc.cpp : implementation of the CImagetestDoc class
// 山东大学信息科学与工程学院 数字图像处理编程讲义程序
// 作者:赵辉 bugzhao@sdu.edu.cn
// 完成于:2005.11.15
#include "stdafx.h"
#include "imagetest.h"
#include "imagetestDoc.h"
#include "ParaInput1.h"
#include "input2.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//定义模板运算函数
//im:输入图像 tp:模板参数
double * mbys(double * im,int imW,int imH,double *tp,int tpW,int tpH)
{
double * out=new double[imW*imH];
memset(out, 0, imW*imH*sizeof(double));
int i,j,m,n;
#define im(ROW,COL) im[imW*(ROW)+(COL)]
#define tp(ROW,COL) tp[tpW*(ROW)+(COL)]
#define out(ROW,COL) out[imW*(ROW)+(COL)]
double a;
for(i=0;i<imH;i++)
for(j=0;j<imW;j++)
{
a=0;
//去掉靠近边界的行
if(i>int(tpH/2) && i<imH-int(tpH/2) && j>int(tpW/2) && j<imW-int(tpW/2))
for(m=0;m<tpH;m++)
for(n=0;n<tpW;n++)
{
a+=im(i+m-int(tpH/2),j+n-int(tpW/2))*tp(m,n);
}
out(i,j)=a;
}
return out;
}
double * mbys3(double * im,int imW,int imH,int tpW,int tpH)
{
double * out=new double[imW*imH];
memset(out, 0, imW*imH*sizeof(double));
int i,j,m,n;
#define im(ROW,COL) im[imW*(ROW)+(COL)]
#define out(ROW,COL) out[imW*(ROW)+(COL)]
double a;
for(i=0;i<imH;i++)
for(j=0;j<imW;j++)
{
a=0;
//去掉靠近边界的行
if(i>int(tpH/2) && i<imH-int(tpH/2) && j>int(tpW/2) && j<imW-int(tpW/2))
for(m=0;m<tpH;m++)
for(n=0;n<tpW;n++)
{
a+=im(i+m-int(tpH/2),j+n-int(tpW/2));
}
out(i,j)=a/(tpW*tpH);
}
return out;
}
/////////////////////////////////////////////////////////////////////////////
// CImagetestDoc
IMPLEMENT_DYNCREATE(CImagetestDoc, CDocument)
BEGIN_MESSAGE_MAP(CImagetestDoc, CDocument)
//{{AFX_MSG_MAP(CImagetestDoc)
ON_COMMAND(ID_IMG_REVERSE_COLOR, OnImgReverseColor)
ON_COMMAND(ID_IMG_CONVERT_GRAY, OnImgConvertGray)
ON_COMMAND(ID_IMG_INCREASE_BRIGHTNESS, OnImgIncreaseBrightness)
ON_COMMAND(ID_IMG_EDGE_BLUR, OnImgEdgeBlur)
ON_COMMAND(IDM_Forstner, OnForstner)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CImagetestDoc construction/destruction
CImagetestDoc::CImagetestDoc()
{
// TODO: add one-time construction code here
m_nDocSize.cx = 800;
m_nDocSize.cy = 800;
m_palDIB = NULL;
m_hDIB = NULL;
}
CImagetestDoc::~CImagetestDoc()
{
if (m_hDIB != NULL)
{
::GlobalFree((HGLOBAL) m_hDIB);
m_hDIB=NULL;
}
if (m_palDIB != NULL)
{
delete m_palDIB;
m_palDIB=NULL;
}
}
BOOL CImagetestDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
m_hDIB = NewDIB(m_nDocSize.cx, m_nDocSize.cy,24);
InitDIBData();
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CImagetestDoc serialization
void CImagetestDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}
}
/////////////////////////////////////////////////////////////////////////////
// CImagetestDoc diagnostics
#ifdef _DEBUG
void CImagetestDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CImagetestDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CImagetestDoc commands
BOOL CImagetestDoc::InitDIBData()
{
if (m_palDIB != NULL)
{
delete m_palDIB;
m_palDIB = NULL;
}
if (m_hDIB == NULL)
{
return FALSE;
}
m_palDIB = new CPalette;
if (m_palDIB == NULL)
{
// we must be really low on memory
::GlobalFree((HGLOBAL) m_hDIB);
m_hDIB = NULL;
return FALSE;
}
if (::CreateDIBPalette(m_hDIB, m_palDIB) == NULL)
{
// DIB may not have a palette
delete m_palDIB;
m_palDIB = NULL;
}
return TRUE;
}
BOOL CImagetestDoc::ReadImgFile(CString sName)
{
if (m_hDIB != NULL)
{
::GlobalFree((HGLOBAL) m_hDIB);
m_hDIB=NULL;
}
if (m_palDIB != NULL)
{
delete m_palDIB;
m_palDIB=NULL;
}
// replace calls to Serialize with ReadDIBFile function
CFile nFile;
if(!nFile.Open(sName,CFile::modeRead))
return false;
m_hDIB = ReadDIBFile(nFile);
nFile.Close();
InitDIBData();
if (m_hDIB == NULL)
return FALSE;
return TRUE;
}
BOOL CImagetestDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
if (!CDocument::OnOpenDocument(lpszPathName))
return FALSE;
// TODO: Add your specialized creation code here
BOOL b = ReadImgFile(lpszPathName);
if(b )
{
LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);
m_nDocSize.cx = (int) ::DIBWidth(lpDIB); // Size of DIB - x
m_nDocSize.cy = (int) ::DIBHeight(lpDIB); // Size of DIB - y
::GlobalUnlock((HGLOBAL) m_hDIB);
}
POSITION pos;
pos = GetFirstViewPosition();
while(pos != NULL)
{
CScrollView * pView = (CScrollView *)GetNextView(pos);
if(pView != NULL)
{
pView->SetScrollSizes(MM_TEXT, m_nDocSize);
}
}
return b;
}
BOOL CImagetestDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
// TODO: Add your specialized code here and/or call the base class
CFile nFile;
if(m_hDIB == NULL)
return false;
nFile.Open(lpszPathName,CFile::modeWrite | CFile::modeCreate);
SaveDIB(m_hDIB, nFile);
nFile.Close();
return true;
// return CDocument::OnSaveDocument(lpszPathName);
}
void CImagetestDoc::OnImgReverseColor()
{
//计算操作所用时间-计时开始
TimeCountStart;
int i,j;
unsigned char *lpSrc;
LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)m_hDIB);
int cxDIB = (int) ::DIBWidth(lpDIB); // Size of DIB - x
int cyDIB = (int) ::DIBHeight(lpDIB); // Size of DIB - y
LPSTR lpDIBBits=::FindDIBBits (lpDIB);
// 计算图像每行的字节数
long lLineBytes = WIDTHBYTES(cxDIB * 8);
// 每行
for(i = 0; i < cyDIB; i++)
{
// 每列
for(j = 0; j < cxDIB; j++)
{
// 指向DIB第i行,第j个象素的指针(这里的行为从上到下的)
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (cyDIB - 1 - i) + j;
// 计算新的灰度值
*(lpSrc) = BYTE(255-*lpSrc);
}
}
::GlobalUnlock((HGLOBAL) m_hDIB);
UpdateAllViews(NULL, 0, NULL);
//显示操作所用时间
TimeCountEnd;
}
void CImagetestDoc::OnImgConvertGray()
{
int i,j;
unsigned char *lpSrc,*lpDst;//一个指向源、目的像素的移动指针
//对源图像进行操作
LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)m_hDIB);
int cxDIB = (int) ::DIBWidth(lpDIB);
int cyDIB = (int) ::DIBHeight(lpDIB);
LPSTR lpDIBBits=::FindDIBBits (lpDIB); //找到源图像中图像数据区起始位置
long lLineBytesSrc = WIDTHBYTES(cxDIB * 8 * 3);// 计算源24位真彩图像每行的字节数
int numColors=(int) ::DIBNumColors((char *)lpDIB);
if (numColors!=0) //如果numColors是0,则表示目前图像为24位真彩图
{
::GlobalUnlock((HGLOBAL) m_hDIB);
return;
}
//新创建一个8位(256级灰度)的DIB句柄
HDIB grayhDIB=NewDIB(cxDIB, cyDIB,8);
LPSTR glpDIB=(LPSTR)::GlobalLock((HGLOBAL)grayhDIB);
LPSTR glpDIBBits=::FindDIBBits (glpDIB);
long lLineBytesDst = WIDTHBYTES(cxDIB * 8);// 计算目标8位灰度图像每行的字节数
// 每行
for(i = 0; i < cyDIB; i++)
{
//每列
for(j = 0; j < cxDIB; j++)
{
// 指向DIB第i行,第j个象素的指针(这里的行为从上到下的)
lpSrc = (unsigned char*)lpDIBBits + lLineBytesSrc * (cyDIB - 1 - i) + j*3;
lpDst = (unsigned char*)glpDIBBits + lLineBytesDst * (cyDIB - 1 - i) + j;
*lpDst=(*lpSrc)/3+(*(lpSrc+1))/3+(*(lpSrc+2))/3;
}
}
m_hDIB=grayhDIB;
::GlobalUnlock((HGLOBAL) m_hDIB);
::GlobalUnlock((HGLOBAL) grayhDIB);
UpdateAllViews(NULL, 0, NULL);
}
void CImagetestDoc::OnImgIncreaseBrightness()
{
//获取输入参数作为亮度提升间隔
CParaInput1 input1;
input1.m_input1 =10;
if(input1.DoModal ()!=IDOK)
return;
int i,j,increment=10;
increment=input1.m_input1 ;
unsigned char *lpSrc;//一个指向源、目的像素的移动指针
LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)m_hDIB);
int cxDIB = (int) ::DIBWidth(lpDIB); // Size of DIB - x
int cyDIB = (int) ::DIBHeight(lpDIB); // Size of DIB - y
LPSTR lpDIBBits=::FindDIBBits (lpDIB);
// 计算图像每行的字节数
long lLineBytes = WIDTHBYTES(cxDIB * 8);
// 每行
for(i = 0; i < cyDIB; i++)
{
// 每列
for(j = 0; j < cxDIB; j++)
{
// 指向DIB第i行,第j个象素的指针(这里的行为从上到下的)
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (cyDIB - 1 - i) + j;
// 计算新的灰度值
if(*lpSrc<255-increment)
*(lpSrc) = BYTE(increment+*lpSrc);
}
}
::GlobalUnlock((HGLOBAL) m_hDIB);
UpdateAllViews(NULL, 0, NULL);
}
void CImagetestDoc::OnImgEdgeBlur()
{
int i,j;
unsigned char *lpSrc;//一个指向源、目的像素的移动指针
LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)m_hDIB);
int cxDIB = (int) ::DIBWidth(lpDIB); // Size of DIB - x
int cyDIB = (int) ::DIBHeight(lpDIB); // Size of DIB - y
LPSTR lpDIBBits=::FindDIBBits (lpDIB);
// 计算图像每行的字节数
long lLineBytes = WIDTHBYTES(cxDIB * 8);
int FrameWidth=15;
TRACE("%d ",FrameWidth);
// 每行
for(i = 0; i < cyDIB; i++)
{
// 每列
for(j = 0; j < cxDIB; j++)
{
if(i<=FrameWidth || i>cyDIB-FrameWidth || j<=FrameWidth || j>cxDIB-FrameWidth)
{ // 指向DIB第i行,第j个象素的指针(这里的行为从上到下的)
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (cyDIB - 1 - i) + j;
if((*lpSrc-40)>0)
*lpSrc=*lpSrc-40;
}
if(i<=FrameWidth-10 || i>cyDIB-FrameWidth+10 || j<=FrameWidth-10 || j>cxDIB-FrameWidth+10)
{ // 指向DIB第i行,第j个象素的指针(这里的行为从上到下的)
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (cyDIB - 1 - i) + j;
if((*lpSrc+45)<255)
*lpSrc=*lpSrc+45;
}
}
}
::GlobalUnlock((HGLOBAL) m_hDIB);
UpdateAllViews(NULL, 0, NULL);
}
void CImagetestDoc::OnForstner()
{
// TODO: Add your command handler code here
unsigned char *lpSrc;//一个指向源、目的像素的移动指针
LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)m_hDIB);
int cxDIB = (int) ::DIBWidth(lpDIB); // 图像宽度
int cyDIB = (int) ::DIBHeight(lpDIB); // 图像高度
LPSTR lpDIBBits=::FindDIBBits (lpDIB);
long lLineBytes = WIDTHBYTES(cxDIB * 8); // 计算灰度图像每行的字节数
//创建I、Gu、Gv、mx、corner数组
double *I=new double[cxDIB*cyDIB];
double *Gu=new double[cxDIB*cyDIB];
double *Gv=new double[cxDIB*cyDIB];
double *Gu2=new double[cxDIB*cyDIB];
double *Gv2=new double[cxDIB*cyDIB];
double *Guv=new double[cxDIB*cyDIB];
double *DetN=new double[cxDIB*cyDIB];
double *trN=new double[cxDIB*cyDIB];
double *w=new double[cxDIB*cyDIB];
double *q=new double[cxDIB*cyDIB];
bool *houxian=new bool[cxDIB*cyDIB];
double *Tw=new double[cxDIB*cyDIB];
double *mx=new double[cxDIB*cyDIB];
corner=new bool[cxDIB*cyDIB];
memset(corner, 0, cxDIB*cyDIB*sizeof(bool));
memset(houxian, 0, cxDIB*cyDIB*sizeof(bool));
memset(mx, 0, cxDIB*cyDIB*sizeof(double));
//定义宏以方便访问元素
#define I(ROW,COL) I[cxDIB*(ROW)+(COL)]
#define Gu(ROW,COL) Gu[cxDIB*(ROW)+(COL)]
#define Gu2(ROW,COL) Gu2[cxDIB*(ROW)+(COL)]
#define Gv(ROW,COL) Gv[cxDIB*(ROW)+(COL)]
#define Gv2(ROW,COL) Gv2[cxDIB*(ROW)+(COL)]
#define Guv(ROW,COL) Guv[cxDIB*(ROW)+(COL)]
#define DetN(ROW,COL) DetN[cxDIB*(ROW)+(COL)]
#define trN(ROW,COL) trN[cxDIB*(ROW)+(COL)]
#define w(ROW,COL) w[cxDIB*(ROW)+(COL)]
#define q(ROW,COL) q[cxDIB*(ROW)+(COL)]
#define corner(ROW,COL) corner[cxDIB*(ROW)+(COL)]
#define houxian(ROW,COL) w[cxDIB*(ROW)+(COL)]
#define Tw(ROW,COL) Tw[cxDIB*(ROW)+(COL)]
#define mx(ROW,COL) mx[cxDIB*(ROW)+(COL)]
int i,j;
//将图像灰度值复制到I中,这步很重要!想想为什么?
for(i = 0; i < cyDIB; i++)
{
for(j = 0; j < cxDIB; j++)
{
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (cyDIB - 1 - i) + j;
//将256级灰度图像转化为double型
I(i,j)=double(*lpSrc);
}
}
//计算Gu
double du[9]={0,0,0,0,-1,0,0,0,1};
Gu=mbys(I,cxDIB,cyDIB,du,3,3);
//计算Gv
double dv[9]={0,0,0,0,0,-1,0,1,0};
Gv=mbys(I,cxDIB,cyDIB,dv,3,3);
//计算Gu2
int m,n;
memset(Gu2, 0, cxDIB*cyDIB*sizeof(double));
for(i=0;i<cyDIB;i++)
for(j=0;j<cxDIB;j++)
{
double a=0;
//去掉靠近边界的行
if(i>int(5/2) && i<cyDIB-int(5/2) && j>int(5/2) && j<cxDIB-int(5/2))
for(m=0;m<5;m++)
for(n=0;n<5;n++)
{
a+=Gu(i+m-int(5/2),j+n-int(5/2))*Gu(i+m-int(5/2),j+n-int(5/2));
}
Gu2(i,j)=a;
}
//计算Gv2
memset(Gv2, 0, cxDIB*cyDIB*sizeof(double));
for(i=0;i<cyDIB;i++)
for(j=0;j<cxDIB;j++)
{
double a=0;
//去掉靠近边界的行
if(i>int(5/2) && i<cyDIB-int(5/2) && j>int(5/2) && j<cxDIB-int(5/2))
for(m=0;m<5;m++)
for(n=0;n<5;n++)
{
a+=Gv(i+m-int(5/2),j+n-int(5/2))*Gv(i+m-int(5/2),j+n-int(5/2));
}
Gv2(i,j)=a;
}
//计算Guv
memset(Guv, 0, cxDIB*cyDIB*sizeof(double));
for(i=0;i<cyDIB;i++)
for(j=0;j<cxDIB;j++)
{
double a=0;
//去掉靠近边界的行
if(i>int(5/2) && i<cyDIB-int(5/2) && j>int(5/2) && j<cxDIB-int(5/2))
for(m=0;m<5;m++)
for(n=0;n<5;n++)
{
a+=Gv(i+m-int(5/2),j+n-int(5/2))*Gu(i+m-int(5/2),j+n-int(5/2));
}
Guv(i,j)=a;
}
//计算DetN trN w q
for(i = 0; i < cyDIB; i++)
{
for(j = 0; j < cxDIB; j++)
{
//注意:要在分母中加入一个极小量以防止除数为零溢出
DetN(i,j)=Gu2(i,j)*Gv2(i,j)-Guv(i,j)*Guv(i,j);
trN(i,j)=Gu2(i,j)+Gv2(i,j);
w(i,j) = DetN(i,j)/(trN(i,j)+0.0000001);
q(i,j)=4*DetN(i,j)/(trN(i,j)*trN(i,j));
}
}
double Tq=0.5;
Tw=mbys3(w,cxDIB,cyDIB,5,5);
for(i = 0; i < cyDIB; i++)
{
for(j = 0; j < cxDIB; j++)
{
if(q(i,j)>Tq&&w(i,j)>Tw(i,j))
houxian(i,j)=1;
}
}
double max=-1000000;
double max1=-1000000;
for(i=0;i<cyDIB;i++)
for(j=0;j<cxDIB;j++)
{
//去掉靠近边界的行
if(i>int(5/2) && i<cyDIB-int(5/2) && j>int(5/2) && j<cxDIB-int(5/2))
for(m=0;m<5;m++)
for(n=0;n<5;n++)
{
if(houxian(i+m-int(5/2),j+n-int(5/2)))
if(Tw(i+m-int(5/2),j+n-int(5/2))>max/*&&q(i,j)>max1*/)
max=Tw(i+m-int(5/2),j+n-int(5/2));
// max1=q(i+m-int(5/2),j+n-int(5/2));
}
mx(i,j)=max;
}
for(i=0;i<cyDIB;i++)
for(j=0;j<cxDIB;j++)
{
if(Tw(i,j)==mx(i,j))
corner(i,j)=1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -