📄 imageprocessingview.cpp
字号:
// ImageProcessingView.cpp : implementation of the CImageProcessingView class
//
#include "stdafx.h"
#include "ImageProcessing.h"
#include "ImageProcessingDoc.h"
#include "ImageProcessingView.h"
#include "GlobalApi.h"
#include "DlgCoding.h"
#include <complex>
using namespace std;
#include "DlgHistShow1.h"
#include "DlgSmooth.h"
#include "DlgMedian.h"
#include "DlgEnhColor.h"
#include "DlgEhnLinTrans.h"
#include "DlgReg.h"
#include "DlgRecMatch.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CImageProcessingView
IMPLEMENT_DYNCREATE(CImageProcessingView, CScrollView)
BEGIN_MESSAGE_MAP(CImageProcessingView, CScrollView)
//{{AFX_MSG_MAP(CImageProcessingView)
ON_COMMAND(ID_FFT_2D, OnFft2d)
ON_COMMAND(ID_DFT_2D, OnDft2d)
ON_COMMAND(ID_VIEW_HISTOGRAM, OnViewHistogram)
ON_COMMAND(ID_ENHANCE_SMOOTH, OnEnhanceSmooth)
ON_COMMAND(ID_ENHANCE_MEDIAN, OnEnhanceMedian)
ON_COMMAND(ID_ENHANCE_PSEUDCOLOR, OnEnhancePseudcolor)
ON_COMMAND(ID_TRANS_DWT, OnTransDwt)
ON_COMMAND(ID_TRANS_IDWT, OnTransIdwt)
ON_COMMAND(IDC_ENHANCE_LINTRANS, OnEnhanceLintrans)
ON_COMMAND(IDC_ENHANCE_HISTEQU, OnEnhanceHistequ)
ON_COMMAND(ID_REG_REG, OnRegReg)
ON_COMMAND(IDC_ENHANCE_SHARP, OnEnhanceSharp)
ON_COMMAND(ID_ENHANCE_SMOOTH_FR, OnEnhanceSmoothFr)
ON_COMMAND(IDC_ENHANCE_BUTT_LOW, OnEnhanceButtLow)
ON_COMMAND(IDC_ENHANCE_SHARP_FREQ, OnEnhanceSharpFreq)
ON_COMMAND(IDC_ENHANCE_BUTT_HIGHT, OnEnhanceButtHight)
ON_COMMAND(ID_REGIONSEG_FIX, OnRegionsegFix)
ON_COMMAND(ID_ADA_REGION_SEG, OnAdaRegionSeg)
ON_COMMAND(ID_EDGE_ROBERTS, OnEdgeRoberts)
ON_COMMAND(ID_EDGE_SOBEL, OnEdgeSobel)
ON_COMMAND(ID_EDGE_PREWITT, OnEdgePrewitt)
ON_COMMAND(ID_EDGE_LAPLACE, OnEdgeLaplace)
ON_COMMAND(ID_EDGE_CANNY, OnEdgeCanny)
ON_COMMAND(ID_EDGE_TRACK, OnEdgeTrack)
ON_COMMAND(ID_REGION_GROW, OnRegionGrow)
ON_COMMAND(ID_MOTION_BACKGROUND, OnMotionBackground)
ON_COMMAND(ID_RECOG_MATCH, OnRecogMatch)
ON_COMMAND(ID_CODING_SHANFINO, OnCodingShanfino)
ON_COMMAND(ID_DEGENERATION_INVERSE, OnDegenerationInverse)
ON_COMMAND(ID_DEGENERATION_MOTION, OnDegenerationMotion)
ON_COMMAND(ID_DEGENERATION_Winner, OnDEGENERATIONWinner)
ON_COMMAND(ID_RESTORE_INVERSE, OnRestoreInverse)
ON_COMMAND(ID_RESTORE_MOTION, OnRestoreMotion)
ON_COMMAND(ID_RESTORE_WINNER, OnRestoreWinner)
ON_COMMAND(ID_STREET_FRAMEWORK, OnStreetFramework)
ON_COMMAND(ID_STREET_TRANSFORM, OnStreetTransform)
ON_COMMAND(ID_TRACE, OnTrace)
ON_COMMAND(ID_VIEW_BAYER, OnViewBayer)
ON_COMMAND(ID_VIEW_FloydSteinberg, OnVIEWFloydSteinberg)
ON_COMMAND(ID_OUTLINE, OnOutline)
ON_COMMAND(ID_FRAME_RESTORE, OnFrameRestore)
ON_COMMAND(ID_MOMENT, OnMoment)
ON_COMMAND(ID_BARYCENTERMOMENT, OnBarycentermoment)
ON_COMMAND(ID_ANALYSIS_HOLENUM, OnAnalysisHolenum)
ON_COMMAND(ID_FREQ_DCT, OnFreqDct)
ON_COMMAND(ID_FREQ_HOTELLING, OnFreqHotelling)
ON_COMMAND(ID_FREQ_WALSH, OnFreqWalsh)
ON_COMMAND(ID_CODING_ARITH, OnCodingArith)
ON_COMMAND(ID_CODING_BITPLANE, OnCodingBitplane)
ON_COMMAND(ID_CODING_HUFFMAN, OnCodingHuffman)
ON_COMMAND(ID_CODING_LOADIMG, OnCodingLoadimg)
ON_COMMAND(ID_CODING_WRITEIMG, OnCodingWriteimg)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CImageProcessingView construction/destruction
CImageProcessingView::CImageProcessingView()
{
// 为小波变换设置的参数
// 临时存放小波变换系数内存
m_pDbImage = NULL;
// 设置当前层数
m_nDWTCurDepth = 0;
// 设置小波基紧支集长度
m_nSupp = 1;
}
CImageProcessingView::~CImageProcessingView()
{
// 释放已分配内存
if(m_pDbImage){
delete[]m_pDbImage;
m_pDbImage = NULL;
}
}
BOOL CImageProcessingView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CScrollView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CImageProcessingView drawing
void CImageProcessingView::OnDraw(CDC* pDC)
{
CImageProcessingDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CSize sizeDibDisplay;
if(!pDoc->m_pDibInit->IsEmpty()){
sizeDibDisplay = pDoc->m_pDibInit->GetDimensions();
pDoc->m_pDibInit->Draw(pDC,CPoint(0,0),sizeDibDisplay);
}
}
void CImageProcessingView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
CImageProcessingDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CSize sizeTotal = pDoc->m_pDibInit->GetDimensions();
SetScrollSizes(MM_TEXT, sizeTotal);
GetParentFrame()->RecalcLayout();
ResizeParentToFit();
}
/////////////////////////////////////////////////////////////////////////////
// CImageProcessingView printing
BOOL CImageProcessingView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CImageProcessingView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CImageProcessingView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CImageProcessingView diagnostics
#ifdef _DEBUG
void CImageProcessingView::AssertValid() const
{
CScrollView::AssertValid();
}
void CImageProcessingView::Dump(CDumpContext& dc) const
{
CScrollView::Dump(dc);
}
CImageProcessingDoc* CImageProcessingView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CImageProcessingDoc)));
return (CImageProcessingDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CImageProcessingView message handlers
/*************************************************************************
*
* \函数名称:
* OnFft2d()
*
* \输入参数:
* 无
*
* \返回值:
* 无
*
* \说明:
* 运行二维快速傅立叶变换
*
*************************************************************************
*/
void CImageProcessingView::OnFft2d()
{
//图象FFT变换
// 更改光标形状
BeginWaitCursor();
// 循环控制变量
int y;
int x;
// 获得Doc类的指针
CImageProcessingDoc * pDoc = (CImageProcessingDoc *)this->GetDocument();
CDib * pDib = pDoc->m_pDibInit;
// 获得图象的头文件信息
LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
// 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的离散傅立叶变换)
if (lpBMIH->biBitCount != 8)
{
// 提示用户
MessageBox("目前只支持256色位图的离散傅立叶变换!", "系统提示" ,
MB_ICONINFORMATION | MB_OK);
// 返回
return;
}
// 图象的宽长
CSize sizeImage ;
int nWidth ;
int nHeight;
// 获得图象的宽长
sizeImage = pDib->GetDimensions() ;
nWidth = sizeImage.cx;
nHeight= sizeImage.cy;
// 临时变量
double dTmpOne;
double dTmpTwo;
// 傅立叶变换竖直方向点数
int nTransHeight ;
// 傅立叶变换水平方向点数
int nTransWidth ;
// 计算进行傅立叶变换的点数 (2的整数次幂)
dTmpOne = log(nWidth)/log(2);
dTmpTwo = ceil(dTmpOne) ;
dTmpTwo = pow(2,dTmpTwo) ;
nTransWidth = (int) dTmpTwo ;
// 计算进行傅立叶变换的点数 (2的整数次幂)
dTmpOne = log(nHeight)/log(2);
dTmpTwo = ceil(dTmpOne) ;
dTmpTwo = pow(2,dTmpTwo) ;
nTransHeight = (int) dTmpTwo ;
// 计算图象数据存储每行需要的字节数
// BMP文件的每行数据存储是DWORD对齐的
int nSaveWidth;
nSaveWidth = ( (nWidth << 3) + 31)/32 * 4 ;
// 指向图象数据的指针
LPBYTE lpImage ;
lpImage = pDib->m_lpImage ;
// 图象象素值
unsigned char unchValue;
// 指向时域数据的指针
complex<double> * pCTData ;
// 指向频域数据的指针
complex<double> * pCFData ;
// 分配内存
pCTData=new complex<double>[nTransWidth * nTransHeight];
pCFData=new complex<double>[nTransWidth * nTransHeight];
// 初始化
// 图象数据的宽和高不一定是2的整数次幂,所以pCTData
// 有一部分数据需要补0
for(y=0; y<nTransHeight; y++)
{
for(x=0; x<nTransWidth; x++)
{
pCTData[y*nTransWidth + x]=complex<double>(0,0);
}
}
// 把图象数据传给pCTData
for(y=0; y<nHeight; y++)
{
for(x=0; x<nWidth; x++)
{
unchValue = lpImage[y*nSaveWidth +x];
pCTData[y*nTransWidth + x]=complex<double>(unchValue,0);
}
}
// 傅立叶正变换
DIBFFT_2D(pCTData, nWidth, nHeight, pCFData) ;
// 临时变量
double dTmp;
for(y=0; y<nHeight; y++)
{
for(x=0; x<nWidth; x++)
{
dTmp = pCFData[y * nTransWidth + x].real()
* pCFData[y * nTransWidth + x].real()
+ pCFData[y * nTransWidth + x].imag()
* pCFData[y * nTransWidth + x].imag();
dTmp = sqrt(dTmp) ;
// 为了显示,需要对幅度的大小进行伸缩
dTmp /= 100 ;
// 限制图象数据的大小
dTmp = min(dTmp, 255) ;
lpImage[y*nSaveWidth +x] = (unsigned char)(int)dTmp;
}
}
// 为了在屏幕上显示,我们把幅度值大的部分用黑色显示
for(y=0; y<nHeight; y++)
{
for(x=0; x<nWidth; x++)
{
lpImage[y*nSaveWidth +x] = 255 - lpImage[y*nSaveWidth +x];
}
}
// 刷新屏幕
Invalidate();
// 释放内存
delete pCTData;
delete pCFData;
pCTData = NULL;
pCFData = NULL;
// 设置脏标记
pDoc->SetModifiedFlag(TRUE);
// 更新视图
pDoc->UpdateAllViews(NULL);
// 恢复光标形状
EndWaitCursor();
}
/*************************************************************************
*
* \函数名称:
* OnDft2d()
*
* \输入参数:
* 无
*
* \返回值:
* 无
*
* \说明:
* 运行二维傅立叶变换
*
*************************************************************************
*/
void CImageProcessingView::OnDft2d()
{
//图象离散傅立叶变换
//提示用户,直接进行离散傅立叶变换的时间很长
MessageBox("没有使用FFT,时间可能很长!", "作者提示" ,
MB_ICONINFORMATION | MB_OK);
//更改光标形状
BeginWaitCursor();
// 循环控制变量
int y;
int x;
CImageProcessingDoc * pDoc = (CImageProcessingDoc *)this->GetDocument();
CDib * pDib = pDoc->m_pDibInit;
// 获得图象的头文件信息
LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
// 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的离散傅立叶变换)
if (lpBMIH->biBitCount != 8)
{
// 提示用户
MessageBox("目前只支持256色位图的离散傅立叶变换!", "系统提示" ,
MB_ICONINFORMATION | MB_OK);
// 返回
return;
}
//图象的长宽大小
CSize sizeImage = pDib->GetDimensions();
int nWidth = sizeImage.cx ;
int nHeight = sizeImage.cy ;
// 计算图象数据存储每行需要的字节数
// BMP文件的每行数据存储是DWORD对齐的
int nSaveWidth;
nSaveWidth = ( (nWidth << 3) + 31)/32 * 4 ;
// 指向图象数据的指针
LPBYTE lpImage ;
lpImage = pDib->m_lpImage ;
double * pTrRstRpart = new double [nWidth*nHeight];
double * pTrRstIpart = new double [nWidth*nHeight];
::DIBDFT_2D(pDib, pTrRstRpart,pTrRstIpart);
// 临时变量
double dTmp;
for(y=0; y<nHeight; y++)
{
for(x=0; x<nWidth; x++)
{
dTmp = pTrRstRpart[y*nWidth + x] * pTrRstRpart[y*nWidth + x]
+ pTrRstIpart[y*nWidth + x] * pTrRstIpart[y*nWidth + x];
dTmp = sqrt(dTmp) ;
// 为了显示,需要对幅度的大小进行伸缩
dTmp /= 100 ;
// 限制图象数据的大小
dTmp = min(dTmp, 255) ;
lpImage[y*nSaveWidth +x] = (unsigned char)(int)dTmp;
}
}
// 为了在屏幕上显示,我们把幅度值大的部分用黑色显示
for(y=0; y<nHeight; y++)
{
for(x=0; x<nWidth; x++)
{
lpImage[y*nSaveWidth +x] = 255 - lpImage[y*nSaveWidth +x];
}
}
// 释放内存
delete pTrRstRpart;
pTrRstRpart=NULL ;
delete pTrRstIpart;
pTrRstIpart=NULL ;
// 设置脏标记
pDoc->SetModifiedFlag(TRUE);
// 更新视图
pDoc->UpdateAllViews(NULL);
// 恢复光标形状
EndWaitCursor();
// 刷新屏幕
Invalidate();
}
void CImageProcessingView::OnFreqDct()
{
// 图象的离散余弦变换
// 更改光标形状
BeginWaitCursor();
// 获取文档
CImageProcessingDoc* pDoc = GetDocument();
// 获得图象CDib类的指针
CDib * pDib = pDoc->m_pDibInit;
// 获得图象的头文件信息
LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
// 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的离散余弦变换)
if (lpBMIH->biBitCount != 8)
{
// 提示用户
MessageBox("目前只支持256色位图的离散余弦变换!", "系统提示" ,
MB_ICONINFORMATION | MB_OK);
// 返回
return;
}
::DIBDct(pDib);
// 设置脏标记
pDoc->SetModifiedFlag(TRUE);
// 更新视图
pDoc->UpdateAllViews(NULL);
// 恢复光标
EndWaitCursor();
}
void CImageProcessingView::OnFreqHotelling()
{
// 图象霍特林变换
// 更改光标形状
BeginWaitCursor();
// 获取文档
CImageProcessingDoc* pDoc = GetDocument();
// 获得图象CDib类的指针
CDib * pDib = pDoc->m_pDibInit;
// 获得图象的头文件信息
LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
// 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的离散霍特林变换)
if (lpBMIH->biBitCount != 8)
{
// 提示用户
MessageBox("目前只支持256色位图的离散霍特林变换!", "系统提示" ,
MB_ICONINFORMATION | MB_OK);
// 返回
return;
}
// 图象的霍特林变换
DIBHOTELLING(pDib);
// 设置脏标记
pDoc->SetModifiedFlag(TRUE);
// 更新视图
pDoc->UpdateAllViews(NULL);
// 恢复光标
EndWaitCursor();
}
void CImageProcessingView::OnFreqWalsh()
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -