CImageProcessView.cpp

来源:互联网 发布:淘宝的热线电话 编辑:程序博客网 时间:2024/04/28 17:35
// ImageProcessView.cpp : implementation of the CImageProcessView class//#include "stdafx.h"#include "ImageProcess.h"#include "ImageProcessDoc.h"#include "ImageProcessView.h"#include "MainFrm.h"#include "afxole.h"#include "math.h"#include "atlimage.h"#include "CDemoTimer.h"// 编码表RGB数组#include "ColorTable.inc"//颜色表#include "Matrix.h"#include "LEquations.h"#include <stack>#include <queue>#include <list>#include <afxtempl.h>#include <vector>//using namespace std;#ifdef _DEBUG#define new DEBUG_NEW#endifconst double Pi=3.14159;const int TWOVALUE_H=0x80;const int TWOVALUE_L=0x0;int m_ModelWidth;int m_ModelHeight;unsigned char* m_pModelData=NULL;const int TIMER_AVI=0;// CImageProcessViewIMPLEMENT_DYNCREATE(CImageProcessView, CScrollView)BEGIN_MESSAGE_MAP(CImageProcessView, CScrollView)// Standard printing commandsON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)ON_COMMAND(ID_FILE_RE, &CImageProcessView::OnFileReOpen)ON_UPDATE_COMMAND_UI(ID_FILE_RE, &CImageProcessView::OnUpdateFileReOpen)ON_COMMAND(ID_EDIT_PASTE, &CImageProcessView::OnEditPaste)ON_COMMAND(ID_EDIT_COPY, &CImageProcessView::OnEditCopy)ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, &CImageProcessView::OnUpdateEditCopy)ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, &CImageProcessView::OnUpdateEditPaste)ON_WM_LBUTTONDOWN()ON_WM_LBUTTONUP()ON_WM_MOUSEMOVE()ON_COMMAND(ID_EDIT_CUT, &CImageProcessView::OnEditCut)ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, &CImageProcessView::OnUpdateEditCut)ON_COMMAND(ID_VIEW_SELECTAREAMAXIMUM, &CImageProcessView::OnViewSelectareamaximum)ON_UPDATE_COMMAND_UI(ID_VIEW_SELECTAREAMAXIMUM, &CImageProcessView::OnUpdateViewSelectareamaximum)ON_COMMAND(ID_VIEW_INFORMATION, &CImageProcessView::OnViewInformation)ON_UPDATE_COMMAND_UI(ID_VIEW_INFORMATION, &CImageProcessView::OnUpdateViewInformation)ON_COMMAND(ID_HISTGRAM_GRAY, &CImageProcessView::OnHistgramGray)ON_UPDATE_COMMAND_UI(ID_HISTGRAM_GRAY, &CImageProcessView::OnUpdateHistgramGray)ON_COMMAND(ID_HISTGRAM_RGB, &CImageProcessView::OnHistgramRgb)ON_UPDATE_COMMAND_UI(ID_HISTGRAM_RGB, &CImageProcessView::OnUpdateHistgramRgb)ON_COMMAND(ID_HISTGRAM_HSI, &CImageProcessView::OnHistgramHsi)ON_UPDATE_COMMAND_UI(ID_HISTGRAM_HSI, &CImageProcessView::OnUpdateHistgramHsi)ON_COMMAND(ID_PREPROCESS_GRAY, &CImageProcessView::OnPreprocessGray)ON_UPDATE_COMMAND_UI(ID_PREPROCESS_GRAY, &CImageProcessView::OnUpdatePreprocessGray)ON_COMMAND(ID_PREPROCESS_PSDEOCOLORDISPLAY, &CImageProcessView::OnPreprocessPsdeocolordisplay)ON_UPDATE_COMMAND_UI(ID_PREPROCESS_PSDEOCOLORDISPLAY, &CImageProcessView::OnUpdatePreprocessPsdeocolordisplay)ON_COMMAND(ID_PREPROCESS_NEGATIVEIMAGE, &CImageProcessView::OnPreprocessNegativeimage)ON_UPDATE_COMMAND_UI(ID_PREPROCESS_NEGATIVEIMAGE, &CImageProcessView::OnUpdatePreprocessNegativeimage)ON_COMMAND(ID_HISTGRAM_EQUALIZER, &CImageProcessView::OnHistgramEqualizer)ON_UPDATE_COMMAND_UI(ID_HISTGRAM_EQUALIZER, &CImageProcessView::OnUpdateHistgramEqualizer)ON_COMMAND(ID_HISTGRAM_ROBUSTNORMALIZATION, &CImageProcessView::OnHistgramRobustnormalization)ON_UPDATE_COMMAND_UI(ID_HISTGRAM_ROBUSTNORMALIZATION, &CImageProcessView::OnUpdateHistgramRobustnormalization)ON_COMMAND(ID_GAMM_BRIGHT, &CImageProcessView::OnGammBright)ON_UPDATE_COMMAND_UI(ID_GAMM_DARK, &CImageProcessView::OnUpdateGammDark)ON_COMMAND(ID_GAMM_DARK, &CImageProcessView::OnGammDark)ON_UPDATE_COMMAND_UI(ID_GAMM_BRIGHT, &CImageProcessView::OnUpdateGammBright)ON_COMMAND(ID_ADDNOISE_GUASS, &CImageProcessView::OnAddnoiseGuass)ON_COMMAND(ID_ADDNOISE_SALTPEPPER, &CImageProcessView::OnAddnoiseSaltpepper)ON_UPDATE_COMMAND_UI(ID_ADDNOISE_GUASS, &CImageProcessView::OnUpdateAddnoiseGuass)ON_UPDATE_COMMAND_UI(ID_ADDNOISE_SALTPEPPER, &CImageProcessView::OnUpdateAddnoiseSaltpepper)ON_COMMAND(ID_HISTGRAM_LOCAL, &CImageProcessView::OnHistgramLocal)ON_UPDATE_COMMAND_UI(ID_HISTGRAM_LOCAL, &CImageProcessView::OnUpdateHistgramLocal)ON_COMMAND(ID_PREPROCESS_LAPLACESHARPEN, &CImageProcessView::OnPreprocessLaplacesharpen)ON_UPDATE_COMMAND_UI(ID_PREPROCESS_LAPLACESHARPEN, &CImageProcessView::OnUpdatePreprocessLaplacesharpen)ON_COMMAND(ID_SMOOTH_MEANFILTER, &CImageProcessView::OnSmoothMeanfilter)ON_UPDATE_COMMAND_UI(ID_SMOOTH_MEANFILTER, &CImageProcessView::OnUpdateSmoothMeanfilter)ON_COMMAND(ID_SMOOTH_GAUSSFILTER, &CImageProcessView::OnSmoothGaussfilter)ON_UPDATE_COMMAND_UI(ID_SMOOTH_GAUSSFILTER, &CImageProcessView::OnUpdateSmoothGaussfilter)ON_COMMAND(ID_SMOOTH_MEDIANFILTER, &CImageProcessView::OnSmoothMedianfilter)ON_UPDATE_COMMAND_UI(ID_SMOOTH_MEDIANFILTER, &CImageProcessView::OnUpdateSmoothMedianfilter)ON_COMMAND(ID_SMOOTH_COLORFILTER, &CImageProcessView::OnSmoothColorfilter)ON_UPDATE_COMMAND_UI(ID_SMOOTH_COLORFILTER, &CImageProcessView::OnUpdateSmoothColorfilter)ON_COMMAND(ID_FREQUENCYDOMAIN_FFT, &CImageProcessView::OnFrequencydomainFft)ON_UPDATE_COMMAND_UI(ID_FREQUENCYDOMAIN_FFT, &CImageProcessView::OnUpdateFrequencydomainFft)ON_COMMAND(ID_BUTTERWORTH_LOWFILTER, &CImageProcessView::OnButterworthLowfilter)ON_COMMAND(ID_BUTTERWORTH_HIGHFILTER, &CImageProcessView::OnButterworthHighfilter)ON_UPDATE_COMMAND_UI(ID_BUTTERWORTH_LOWFILTER, &CImageProcessView::OnUpdateButterworthLowfilter)ON_UPDATE_COMMAND_UI(ID_BUTTERWORTH_HIGHFILTER, &CImageProcessView::OnUpdateButterworthHighfilter)ON_COMMAND(ID_FREQUENCYDOMAIN_HOMOMORPHICFILTER, &CImageProcessView::OnFrequencydomainHomomorphicfilter)ON_UPDATE_COMMAND_UI(ID_FREQUENCYDOMAIN_HOMOMORPHICFILTER, &CImageProcessView::OnUpdateFrequencydomainHomomorphicfilter)ON_COMMAND(ID_FILE_GETMODAL, &CImageProcessView::OnFileGetmodal)ON_UPDATE_COMMAND_UI(ID_FILE_GETMODAL, &CImageProcessView::OnUpdateFileGetmodal)ON_COMMAND(ID_SPATIALDOMAIN_IMAGE, &CImageProcessView::OnSpatialdomainImage)ON_UPDATE_COMMAND_UI(ID_SPATIALDOMAIN_IMAGE, &CImageProcessView::OnUpdateSpatialdomainImage)ON_COMMAND(ID_CONVOLUTION_MEAN, &CImageProcessView::OnConvolutionMean)ON_UPDATE_COMMAND_UI(ID_CONVOLUTION_MEAN, &CImageProcessView::OnUpdateConvolutionMean)ON_COMMAND(ID_CONVOLUTION_GAUSS, &CImageProcessView::OnConvolutionGauss)ON_UPDATE_COMMAND_UI(ID_CONVOLUTION_GAUSS, &CImageProcessView::OnUpdateConvolutionGauss)ON_COMMAND(ID_CONVOLUTION_LAPLACE, &CImageProcessView::OnConvolutionLaplace)ON_UPDATE_COMMAND_UI(ID_CONVOLUTION_LAPLACE, &CImageProcessView::OnUpdateConvolutionLaplace)ON_COMMAND(ID_CONVOLUTION_MARR, &CImageProcessView::OnConvolutionMarr)ON_UPDATE_COMMAND_UI(ID_CONVOLUTION_MARR, &CImageProcessView::OnUpdateConvolutionMarr)ON_COMMAND(ID_CONVOLUTION_CORRELATION, &CImageProcessView::OnConvolutionCorrelation)ON_UPDATE_COMMAND_UI(ID_CONVOLUTION_CORRELATION, &CImageProcessView::OnUpdateConvolutionCorrelation)ON_COMMAND(ID_ADAPTIVE_NOISEREDUCTION, &CImageProcessView::OnAdaptiveNoisereduction)ON_UPDATE_COMMAND_UI(ID_ADAPTIVE_NOISEREDUCTION, &CImageProcessView::OnUpdateAdaptiveNoisereduction)ON_COMMAND(ID_ADAPTIVE_MEDIAN, &CImageProcessView::OnAdaptiveMedian)ON_UPDATE_COMMAND_UI(ID_ADAPTIVE_MEDIAN, &CImageProcessView::OnUpdateAdaptiveMedian)ON_COMMAND(ID_FREQUENCYDOMAIN_NOTCHPASSFILTER, &CImageProcessView::OnFrequencydomainNotchpassfilter)ON_UPDATE_COMMAND_UI(ID_FREQUENCYDOMAIN_NOTCHPASSFILTER, &CImageProcessView::OnUpdateFrequencydomainNotchpassfilter)ON_COMMAND(ID_FREQUENCYDOMAIN_OPTIMUMNOTCHFILTER, &CImageProcessView::OnFrequencydomainOptimumnotchfilter)ON_UPDATE_COMMAND_UI(ID_FREQUENCYDOMAIN_OPTIMUMNOTCHFILTER, &CImageProcessView::OnUpdateFrequencydomainOptimumnotchfilter)ON_COMMAND(ID_FREQUENCYDOMAIN_WINNERFILTER, &CImageProcessView::OnFrequencydomainWinnerfilter)ON_UPDATE_COMMAND_UI(ID_FREQUENCYDOMAIN_WINNERFILTER, &CImageProcessView::OnUpdateFrequencydomainWinnerfilter)ON_COMMAND(ID_FREQUENCYDOMAIN_LEASTSQUARESFILTER, &CImageProcessView::OnFrequencydomainLeastsquaresfilter)ON_UPDATE_COMMAND_UI(ID_FREQUENCYDOMAIN_LEASTSQUARESFILTER, &CImageProcessView::OnUpdateFrequencydomainLeastsquaresfilter)ON_COMMAND(ID_SPATIALDOMAIN_GEOMETRICTRANSFORMATIONS, &CImageProcessView::OnSpatialdomainGeometrictransformations)ON_UPDATE_COMMAND_UI(ID_SPATIALDOMAIN_GEOMETRICTRANSFORMATIONS, &CImageProcessView::OnUpdateSpatialdomainGeometrictransformations)ON_COMMAND(ID_DWT_DWT, &CImageProcessView::OnDwtDwt)ON_UPDATE_COMMAND_UI(ID_DWT_DWT, &CImageProcessView::OnUpdateDwtDwt)ON_COMMAND(ID_DWT_IDWT, &CImageProcessView::OnDwtIdwt)ON_UPDATE_COMMAND_UI(ID_DWT_IDWT, &CImageProcessView::OnUpdateDwtIdwt)ON_COMMAND(ID_EDGE_ALL, &CImageProcessView::OnEdgeAll)ON_UPDATE_COMMAND_UI(ID_EDGE_ALL, &CImageProcessView::OnUpdateEdgeAll)ON_COMMAND(ID_EDGE_H, &CImageProcessView::OnEdgeH)ON_UPDATE_COMMAND_UI(ID_EDGE_H, &CImageProcessView::OnUpdateEdgeH)ON_COMMAND(ID_EDGE_V, &CImageProcessView::OnEdgeV)ON_UPDATE_COMMAND_UI(ID_EDGE_V, &CImageProcessView::OnUpdateEdgeV)ON_COMMAND(ID_DWT_SMOTH, &CImageProcessView::OnDwtSmooth)ON_UPDATE_COMMAND_UI(ID_DWT_SMOTH, &CImageProcessView::OnUpdateDwtSmooth)ON_COMMAND(ID_MORPHOLOGICAL_DILATION, &CImageProcessView::OnMorphologicalDilation)ON_UPDATE_COMMAND_UI(ID_MORPHOLOGICAL_DILATION, &CImageProcessView::OnUpdateMorphologicalDilation)ON_COMMAND(ID_MORPHOLOGICAL_EROSION, &CImageProcessView::OnMorphologicalErosion)ON_UPDATE_COMMAND_UI(ID_MORPHOLOGICAL_EROSION, &CImageProcessView::OnUpdateMorphologicalErosion)ON_COMMAND(ID_MORPHOLOGICAL_OPEN, &CImageProcessView::OnMorphologicalOpen)ON_UPDATE_COMMAND_UI(ID_MORPHOLOGICAL_OPEN, &CImageProcessView::OnUpdateMorphologicalOpen)ON_COMMAND(ID_MORPHOLOGICAL_CLOSE, &CImageProcessView::OnMorphologicalClose)ON_UPDATE_COMMAND_UI(ID_MORPHOLOGICAL_CLOSE, &CImageProcessView::OnUpdateMorphologicalClose)ON_COMMAND(ID_SEGMENTATION_FIXEDTHRESHOLD, &CImageProcessView::OnSegmentationFixedthreshold)ON_UPDATE_COMMAND_UI(ID_SEGMENTATION_FIXEDTHRESHOLD, &CImageProcessView::OnUpdateSegmentationFixedthreshold)ON_COMMAND(ID_MORPHOLOGICAL_HITORMISS, &CImageProcessView::OnMorphologicalHitormiss)ON_UPDATE_COMMAND_UI(ID_MORPHOLOGICAL_HITORMISS, &CImageProcessView::OnUpdateMorphologicalHitormiss)ON_COMMAND(ID_APPLICATION_BOUNDARYEXTRACTION, &CImageProcessView::OnApplicationBoundaryextraction)ON_UPDATE_COMMAND_UI(ID_APPLICATION_BOUNDARYEXTRACTION, &CImageProcessView::OnUpdateApplicationBoundaryextraction)ON_COMMAND(ID_APPLICATION_REGIONFILLING, &CImageProcessView::OnApplicationRegionfilling)ON_UPDATE_COMMAND_UI(ID_APPLICATION_REGIONFILLING, &CImageProcessView::OnUpdateApplicationRegionfilling)ON_COMMAND(ID_APPLICATION_CONNECTEDCOMPONENTS, &CImageProcessView::OnApplicationConnectedcomponents)ON_UPDATE_COMMAND_UI(ID_APPLICATION_CONNECTEDCOMPONENTS, &CImageProcessView::OnUpdateApplicationConnectedcomponents)ON_COMMAND(ID_APPLICATION_CONVEXHULL, &CImageProcessView::OnApplicationConvexhull)ON_UPDATE_COMMAND_UI(ID_APPLICATION_CONVEXHULL, &CImageProcessView::OnUpdateApplicationConvexhull)ON_COMMAND(ID_APPLICATION_THIN, &CImageProcessView::OnApplicationThin)ON_UPDATE_COMMAND_UI(ID_APPLICATION_THIN, &CImageProcessView::OnUpdateApplicationThin)ON_COMMAND(ID_APPLICATION_PRUNED, &CImageProcessView::OnApplicationPruned)ON_UPDATE_COMMAND_UI(ID_APPLICATION_PRUNED, &CImageProcessView::OnUpdateApplicationPruned)ON_COMMAND(ID_GRAY_DILATION, &CImageProcessView::OnGrayDilation)ON_UPDATE_COMMAND_UI(ID_GRAY_DILATION, &CImageProcessView::OnUpdateGrayDilation)ON_COMMAND(ID_GRAY_EROSION, &CImageProcessView::OnGrayErosion)ON_UPDATE_COMMAND_UI(ID_GRAY_EROSION, &CImageProcessView::OnUpdateGrayErosion)ON_COMMAND(ID_GRAY_OPEN, &CImageProcessView::OnGrayOpen)ON_UPDATE_COMMAND_UI(ID_GRAY_OPEN, &CImageProcessView::OnUpdateGrayOpen)ON_COMMAND(ID_GRAY_CLOSE, &CImageProcessView::OnGrayClose)ON_UPDATE_COMMAND_UI(ID_GRAY_CLOSE, &CImageProcessView::OnUpdateGrayClose)ON_COMMAND(ID_GRAY_GRADIENT, &CImageProcessView::OnGrayGradient)ON_UPDATE_COMMAND_UI(ID_GRAY_GRADIENT, &CImageProcessView::OnUpdateGrayGradient)ON_COMMAND(ID_GRAY_TOPHAT, &CImageProcessView::OnGrayTophat)ON_UPDATE_COMMAND_UI(ID_GRAY_TOPHAT, &CImageProcessView::OnUpdateGrayTophat)ON_COMMAND(ID_EDGE_SOBEL, &CImageProcessView::OnEdgeSobel)ON_UPDATE_COMMAND_UI(ID_EDGE_SOBEL, &CImageProcessView::OnUpdateEdgeSobel)ON_COMMAND(ID_EDGE_LAPLACE, &CImageProcessView::OnEdgeLaplace)ON_UPDATE_COMMAND_UI(ID_EDGE_LAPLACE, &CImageProcessView::OnUpdateEdgeLaplace)ON_COMMAND(ID_EDGE_LOG, &CImageProcessView::OnEdgeLog)ON_UPDATE_COMMAND_UI(ID_EDGE_LOG, &CImageProcessView::OnUpdateEdgeLog)ON_COMMAND(ID_HOUGH_LINES, &CImageProcessView::OnHoughLines)ON_UPDATE_COMMAND_UI(ID_HOUGH_LINES, &CImageProcessView::OnUpdateHoughLines)ON_COMMAND(ID_SEGMENTATION_REGIONGROWING, &CImageProcessView::OnSegmentationRegiongrowing)ON_UPDATE_COMMAND_UI(ID_SEGMENTATION_REGIONGROWING, &CImageProcessView::OnUpdateSegmentationRegiongrowing)ON_COMMAND(ID_SEGMENTATION_WATERSHED, &CImageProcessView::OnSegmentationWatershed)ON_UPDATE_COMMAND_UI(ID_SEGMENTATION_WATERSHED, &CImageProcessView::OnUpdateSegmentationWatershed)ON_COMMAND(ID_APPLICATION_THINBYCONDITION, &CImageProcessView::OnApplicationThinbycondition)ON_UPDATE_COMMAND_UI(ID_APPLICATION_THINBYCONDITION, &CImageProcessView::OnUpdateApplicationThinbycondition)ON_COMMAND(ID_OBJECTRECOGNITION_CORRELATIONMATCH, &CImageProcessView::OnObjectrecognitionCorrelationmatch)ON_UPDATE_COMMAND_UI(ID_OBJECTRECOGNITION_CORRELATIONMATCH, &CImageProcessView::OnUpdateObjectrecognitionCorrelationmatch)ON_COMMAND(ID_MORPHOLOGICAL_DISTANCETRANSFORM, &CImageProcessView::OnMorphologicalDistancetransform)ON_UPDATE_COMMAND_UI(ID_MORPHOLOGICAL_DISTANCETRANSFORM, &CImageProcessView::OnUpdateMorphologicalDistancetransform)ON_COMMAND(ID_APPLICATION_SEPARATEOBJECT, &CImageProcessView::OnApplicationSeparateobject)ON_UPDATE_COMMAND_UI(ID_APPLICATION_SEPARATEOBJECT, &CImageProcessView::OnUpdateApplicationSeparateobject)ON_COMMAND(ID_WATERSHEDPROCESS_GETSEED, &CImageProcessView::OnWatershedprocessGetseed)ON_UPDATE_COMMAND_UI(ID_WATERSHEDPROCESS_GETSEED, &CImageProcessView::OnUpdateWatershedprocessGetseed)ON_COMMAND(ID_WATERSHEDPROCESS_LABELMARKED, &CImageProcessView::OnWatershedprocessLabelmarked)ON_UPDATE_COMMAND_UI(ID_WATERSHEDPROCESS_LABELMARKED, &CImageProcessView::OnUpdateWatershedprocessLabelmarked)ON_COMMAND(ID_WATERSHEDPROCESS_GETAREAS, &CImageProcessView::OnWatershedprocessGetareas)ON_UPDATE_COMMAND_UI(ID_WATERSHEDPROCESS_GETAREAS, &CImageProcessView::OnUpdateWatershedprocessGetareas)ON_COMMAND(ID_SEGMENTATION_OSTU, &CImageProcessView::OnSegmentationOstu)ON_UPDATE_COMMAND_UI(ID_SEGMENTATION_OSTU, &CImageProcessView::OnUpdateSegmentationOstu)ON_COMMAND(ID_SEGMENTATION_ENTROPY, &CImageProcessView::OnSegmentationEntropy)ON_UPDATE_COMMAND_UI(ID_SEGMENTATION_ENTROPY, &CImageProcessView::OnUpdateSegmentationEntropy)ON_COMMAND(ID_SEGMENTATION_MAXLIKELIHOOD, &CImageProcessView::OnSegmentationMaxlikelihood)ON_UPDATE_COMMAND_UI(ID_SEGMENTATION_MAXLIKELIHOOD, &CImageProcessView::OnUpdateSegmentationMaxlikelihood)ON_COMMAND(ID_SEGMENTATION_LOCALTHRESHOLDING, &CImageProcessView::OnSegmentationLocalthresholding)ON_UPDATE_COMMAND_UI(ID_SEGMENTATION_LOCALTHRESHOLDING, &CImageProcessView::OnUpdateSegmentationLocalthresholding)ON_COMMAND(ID_APPLICATION_PARALLELTHIN, &CImageProcessView::OnApplicationParallelthin)ON_UPDATE_COMMAND_UI(ID_APPLICATION_PARALLELTHIN, &CImageProcessView::OnUpdateApplicationParallelthin)ON_COMMAND(ID_HOUGH_FONTOFNORMAL, &CImageProcessView::OnHoughFontofnormal)ON_UPDATE_COMMAND_UI(ID_HOUGH_FONTOFNORMAL, &CImageProcessView::OnUpdateHoughFontofnormal)ON_COMMAND(ID_CIRCLEDETECTION_CHORDBISECTIONALG, &CImageProcessView::OnCircledetectionChordbisectionalg)ON_UPDATE_COMMAND_UI(ID_CIRCLEDETECTION_CHORDBISECTIONALG, &CImageProcessView::OnUpdateCircledetectionChordbisectionalg)ON_COMMAND(ID_CIRCLEDETECTION_ACURR, &CImageProcessView::OnCircledetectionAcurr)ON_UPDATE_COMMAND_UI(ID_CIRCLEDETECTION_ACURR, &CImageProcessView::OnUpdateCircledetectionAcurr)ON_COMMAND(ID_HISTGRAM_GRAYBAR, &CImageProcessView::OnHistgramGrayBar)ON_UPDATE_COMMAND_UI(ID_HISTGRAM_GRAYBAR, &CImageProcessView::OnUpdateHistgramGrayBar)ON_COMMAND(ID_HISTGRAM_RGBBAR, &CImageProcessView::OnHistgramRgbbar)ON_UPDATE_COMMAND_UI(ID_HISTGRAM_RGBBAR, &CImageProcessView::OnUpdateHistgramRgbbar)ON_COMMAND(ID_HISTGRAM_HSIBAR, &CImageProcessView::OnHistgramHsibar)ON_UPDATE_COMMAND_UI(ID_HISTGRAM_HSIBAR, &CImageProcessView::OnUpdateHistgramHsibar)ON_COMMAND(ID_OBJECTRECOGNITION_PLESSEYCORNERDETECTOR, &CImageProcessView::OnObjectrecognitionPlesseycornerdetector)ON_UPDATE_COMMAND_UI(ID_OBJECTRECOGNITION_PLESSEYCORNERDETECTOR, &CImageProcessView::OnUpdateObjectrecognitionPlesseycornerdetector)ON_COMMAND(ID_EDGE_CANNY, &CImageProcessView::OnEdgeCanny)ON_UPDATE_COMMAND_UI(ID_EDGE_CANNY, &CImageProcessView::OnUpdateEdgeCanny)ON_COMMAND(ID_SEGMENTATION_OPTIMAL, &CImageProcessView::OnSegmentationOptimal)ON_UPDATE_COMMAND_UI(ID_SEGMENTATION_OPTIMAL, &CImageProcessView::OnUpdateSegmentationOptimal)ON_COMMAND(ID_EDGE_NON, &CImageProcessView::OnEdgeNon)ON_UPDATE_COMMAND_UI(ID_EDGE_NON, &CImageProcessView::OnUpdateEdgeNon)ON_COMMAND(ID_EDGE_HYSTERESIS, &CImageProcessView::OnEdgeHysteresis)ON_UPDATE_COMMAND_UI(ID_EDGE_HYSTERESIS, &CImageProcessView::OnUpdateEdgeHysteresis)ON_COMMAND(ID_HOUGH_CIRCLE, &CImageProcessView::OnHoughCircle)ON_UPDATE_COMMAND_UI(ID_HOUGH_CIRCLE, &CImageProcessView::OnUpdateHoughCircle)ON_COMMAND(ID_SEGMENTATION_DYNAMIC, &CImageProcessView::OnSegmentationDynamic)ON_UPDATE_COMMAND_UI(ID_SEGMENTATION_DYNAMIC, &CImageProcessView::OnUpdateSegmentationDynamic)ON_COMMAND(ID_SPATIALDOMAIN_ZOOMBILINEARINTERPOLATION, &CImageProcessView::OnSpatialdomainZoombilinearinterpolation)ON_UPDATE_COMMAND_UI(ID_SPATIALDOMAIN_ZOOMBILINEARINTERPOLATION, &CImageProcessView::OnUpdateSpatialdomainZoombilinearinterpolation)ON_UPDATE_COMMAND_UI(ID_APPLICATION_CONTOURTRACE, &CImageProcessView::OnUpdateApplicationContourtrace)ON_COMMAND(ID_APPLICATION_CONTOURTRACE, &CImageProcessView::OnApplicationContourtrace)ON_COMMAND(ID_EDGE_TRACE, &CImageProcessView::OnEdgeTrace)ON_UPDATE_COMMAND_UI(ID_EDGE_TRACE, &CImageProcessView::OnUpdateEdgeTrace)ON_WM_KEYDOWN()ON_COMMAND(ID_SMOOTH_TRUN, &CImageProcessView::OnSmoothTrun)ON_UPDATE_COMMAND_UI(ID_SMOOTH_TRUN, &CImageProcessView::OnUpdateSmoothTrun)ON_COMMAND(ID_SMOOTH_ANISOTROPICDIFFUSION, &CImageProcessView::OnSmoothAnisotropicdiffusion)ON_UPDATE_COMMAND_UI(ID_SMOOTH_ANISOTROPICDIFFUSION, &CImageProcessView::OnUpdateSmoothAnisotropicdiffusion)ON_COMMAND(ID_GRAY_RECONSTRUCTION, &CImageProcessView::OnGrayReconstruction)ON_COMMAND(ID_EDGE_RELAXATION, &CImageProcessView::OnEdgeRelaxation)ON_UPDATE_COMMAND_UI(ID_EDGE_RELAXATION, &CImageProcessView::OnUpdateEdgeRelaxation)ON_COMMAND(ID_SEGMENTATION_BOUNDARYTRACE, &CImageProcessView::OnSegmentationBoundarytrace)ON_UPDATE_COMMAND_UI(ID_SEGMENTATION_BOUNDARYTRACE, &CImageProcessView::OnUpdateSegmentationBoundarytrace)ON_COMMAND(ID_FILE_OPENAVI, &CImageProcessView::OnFileOpenavi)ON_WM_TIMER()ON_COMMAND(ID_FILE_BMP2AVI, &CImageProcessView::OnFileBmp2avi)ON_WM_RBUTTONDOWN()END_MESSAGE_MAP()// CImageProcessView construction/destructionCImageProcessView::CImageProcessView(){// TODO: add construction code herem_bDrag=false;m_bTwoValue=false;m_bDWT=false;pDlg=NULL;THRESHOLD=100;m_bWatershedProcGetSeed=false;m_AviBuff=NULL;}CImageProcessView::~CImageProcessView(){if(m_pModelData)delete []m_pModelData;m_pModelData=NULL;//must do it else heap err !!! m_bWatershedProcGetSeed=false;if(pDlg){   delete []pDlg->pData;delete pDlg;//无模式对话框pDlg=NULL;}}BOOL CImageProcessView::PreCreateWindow(CREATESTRUCT& cs){// TODO: Modify the Window class or styles here by modifying//  the CREATESTRUCT csreturn CScrollView::PreCreateWindow(cs);}// CImageProcessView drawingvoid CImageProcessView::OnDraw(CDC* pDC){CImageProcessDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);if (!pDoc)return;CSize sizeTotal;if(pDoc->m_pDib->m_lpBMIH!=NULL){//if< image size some image part cann't see!sizeTotal.cx =pDoc->m_pDib->m_lpBMIH->biWidth+4;//change it ,no use? big enough then have barsizeTotal.cy= pDoc->m_pDib->m_lpBMIH->biHeight+4;//big enough then have barSetScrollSizes(MM_TEXT, sizeTotal);//must have ;use scrollResizeParentToFit( );   }// TODO: add draw code for native data here//填充底色为灰CRect m_rcClient;GetClientRect(&m_rcClient);CBrush m_brsBG;m_brsBG.CreateSolidBrush(RGB(192,192,192));//COLOR_GRAY;pDC->FillRect(&m_rcClient, &m_brsBG);if (pDoc->m_pDib->m_lpBMIH!=NULL){CSize sizeFileDib=pDoc->m_pDib->GetDimensions();pDoc->m_pDib->Draw(pDC,CPoint(0,0),sizeFileDib);lWidth =pDoc->m_pDib->m_lpBMIH->biWidth;          // Size of DIB - xlHeight= pDoc->m_pDib->m_lpBMIH->biHeight;        // Size of DIB - y//if Select Area is error,init if(pDoc->EndPoint.x-pDoc->StartPoint.x<=5 || pDoc->EndPoint.x>lWidth-1 ||pDoc->EndPoint.y-pDoc->StartPoint.y<=5 || pDoc->EndPoint.y>lHeight-1 || pDoc->StartPoint.y<0 || pDoc->StartPoint.x<0){pDoc->StartPoint.x=0;pDoc->StartPoint.y=0;pDoc->EndPoint.x=lWidth-1;pDoc->EndPoint.y=lHeight-1;}if(pDoc->m_pDib->m_lpBMIH->biBitCount==8 ){lLineBytes=lWidth & 0xffc;if(lWidth%4) lLineBytes+=4;//if TwoValue?m_bTwoValue=true;unsigned char* lpSrc;for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc =(unsigned char *)pDoc->m_pDib->m_lpImage+  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x;// 针对每行图像每列进行操作for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){if(*lpSrc & 0x70){m_bTwoValue=false;i =pDoc->EndPoint.y+1;//outj =pDoc->EndPoint.x+1;}lpSrc++;//}}}else if(pDoc->m_pDib->m_lpBMIH->biBitCount==24 )lLineBytes =(lWidth *3+3)/4*4;else if(pDoc->m_pDib->m_lpBMIH->biBitCount==32 )lLineBytes =lWidth *4;if(pDoc->StartPoint.y >0 || pDoc->StartPoint.x >0 || pDoc->EndPoint.y <lHeight-1 || pDoc->EndPoint.x <lWidth-1  ){//not all areaCPen myPen;myPen.CreatePen(PS_DOT, 1, RGB(255,0,0));pDC->SelectObject(myPen);pDC->SelectObject(GetStockObject(NULL_BRUSH));pDC->Rectangle(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y));}}else{pDC->SetBkMode(TRANSPARENT);pDC->TextOut(50,100,"Open an Image !");}}// CImageProcessView printingBOOL CImageProcessView::OnPreparePrinting(CPrintInfo* pInfo){// default preparationreturn DoPreparePrinting(pInfo);}void CImageProcessView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/){// TODO: add extra initialization before printing}void CImageProcessView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/){// TODO: add cleanup after printing}// CImageProcessView diagnostics#ifdef _DEBUGvoid CImageProcessView::AssertValid() const{CScrollView::AssertValid();}void CImageProcessView::Dump(CDumpContext& dc) const{CScrollView::Dump(dc);}CImageProcessDoc* CImageProcessView::GetDocument() const // non-debug version is inline{ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CImageProcessDoc)));return (CImageProcessDoc*)m_pDocument;}#endif //_DEBUG// CImageProcessView message handlersvoid CImageProcessView::OnInitialUpdate(){CScrollView::OnInitialUpdate();// TODO: Add your specialized code here and/or call the base classCImageProcessDoc* pDoc = GetDocument();static bool first=true;//do it once,must have it for DisplayNewImg()if (pDoc->m_pDib->m_lpBMIH==NULL && first){first=false;CString m_fileName;//=("c:\\tu\\Iris.bmp");char strDirName[80]; GetCurrentDirectory(80, (LPSTR)strDirName);CString pathName;pathName.Format(_T("%s"),strDirName);m_fileName=pathName+"\\lena.bmp";CFile file;if( file.Open(m_fileName,CFile::modeRead | CFile::shareDenyWrite,NULL)){pDoc->m_pDib->Read(&file);file.Close();pDoc->SetPathName(m_fileName);//if not cannot get pDoc->GetPathName}}CSize sizeTotal;if(pDoc->m_pDib->m_lpBMIH==NULL){sizeTotal.cx =512+4;sizeTotal.cy= 512+4;}else{//if< image size some image part cann't see!sizeTotal.cx =pDoc->m_pDib->m_lpBMIH->biWidth+4;//change it ,no use? big enough then have barsizeTotal.cy= pDoc->m_pDib->m_lpBMIH->biHeight+4;//big enough then have bar}SetScrollSizes(MM_TEXT, sizeTotal);//must have ;use scrollResizeParentToFit( );   }void CImageProcessView::OnFileReOpen(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();CFile file;if(NULL!=file.Open(pDoc->GetPathName(),CFile::modeRead | CFile::shareDenyWrite,NULL)){pDoc->m_pDib->Read(&file);file.Close();}}void CImageProcessView::OnUpdateFileReOpen(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnEditPaste(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();COleDataObject dataObject;VERIFY(dataObject.AttachClipboard());// Seems to be MOVEABLE memory, so we must use GlobalLock!//  (hDib != lpDib) GetGlobalData copies the memory, so we can//  hang onto it until we delete the CDib.HGLOBAL hDib = dataObject.GetGlobalData(CF_DIB);ASSERT(hDib != NULL);LPVOID lpDib = ::GlobalLock(hDib);ASSERT(lpDib != NULL);pDoc->m_pDib->AttachMemory(lpDib, TRUE, hDib);CClientDC dc(this);pDoc->m_pDib->UsePalette(&dc);pDoc->SetModifiedFlag();pDoc->UpdateAllViews(NULL);}void CImageProcessView::OnEditCopy(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();COleDataSource* pSource = new COleDataSource();int nHeaderSize = pDoc->m_pDib->GetSizeHeader();int nImageSize = pDoc->m_pDib->GetSizeImage();HGLOBAL hHeader = ::GlobalAlloc(GMEM_SHARE,nHeaderSize + nImageSize);LPVOID pHeader = ::GlobalLock(hHeader);ASSERT(pHeader != NULL);LPVOID pImage = (LPBYTE) pHeader + nHeaderSize;memcpy(pHeader, pDoc->m_pDib->m_lpBMIH, nHeaderSize); memcpy(pImage, pDoc->m_pDib->m_lpImage, nImageSize);// Receiver is supposed to free the global memory ::GlobalUnlock(hHeader);pSource->CacheGlobalData(CF_DIB, hHeader);if (pSource) pSource->SetClipboard(); // OLE deletes data source}void CImageProcessView::OnUpdateEditCopy(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnUpdateEditPaste(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code here//CImageProcessDoc* pDoc = GetDocument();COleDataObject dataObject;BOOL bAvail = dataObject.AttachClipboard() && dataObject.IsDataAvailable(CF_DIB);pCmdUI->Enable(bAvail);}void CImageProcessView::OnLButtonDown(UINT nFlags, CPoint point){// TODO: Add your message handler code here and/or call defaultif(!m_bDrag){m_LastStPoint = point+GetDeviceScrollPosition( );m_LastEndPoint=m_LastStPoint;m_bDrag = true;}//select seedif(m_bWatershedProcGetSeed){CPoint pt=point+GetDeviceScrollPosition( );*(m_pModelData+lLineBytes * (lHeight - 1 - pt.y) + pt.x)=TWOVALUE_H;}CScrollView::OnLButtonDown(nFlags, point);}void CImageProcessView::OnLButtonUp(UINT nFlags, CPoint point){// TODO: Add your message handler code here and/or call defaultCImageProcessDoc* pDoc = GetDocument();m_bDrag = false;//比较点大小,获取区域CPoint pt=point+GetDeviceScrollPosition( );CPoint pt1,pt2;pt1.x=min(m_LastStPoint.x,pt.x);pt1.y=min(m_LastStPoint.y,pt.y);pt2.x=max(m_LastStPoint.x,pt.x);pt2.y=max(m_LastStPoint.y,pt.y);if(pt1.x>0 && pt2.x-pt1.x>5 && pt2.x<lWidth-1&& pt1.y>0 && pt2.y-pt1.y>5 && pt2.y<lHeight-1){//change select areapDoc->StartPoint=pt1;pDoc->EndPoint=pt2;}Invalidate(true);//Draw Rect CScrollView::OnLButtonUp(nFlags, point);}void CImageProcessView::OnMouseMove(UINT nFlags, CPoint point){// TODO: Add your message handler code here and/or call defaultCImageProcessDoc* pDoc = GetDocument();CPoint pt=point+GetDeviceScrollPosition( );if(m_bDrag)//Draw select Rect{RECTlastrect, currect;lastrect.top =min(m_LastStPoint.y,m_LastEndPoint.y)-GetDeviceScrollPosition( ).y;lastrect.left =min(m_LastStPoint.x,m_LastEndPoint.x)-GetDeviceScrollPosition( ).x;lastrect.right =max(m_LastStPoint.x,m_LastEndPoint.x)-GetDeviceScrollPosition( ).x;lastrect.bottom =max(m_LastStPoint.y,m_LastEndPoint.y)-GetDeviceScrollPosition( ).y;currect.top =min(pt.y,m_LastStPoint.y)-GetDeviceScrollPosition( ).y; currect.left =min(pt.x,m_LastStPoint.x)-GetDeviceScrollPosition( ).x; currect.right =max(pt.x,m_LastStPoint.x)-GetDeviceScrollPosition( ).x;currect.bottom = max(pt.y,m_LastStPoint.y)-GetDeviceScrollPosition( ).y;SIZEsz;sz.cx = 1;sz.cy = 1;CDC *pdc = GetDC();CBrush m_brsBG;m_brsBG.CreateSolidBrush(RGB(255,255,255));//;pdc->DrawDragRect(&currect, sz, &lastrect, sz, &m_brsBG,&m_brsBG);//, NULL);//no corlor ReleaseDC(pdc);CString str;//CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;//CStatusBar* pStatus=&pFrame->m_wndStatusBar;//if(pStatus){//str.Format("区域(%d:%d)-(%d:%d)",currect.left,currect.top,currect.right,currect.bottom);//pStatus->SetPaneText(0,str);//}// same as:str.Format("区域(%d:%d)-(%d:%d)",currect.left,currect.top,currect.right,currect.bottom);((CMainFrame*)AfxGetMainWnd())->m_wndStatusBar.SetPaneText(0,str);m_LastEndPoint = pt;}else//display point infomation{m_LastEndPoint=pt;//display point valueCString str;str="";if(pDoc->m_pDib->m_lpBMIH){unsigned char *lpSrc;if((pt.x>=0) && (pt.x<lWidth) && (pt.y>=0) && (pt.y<lHeight)){if(pDoc->m_pDib->m_lpBMIH->biBitCount==8 ){lpSrc=(unsigned char*)pDoc->m_pDib->m_lpImage + lLineBytes*(lHeight - 1 -pt.y) + pt.x;double grad=0.0;double angle=0.0;Gradient(pt,&grad,&angle);str.Format("(x=%d y=%d)=%d\tGradient(%3.1f,%3.1f)",pt.x,pt.y,*lpSrc,grad,angle);}else if(pDoc->m_pDib->m_lpBMIH->biBitCount==24 ){lpSrc=(unsigned char*)pDoc->m_pDib->m_lpImage + lLineBytes*(lHeight - 1 -pt.y) + pt.x*3;RGB rgb;HSI hsi;rgb.b=*lpSrc;rgb.g=*(lpSrc+1);rgb.r=*(lpSrc+2);RgbtoHsi(&rgb, &hsi);int gray=(int)(0.114*rgb.r+0.587*rgb.g+0.299*rgb.b);str.Format("Pos(%d %d) RGB(%d %d %d) Gray(%d) hsi(%4.1f %3.2f %3.2f--%d %d %d)",point.x,point.y,rgb.r,rgb.g,rgb.b,gray,hsi.Hue,hsi.Saturation,hsi.Intensity,(int)(hsi.Hue/360.0*255.0),(int)(hsi.Saturation*255.0),(int)(hsi.Intensity*255.0));}else  if(pDoc->m_pDib->m_lpBMIH->biBitCount==32 ){lpSrc=(unsigned char*)pDoc->m_pDib->m_lpImage + lLineBytes*(lHeight - 1 -pt.y) + pt.x*4;RGB rgb;HSI hsi;rgb.b=*lpSrc;rgb.g=*(lpSrc+1);rgb.r=*(lpSrc+2);//*(lpSrc+3)==*(lpSrc+1)?????RgbtoHsi(&rgb, &hsi);int gray=(int)(0.114*rgb.r+0.587*rgb.g+0.299*rgb.b);str.Format("Pos(%d %d) RGB(%d %d %d)  Gray(%d) hsi(%4.1f %3.2f %3.2f--%d %d %d)",point.x,point.y,rgb.r,rgb.g,rgb.b,gray,hsi.Hue,hsi.Saturation,hsi.Intensity,(int)(hsi.Hue/360.0*255.0),(int)(hsi.Saturation*255.0),(int)(hsi.Intensity*255.0));}((CMainFrame*)AfxGetMainWnd())->m_wndStatusBar.SetPaneText(0,str);}}}CScrollView::OnMouseMove(nFlags, point);}void CImageProcessView::Gradient(CPoint pt,double* grad,double* angle){CImageProcessDoc* pDoc = GetDocument();int pixel[8];if(pt.y>2 && pt.y<lHeight-2 && pt.x>2 && pt.x<lWidth-2){//if(pt.y>0 && pt.y<lHeight-1 && pt.x>0 && pt.x<lWidth-1){unsigned char *lpSrc;lpSrc = (unsigned char*)pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - pt.y) + pt.x;//sobel no noise Theta<1 pixel[0] = (int)*(lpSrc+lLineBytes-1);pixel[1] = (int)*(lpSrc+lLineBytes);pixel[2] = (int)*(lpSrc+lLineBytes+1);pixel[3] = (int)*(lpSrc-1);pixel[4] = (int)*(lpSrc+1);pixel[5] = (int)*(lpSrc - lLineBytes-1);pixel[6] = (int)*(lpSrc - lLineBytes);pixel[7] = (int)*(lpSrc - lLineBytes+1);//  1   2   1//  0   0   0// -1  -2  -1int gy=pixel[0]+2*pixel[1]+pixel[2]-pixel[5]-2*pixel[6]-pixel[7];//  -1   0   1//  -2   0   2//  -1   0   1int gx=pixel[2]+2*pixel[4]+pixel[7]-pixel[0]-2*pixel[3]-pixel[5];////no noise Theta<0.2//double h[7][7]=//{//{ 0.000, -0.646, -0.815, 0.000, 0.815, 0.646, 0.000},//{-0.963, -1.997, -1.000, 0.000, 1.000, 1.997, 0.963},//{-2.458, -2.000, -1.000, 0.000, 1.000, 2.000, 2.458},//{-2.962, -2.000, -1.000, 0.000, 1.000, 2.000, 2.962},//{-2.458, -2.000, -1.000, 0.000, 1.000, 2.000, 2.458},//{-0.963, -1.997, -1.000, 0.000, 1.000, 1.997, 0.963},//{ 0.000, -0.646, -0.815, 0.000, 0.815, 0.646, 0.000}//};//double gx=0.0;//double gy=0.0;//for(int i=-3;i<4;i++)//for(int j=-3;j<4;j++){//gx+=(h[i+3][j+3]*(*(lpSrc+i*lLineBytes+j)));//gy-=(h[j+3][i+3]*(*(lpSrc+i*lLineBytes+j)));//}*grad =sqrt(double(gx*gx+gy*gy));if(gx==0){if(gy>0) *angle=90;else if(gy<0) *angle=270;}else{if(gy==0){if(gx>0) *angle=0;else if(gx<0) *angle=180;}else{*angle=180.0/Pi*atan((double)gy/gx);if(gx<0 && gy<0)*angle=*angle+180; else if(gx<0 && gy>0) *angle=*angle+180;else if(gx>0 && gy<0) if((*angle)<-0.5) *angle=*angle+360;}}}}void CImageProcessView::OnEditCut(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();int w,h;w=pDoc->EndPoint.x-pDoc->StartPoint.x+1;h=pDoc->EndPoint.y-pDoc->StartPoint.y+1;int n;int l;int biBitCount=pDoc->m_pDib->m_lpBMIH->biBitCount;if(biBitCount==8){n=1;l=(w+3)/4*4;}else if(biBitCount==24){n=3;l=(w*3+3)/4*4;}else {n=4;l=w*4;} unsigned char *lpNewDIBBits=new unsigned char [((long) h) *  l];// 判断是否内存分配失败if (lpNewDIBBits == NULL){// 分配内存失败return ;}unsigned char *lpDst,*lpSrc;for(int i = 0; i < h; i++){// 列for(int j = 0; j <w ; j++){// 指向DIB第i行,第j个象素的指针lpSrc = (unsigned char*)pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - i-pDoc->StartPoint.y) + (j+pDoc->StartPoint.x)*n;lpDst = (unsigned char*)lpNewDIBBits +  l * (h - 1 - i) + j*n;*lpDst=*lpSrc;if(n>=3){*(lpDst+1)=*(lpSrc+1);*(lpDst+2)=*(lpSrc+2);}if(n==8)//32 bit*(lpDst+3)=*(lpSrc+3);}}// 复制的图像unsigned char  ColorTable[1024];if(biBitCount==8){lpSrc=(unsigned char*)pDoc->m_pDib->m_lpvColorTable;memcpy(ColorTable,lpSrc,1024);}delete pDoc->m_pDib;lHeight   =h;lWidth    =w;lLineBytes=l;pDoc->m_pDib =new CDib(CSize(lLineBytes,lHeight) ,biBitCount);pDoc->m_pDib->m_lpBMIH->biWidth=lWidth;if(biBitCount==8){lpSrc=(unsigned char*)pDoc->m_pDib->m_lpvColorTable;memcpy(lpSrc,ColorTable,1024);}memcpy(pDoc->m_pDib->m_lpImage,lpNewDIBBits,lLineBytes*lHeight);delete []lpNewDIBBits;Invalidate(true);}void CImageProcessView::OnUpdateEditCut(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->StartPoint.y >0 || pDoc->StartPoint.x >0 || pDoc->EndPoint.y <lHeight-1 || pDoc->EndPoint.x <lWidth-1)if(pDoc->m_pDib->m_lpBMIH!=NULL)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::RgbtoHsi(RGB *pRgb, HSI *pHsi){const double ZERO_SATURATION=0.0;const double UNDEFINED_HUE=0.000;const double DEGREES_PER_RADIAN=180.0 / 3.14159265358979;doubleR, G, B, Sum, Quotient;doubleRadians, Angle, MinValue, MaxValue, TempDouble1, TempDouble2;R = ((double) pRgb->r) / 255.0;G = ((double) pRgb->g) / 255.0;B = ((double) pRgb->b) / 255.0;Sum = R + G + B;pHsi->Intensity = Sum / 3.0;MinValue = (R < G) ? R : G;MinValue = (B < MinValue) ? B : MinValue;MaxValue = (R > G) ? R : G;MaxValue = (B > MaxValue) ? B : MaxValue;if(pHsi->Intensity < 0.00001)pHsi->Saturation = ZERO_SATURATION;elsepHsi->Saturation = 1.0 - (3.0 * MinValue) / Sum;if(MinValue == MaxValue){pHsi->Hue = UNDEFINED_HUE;pHsi->Saturation = ZERO_SATURATION;return;}TempDouble1 = (((R - G) + (R - B)) / 2.0);TempDouble2 = (R - G) * (R - G) + (R - B) * (G - B);Quotient = (TempDouble1 / sqrt(TempDouble2));Radians = acos(Quotient);Angle = Radians * DEGREES_PER_RADIAN;pHsi->Hue =(B>G) ? 360.0 - Angle : Angle;return;}void CImageProcessView::OnViewSelectareamaximum(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();pDoc->StartPoint.x=0;pDoc->StartPoint.y=0;pDoc->EndPoint.x=lWidth-1;pDoc->EndPoint.y=lHeight-1;Invalidate(true);}void CImageProcessView::OnUpdateViewSelectareamaximum(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();bool bEnable=false;if(pDoc->StartPoint.y >0 || pDoc->StartPoint.x >0 || pDoc->EndPoint.y <lHeight-1 || pDoc->EndPoint.x <lWidth-1)bEnable=true;pCmdUI->Enable(bEnable);}void CImageProcessView::OnViewInformation(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();//display infoCString str;if(pDoc->m_pDib->m_lpBMIH->biBitCount==8 ){int hist[256]={0};int min=255;int max=0;int total=0;int num=(pDoc->EndPoint.x-pDoc->StartPoint.x+1)*(pDoc->EndPoint.y-pDoc->StartPoint.y+1);for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){unsigned char* lpSrc =(unsigned char *)pDoc->m_pDib->m_lpImage+  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;//hist[*lpSrc]++;if(*lpSrc<min) min=*lpSrc;if(*lpSrc>max) max=*lpSrc;total+=*lpSrc;}}if(num<1) num=1;int mean=(int)(total/num);int v=0;int k_1=0,k_10=0,k_90=255,k_99=255;for(int i=0;i<256;i++){v+=hist[i];if(v<num/100)k_1=i;if(v<num/10)k_10=i;if(v<num*9/10)k_90=i;if(v<num*99/100)k_99=i;}if(num>20){str.Format("\npDoc->StartPoint(%d ,%d)---pDoc->EndPoint(%d ,%d)\n Size(%dx%d)\n  min=%d,max=%d,mean=%d\n\nratio\tgray\n0.01\t%d \n0.1 \t%d\n0.9 \t%d\n0.99\t%d\n",pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y,pDoc->EndPoint.x-pDoc->StartPoint.x+1,pDoc->EndPoint.y-pDoc->StartPoint.y+1,min,max,mean,k_1,k_10,k_90,k_99);//TRACE(str);if(pDoc->EndPoint.x-pDoc->StartPoint.x+1<=16 && pDoc->EndPoint.y-pDoc->StartPoint.y+1<=16){//for see edgeif(pDoc->EndPoint.x-pDoc->StartPoint.x<20 && pDoc->StartPoint.x<10){pDoc->EndPoint.x=15;pDoc->StartPoint.x=0;}if(pDoc->EndPoint.x-pDoc->StartPoint.x<20 && pDoc->EndPoint.x>lWidth-10){pDoc->EndPoint.x=lWidth-1;pDoc->StartPoint.x=lWidth-16;}if(pDoc->EndPoint.y-pDoc->StartPoint.y<20 && pDoc->StartPoint.y<10){pDoc->EndPoint.y=15;pDoc->StartPoint.y=0;}if(pDoc->EndPoint.y-pDoc->StartPoint.y<20 && pDoc->EndPoint.y>lHeight-10){pDoc->EndPoint.y=lHeight-1;pDoc->StartPoint.y=lHeight-16;}CString tmpstr;str.Format("Data Size(%d x %d)[%d,%d,%d,%d]:\n",pDoc->EndPoint.x-pDoc->StartPoint.x+1,pDoc->EndPoint.y-pDoc->StartPoint.y+1,pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y);for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){str+="\n";unsigned char* lpSrc =(unsigned char *)pDoc->m_pDib->m_lpImage+  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;//if(m_bTwoValue) tmpstr.Format("%d ",*lpSrc);else{if(*lpSrc<10)  tmpstr.Format("00%d ",*lpSrc);else if(*lpSrc<100) tmpstr.Format("0%d ",*lpSrc);else tmpstr.Format("%d ",*lpSrc);}str+=tmpstr;}}tmpstr.Format("\n\n  min=%d,max=%d,mean=%d\nColor=%d\n",min,max,mean,pDoc->m_pDib->m_lpBMIH->biBitCount);str+=tmpstr;}MessageBox(str);}}else{//colorunsigned char* lpSrc;int mingray=255;int maxgray=0;RGB minRgb;RGB maxRgb;HSI minHsi;HSI maxHsi;long int totalgray=0;long int totalrgb_r=0;long int totalrgb_g=0;long int totalrgb_b=0;double totalHsi_Hue=0.0;double totalHsi_Saturation=0.0;double totalHsi_Intensity=0.0;minRgb.b=minRgb.g=minRgb.r=255;maxRgb.b=maxRgb.g=maxRgb.r=0;minHsi.Hue=360.0;minHsi.Saturation=minHsi.Intensity=1.0;maxHsi.Hue=maxHsi.Saturation=maxHsi.Intensity=0.0;for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++)for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc=(unsigned char*)pDoc->m_pDib->m_lpImage + lLineBytes*(lHeight - 1 -i) + j*3;RGB rgb;HSI Hsi;rgb.b=*lpSrc;rgb.g=*(lpSrc+1);rgb.r=*(lpSrc+2);RgbtoHsi(&rgb, &Hsi);int gray=(int)(0.114*rgb.r+0.587*rgb.g+0.299*rgb.b);if(gray<mingray) mingray=gray;if(gray>maxgray) maxgray=gray;totalgray+=gray;if(rgb.r<minRgb.r) minRgb.r=rgb.r;if(rgb.r>maxRgb.r) maxRgb.r=rgb.r;totalrgb_r+=rgb.r;if(rgb.g<minRgb.g) minRgb.g=rgb.g;if(rgb.g>maxRgb.g) maxRgb.g=rgb.g;totalrgb_g+=rgb.g;if(rgb.b<minRgb.b) minRgb.b=rgb.b;if(rgb.b>maxRgb.b) maxRgb.b=rgb.b;totalrgb_b+=rgb.b;if(Hsi.Hue<minHsi.Hue) minHsi.Hue=Hsi.Hue;if(Hsi.Hue>maxHsi.Hue) maxHsi.Hue=Hsi.Hue;totalHsi_Hue+=Hsi.Hue;if(Hsi.Saturation<minHsi.Saturation) minHsi.Saturation=Hsi.Saturation;if(Hsi.Saturation>maxHsi.Saturation) maxHsi.Saturation=Hsi.Saturation;totalHsi_Saturation+=Hsi.Saturation;if(Hsi.Intensity<minHsi.Intensity) minHsi.Intensity=Hsi.Intensity;if(Hsi.Intensity>maxHsi.Intensity) maxHsi.Intensity=Hsi.Intensity;totalHsi_Intensity+=Hsi.Intensity;}long int num=(long(pDoc->EndPoint.x-pDoc->StartPoint.x+1))*(pDoc->EndPoint.y-pDoc->StartPoint.y+1);if(num>20){CString tmpStr;str.Format("pDoc->StartPoint(%d ,%d)---pDoc->EndPoint(%d ,%d)\n Size(%d x %d)\nColor=%d\n",pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y,pDoc->EndPoint.x-pDoc->StartPoint.x+1,pDoc->EndPoint.y-pDoc->StartPoint.y+1,pDoc->m_pDib->m_lpBMIH->biBitCount);tmpStr.Format("\n \tmin  \tmax \tmean\n");str+=tmpStr;tmpStr.Format("R\t%d \t%d \t%d\n",minRgb.r,maxRgb.r,(int)(totalrgb_r/num));str+=tmpStr;tmpStr.Format("G\t%d \t%d \t%d\n",minRgb.g,maxRgb.g,(int)(totalrgb_g/num));str+=tmpStr;tmpStr.Format("B\t%d \t%d \t%d\n",minRgb.b,maxRgb.b,(int)(totalrgb_b/num));str+=tmpStr;tmpStr.Format("H\t%3.2f \t%3.2f \t%3.2f\n",minHsi.Hue,maxHsi.Hue,totalHsi_Hue/num);str+=tmpStr;tmpStr.Format("S\t%3.2f \t%3.2f \t%3.2f\n",minHsi.Saturation,maxHsi.Saturation,totalHsi_Saturation/num);str+=tmpStr;tmpStr.Format("I\t%3.2f \t%3.2f \t%3.2f\n",minHsi.Intensity,maxHsi.Intensity,totalHsi_Intensity/num);str+=tmpStr;tmpStr.Format("\nGray\t%d \t%d \t%d\n",mingray,maxgray,(int)(totalgray/num));str+=tmpStr;//TRACE(str);MessageBox(str);}}}void CImageProcessView::OnUpdateViewInformation(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnHistgramGray(){// TODO: Add your command handler code here//CImageProcessDoc* pDoc = GetDocument();int Hist[256]={0};GetHistgram(Hist,false);DisplayDlg dlg;dlg.pData=&Hist[0];dlg.m_Sizex=256;dlg.m_LinePos=100;dlg.m_Title=_T("灰度直方图");dlg.m_Level=1;dlg.DoModal();}void CImageProcessView::GetHistgram(int* pHistgram,bool bSmooth){CImageProcessDoc* pDoc = GetDocument();//获得直方图int iMaxGrayValue = 0;int iMinGrayValue = 255;unsigned char* lpSrc;for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;int pixel = (int)*lpSrc;pHistgram[pixel]++;//修改最大,最小灰度值if(iMinGrayValue > pixel)iMinGrayValue = pixel;if(iMaxGrayValue < pixel)iMaxGrayValue = pixel;}}if(!bSmooth) return;int tmpH[256];memcpy(tmpH,pHistgram,256*sizeof(int));//Gauss filter[7]2.0//[32,60,88,100,88,60,32]/*double d1=exp(-1/(2.0*2.0*2.0));double d2=exp(-4/(2.0*2.0*2.0));double d3=exp(-9/(2.0*2.0*2.0));*/for (int i = max(iMinGrayValue-2,2); i < min(iMaxGrayValue+2,253);i++){int tmp=0;tmp=(tmpH[i-2]+tmpH[i+2])*32+(tmpH[i-2]+tmpH[i+2])*60+(tmpH[i-1]+tmpH[i+1])*88+tmpH[i]*100;pHistgram[i]=tmp/460;}return ;}void CImageProcessView::OnUpdateHistgramGray(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnHistgramRgb(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();int m_nHistRGB[256*3]={0};unsigned char *lpSrc;// 计算各个灰度值的计数,即得到直方图for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++)for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes*(lHeight-1-i) + j*3;//down -up// 计数加1m_nHistRGB[*(lpSrc+2)]++;//Rm_nHistRGB[256+*(lpSrc+1)]++;//Gm_nHistRGB[256*2+*(lpSrc)]++;//B}DisplayDlg dlg;dlg.pData=&m_nHistRGB[0];dlg.m_Sizex=256;dlg.m_Title="彩色RGB直方图";dlg.m_Level=3;//draw numberdlg.m_LinePos=0;dlg.DoModal();}void CImageProcessView::OnUpdateHistgramRgb(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==24)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnHistgramHsi(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();int m_nHistHSI[256*3]={0};unsigned char *lpSrc;// 计算各个灰度值的计数,即得到直方图for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++)for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes*(lHeight-1-i) + j*3;//down -upRGB Rgb;HSI Hsi;Rgb.b=*lpSrc;Rgb.g=*(lpSrc+1);Rgb.r=*(lpSrc+2);RgbtoHsi(&Rgb, &Hsi);unsigned int H,S,I;H=(unsigned int) (Hsi.Hue/360.0*255.0);S=(unsigned int) (Hsi.Saturation*255.0);I=(unsigned int) (Hsi.Intensity*255.0);// 计数加1m_nHistHSI[H]++;//Hm_nHistHSI[256+S]++;//Sm_nHistHSI[256*2+I]++;//I}DisplayDlg dlg;dlg.pData=&m_nHistHSI[0];dlg.m_Sizex=256;dlg.m_Title="彩色HSI直方图";dlg.m_Level=3;//draw numberdlg.m_LinePos=0;dlg.DoModal();}void CImageProcessView::OnUpdateHistgramHsi(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==24)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnPreprocessGray(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();// 更改光标形状BeginWaitCursor();// 获取指向BITMAPINFO结构的指针(Win3.0)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8 ){//8bit to Gray// 灰度映射表BYTE bMap[256];// 计算灰度映射表(保存各个颜色的灰度值),并更新DIB调色板LPRGBQUAD pDibQuad = (LPRGBQUAD) pDoc->m_pDib->m_lpvColorTable;for (int i = 0; i < 256; i ++){// 计算该颜色对应的灰度值bMap[i] = (BYTE)(0.299 * pDibQuad->rgbRed +0.587 * pDibQuad->rgbGreen +0.114 * pDibQuad->rgbBlue + 0.5);// 更新DIB调色板红色分量pDibQuad->rgbRed = (BYTE)i;// 更新DIB调色板绿色分量pDibQuad->rgbGreen =(BYTE)i;// 更新DIB调色板蓝色分量pDibQuad->rgbBlue = (BYTE)i;// 更新DIB调色板保留位pDibQuad->rgbReserved = 0;pDibQuad++;}// 更换每个象素的颜色索引(即按照灰度映射表换成灰度值)// 每行unsigned char *lpSrc;for(int i = 0; i < lHeight; i++){// 每列for(int j = 0; j < lWidth; j++){// 指向DIB第i行,第j个象素的指针lpSrc = pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - i) + j;*lpSrc=bMap[*lpSrc];}}}else if(pDoc->m_pDib->m_lpBMIH->biBitCount>=24){//24bit to gray imageunsigned char*lpSrc;// 指向转置图像对应象素的指针unsigned char*lpDst;lLineBytes =(lWidth *pDoc->m_pDib->m_lpBMIH->biBitCount/8+3)/4*4;long int lNewLineBytes=(lWidth +3)/4*4;// 指向转置图像的指针unsigned char*lpNewDIBBits;// 暂时分配内存,以保存新图像lpNewDIBBits=new unsigned char [lHeight * lNewLineBytes];memset(lpNewDIBBits,0,lHeight * lNewLineBytes);// 判断是否内存分配失败if (lpNewDIBBits == NULL){// 分配内存失败return ;}// 针对图像每行进行操作for(int i = 0; i < lHeight; i++){// 针对每行图像每列进行操作for(int j = 0; j < lWidth; j++){// 指向源DIB第i行,第j个象素的指针lpSrc =pDoc->m_pDib->m_lpImage + lLineBytes*(lHeight - 1 - i) + j*pDoc->m_pDib->m_lpBMIH->biBitCount/8;lpDst =lpNewDIBBits + lNewLineBytes * (lHeight - 1 - i) + j;// 复制象素double v;v=0.299*(*lpSrc)+0.587*(*(lpSrc+1))+0.114*(*(lpSrc+2));//bgr*lpDst=(unsigned char)v;//GBR?}}lLineBytes=lNewLineBytes;CString str=pDoc->GetTitle();pDoc->SetTitle(str+"--Color");DisplayNewImg(lpNewDIBBits,lLineBytes,lHeight,str+"Gray");delete []lpNewDIBBits;}// 恢复光标EndWaitCursor();}void CImageProcessView::OnUpdatePreprocessGray(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount>=24)bAvail=true;else if(pDoc->m_pDib->m_lpBMIH->biBitCount==8){//it's gray image?LPRGBQUAD pDibQuad = (LPRGBQUAD) pDoc->m_pDib->m_lpvColorTable;bAvail=false;for (int i = 0; i < 256; i ++){if((pDibQuad->rgbRed != pDibQuad->rgbGreen) ||  (pDibQuad->rgbRed !=pDibQuad->rgbBlue)|| (pDibQuad->rgbGreen !=pDibQuad->rgbBlue) || (pDibQuad->rgbRed != i)){bAvail=true;break;}pDibQuad++;}}pCmdUI->Enable(bAvail);}void CImageProcessView::DisplayNewImg(unsigned char* lpNewImg,int Lines,int Height,CString strTitle,bool bColor){CImageProcessDoc* pDoc = GetDocument();//建立一个新视图,显示分割结果CMainFrame* pFrame = (CMainFrame *)(AfxGetApp()->m_pMainWnd);//发送新建文件的消息,创建一个新的文档-视图pFrame->SendMessage(WM_COMMAND, ID_FILE_NEW);pFrame->SendMessage(WM_COMMAND, ID_WINDOW_CASCADE);//获取新建视图指针CImageProcessView* pView=(CImageProcessView*)pFrame->MDIGetActive()->GetActiveView();//获取相关联的新的文档类指针CImageProcessDoc* pDocNew=pView->GetDocument();delete pDocNew->m_pDib;if(bColor==false){pDocNew->m_pDib =new CDib(CSize(Lines,Height ) ,8);unsigned char * lpSrc;lpSrc=(unsigned char*)pDocNew->m_pDib->m_lpvColorTable;for(int i=0;i<256;i++){*lpSrc=(unsigned char)i;lpSrc++;*lpSrc=(unsigned char)i;lpSrc++;*lpSrc=(unsigned char)i;lpSrc++;*lpSrc=0;lpSrc++;}memcpy(pDocNew->m_pDib->m_lpImage, lpNewImg, Lines * Height);}else{pDocNew->m_pDib =new CDib(CSize(Lines,Height ) ,24);memcpy(pDocNew->m_pDib->m_lpImage, lpNewImg, (Lines*3) * Height);}pDocNew->SetTitle(strTitle);//display select AreapDocNew->StartPoint=pDoc->StartPoint;pDocNew->EndPoint=pDoc->EndPoint;}// 编码表含义//******************************************//COLOR_SCALE_COUNT=//  "  0   常规灰度编码", // "  1   逆灰度编码",// "  2   红色饱和度编码",// "  3   绿色饱和度编码",// "  4   蓝色饱和度编码",// "  5   黄色饱和度编码",// "  6   青色饱和度编码",//       "  7   紫色饱和度编码", //       "  8   彩虹编码 1", // "9   彩虹编码 2",// "10   热金属编码 1",//       "11   热金属编码 2",//*******************************************void CImageProcessView::OnPreprocessPsdeocolordisplay(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();// 更改光标形状BeginWaitCursor();CString str=pDoc->GetTitle();DisplayNewImg(pDoc->m_pDib->m_lpImage,lLineBytes,lHeight,str+"Gray");const int CHARACT= 11;LPRGBQUAD pDibQuad = (LPRGBQUAD) pDoc->m_pDib->m_lpvColorTable;for (int i = 0; i < 256; i ++){// 更新DIB调色板蓝色分量pDibQuad->rgbBlue = ColorsTable[CHARACT][i][0];// 更新DIB调色板红色分量pDibQuad->rgbRed = ColorsTable[CHARACT][i][1];// 更新DIB调色板绿色分量pDibQuad->rgbGreen =ColorsTable[CHARACT][i][2];pDibQuad++;}//draw display table//color bar in bottomunsigned char*lpSrc;for (int i =0; i <20; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* i -1;for (int j =0; j <lWidth; j ++){lpSrc++;*lpSrc=(BYTE)(j*256/lWidth);}}pDoc->SetTitle(str+"--PsdeoColor");// 更新视图Invalidate(true);// 恢复光标EndWaitCursor();}void CImageProcessView::OnUpdatePreprocessPsdeocolordisplay(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8){//it's gray image?LPRGBQUAD pDibQuad = (LPRGBQUAD) pDoc->m_pDib->m_lpvColorTable;bAvail=true;for (int i = 0; i < 256; i ++){if((pDibQuad->rgbRed != pDibQuad->rgbGreen) ||  (pDibQuad->rgbRed !=pDibQuad->rgbBlue)|| (pDibQuad->rgbGreen !=pDibQuad->rgbBlue)){bAvail=false;break;}pDibQuad++;}}pCmdUI->Enable(bAvail);}void CImageProcessView::OnPreprocessNegativeimage(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();// 更改光标形状BeginWaitCursor();CString str=pDoc->GetTitle();DisplayNewImg(pDoc->m_pDib->m_lpImage,lLineBytes,lHeight,str);unsigned char *lpSrc;for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) +pDoc->StartPoint.x;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){if(!m_bTwoValue) *lpSrc=255-*lpSrc;else *lpSrc=TWOVALUE_H-*lpSrc;lpSrc++;}}pDoc->SetTitle(str+"--Negative");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);}void CImageProcessView::OnUpdatePreprocessNegativeimage(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnHistgramEqualizer(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();int Hist[256]={0};GetHistgram(Hist,false);for(int k=1;k<256;k++) Hist[k]+=Hist[k-1];//计算对应的灰度值int Num=pDoc->EndPoint.y-pDoc->StartPoint.y+1;Num*=(pDoc->EndPoint.x-pDoc->StartPoint.x+1);for(int k=0;k<256;k++) Hist[k]=Hist[k]*255/Num;//look table////method1  Histogram equalization变换//unsigned char *lpSrc;//for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++)//{lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x;//for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++)//{//*lpSrc=(unsigned char)(Hist[*lpSrc]);//lpSrc++;//}//}//method2 change lut tableLPRGBQUAD pDibQuad = (LPRGBQUAD) pDoc->m_pDib->m_lpvColorTable;for (int i = 0; i < 256; i ++){int v=Hist[i];pDibQuad->rgbBlue = (BYTE)v;pDibQuad->rgbRed =(BYTE)v;pDibQuad->rgbGreen =(BYTE)v;pDibQuad++;}CString str=pDoc->GetTitle();pDoc->SetTitle(str+"--直方图均衡化");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);}void CImageProcessView::OnUpdateHistgramEqualizer(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnHistgramRobustnormalization(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();int Hist[256]={0};GetHistgram(Hist,false);for(int k=1;k<256;k++) Hist[k]+=Hist[k-1];const double Th1=0.2;const double Th2=0.8;int g_min=0;int g_max=255;int size=(pDoc->EndPoint.x-pDoc->StartPoint.x+1)*(pDoc->EndPoint.y-pDoc->StartPoint.y+1);while(Hist[g_min]<(int)(size*Th1))g_min++;while(Hist[g_max]>(int)(size*Th2))g_max--;g_min=min(g_min,100);g_max=min(max(g_max,128),220);double a=255.0/(g_max-g_min);double b=-a*g_min;//change lut tableLPRGBQUAD pDibQuad = (LPRGBQUAD) pDoc->m_pDib->m_lpvColorTable;for (int i = 0; i < 256; i ++){int v=min(max((int)(a*i+b+0.5),0),255);pDibQuad->rgbBlue = (BYTE)v;pDibQuad->rgbRed =(BYTE)v;pDibQuad->rgbGreen =(BYTE)v;pDibQuad++;}CString str=pDoc->GetTitle();pDoc->SetTitle(str+"--直方图归一化");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);}void CImageProcessView::OnUpdateHistgramRobustnormalization(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnGammBright(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();const double r=.2;LPRGBQUAD pDibQuad = (LPRGBQUAD) pDoc->m_pDib->m_lpvColorTable;for (int i = 0; i < 256; i ++){//double tmp=(i+1)/256.0;//only one timesdouble tmp=(pDibQuad->rgbBlue+1)/256.0;//can do it againif(tmp<0.9999)tmp=exp(r*log(tmp));int v=(int)(tmp*256);pDibQuad->rgbBlue = (BYTE)v;pDibQuad->rgbRed =(BYTE)v;pDibQuad->rgbGreen =(BYTE)v;pDibQuad++;}CString str=pDoc->GetTitle();pDoc->SetTitle(str+"--伽马校正(r<0)");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);}void CImageProcessView::OnGammDark(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();const double r=2.0;LPRGBQUAD pDibQuad = (LPRGBQUAD) pDoc->m_pDib->m_lpvColorTable;for (int i = 0; i < 256; i ++){//double tmp=(i+1)/256.0;//only one timesdouble tmp=(pDibQuad->rgbBlue+1)/256.0;//can do it againif(tmp<0.9999)tmp=exp(r*log(tmp));int v=(int)(tmp*256);pDibQuad->rgbBlue = (BYTE)v;pDibQuad->rgbRed =(BYTE)v;pDibQuad->rgbGreen =(BYTE)v;pDibQuad++;}CString str=pDoc->GetTitle();pDoc->SetTitle(str+"--伽马校正(r>0)");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);}void CImageProcessView::OnUpdateGammBright(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnUpdateGammDark(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnAddnoiseGuass(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();const double Mean=0;const double Dev=20;//Method1://1、获取概率分布//2、求累积double p[256];p[0]=0.0;for(int i=-127;i<128;i++)p[i+128]=p[i+128-1]+(double)(exp(double(-(i-Mean)*(i-Mean)/(2*Dev*Dev)))/(Dev*sqrt(2.0*Pi)));srand( (unsigned)time( NULL ) );double N=0.0;double S=0.0;unsigned char* lpSrc;for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) +pDoc->StartPoint.x;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){//3、获取均匀分布值double q=(double)rand();q/=RAND_MAX;//4、获取对应值int k;for(k=0;k<256;k++)//q==p[k]if(q<=p[k])break;int v;//5、添加噪声v=((int)*lpSrc)+128-k;//if(v<0) v=0;else if(v>255) v=255;S+=v*v;//定义如此:  not ((*lpSrc)*(*lpSrc));N+=((v-*lpSrc)*(v-*lpSrc));*lpSrc=(unsigned char)v;lpSrc++;}}////Method2:////srand( (unsigned)time( NULL ) );//double N=0.0;//double S=0.0;//unsigned char* lpSrc;//for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){//lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) +pDoc->StartPoint.x;//for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x-1; j +=2){//           ////1、获取均匀分布值//double q=(double)rand();//double r=q/RAND_MAX;////q=(double)rand();//double theta=q/RAND_MAX;//////3、获取对应值//double z1=Dev*cos(2*Pi*theta)*sqrt(-2*log(r));//log10//double z2=Dev*sin(2*Pi*theta)*sqrt(-2*log(r));//////4、添加噪声////int v=((int)*lpSrc)+(int)z1;////if(v<0) v=0;//else if(v>255) v=255;////S+=(v*v);N+=((v-*lpSrc)*(v-*lpSrc));//*lpSrc=(unsigned char)v;////lpSrc++;////v=((int)*lpSrc)+(int)z2;////if(v<0) v=0;//else if(v>255) v=255;////S+=(v*v);N+=((v-*lpSrc)*(v-*lpSrc));//*lpSrc=(unsigned char)v;//lpSrc++;//////}//}CString str=pDoc->GetTitle();CString str1;str1.Format("--+高斯噪声(SNR:%3.1f)",S/N);str+=str1;pDoc->SetTitle(str);InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);}void CImageProcessView::OnAddnoiseSaltpepper(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();srand( (unsigned)time( NULL ) );double N=0.0;double S=0.0;unsigned char* lpSrc;for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) +pDoc->StartPoint.x;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){float dtmp= (float)rand();dtmp/=RAND_MAX;double v=*lpSrc;if(dtmp<0.1)  //10%{if(rand()%2) *lpSrc = 0;else *lpSrc = 255;}S+=((*lpSrc) * (*lpSrc));N+=((v-*lpSrc)*(v-*lpSrc));lpSrc++;}}CString str=pDoc->GetTitle();CString str1;str1.Format("--+椒盐噪声(SNR:%3.1f)",S/N);str+=str1;pDoc->SetTitle(str);InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);}void CImageProcessView::OnUpdateAddnoiseGuass(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnUpdateAddnoiseSaltpepper(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnHistgramLocal(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;unsigned char*lpDst;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){return ;}BeginWaitCursor();lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);//获得直方图int Hist[256]={0};GetHistgram(Hist,false);//get mean,segmadouble Mean=0;for (int i = 0; i < 256;i++){Mean+=(i*Hist[i]);}Mean=Mean/(pDoc->EndPoint.x-pDoc->StartPoint.x+1)/(pDoc->EndPoint.y-pDoc->StartPoint.y+1);double Segma=0;for (int i = 0; i < 256;i++){Segma+=((i-Mean)*(i-Mean)*Hist[i]);}Segma=sqrt(Segma/(pDoc->EndPoint.x-pDoc->StartPoint.x+1)/(pDoc->EndPoint.y-pDoc->StartPoint.y+1));double E=4.0,k0=0.4,k1=0.02,k2=0.4;int M=3,N=3;double mean,segma;for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpDst = lpNewDIBBits +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;if(i>M/2 && i<lHeight-1-M/2 && j>M/2 && j<lWidth-1-M/2){//Get M*N meanmean=0.0;for(int m=-M/2;m<=M/2;m++)for(int n=-N/2;n<=N/2;n++)mean+=*(lpSrc+ lLineBytes* m+n);mean/=(M*N);if(mean<k0*Mean){segma=0.0;for(int m=-M/2;m<=M/2;m++)for(int n=-N/2;n<=N/2;n++)segma+=((*(lpSrc+ lLineBytes* m+n)-mean)*(*(lpSrc+ lLineBytes*m+n)-mean));segma=sqrt(segma/(M*N));double dtmp;if(segma>=k1*Segma && segma<=k2*Segma){dtmp=E*(*lpSrc);if(dtmp>255) dtmp=255;*lpDst=(unsigned char)dtmp;//}}}}}CString str=pDoc->GetTitle();DisplayNewImg(lpNewDIBBits,lLineBytes,lHeight,str+"局部增强");// 恢复光标EndWaitCursor();// 释放内存delete []lpNewDIBBits;}void CImageProcessView::OnUpdateHistgramLocal(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnPreprocessLaplacesharpen(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;unsigned char*lpDst;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){return ;}BeginWaitCursor();lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);int pixel[8];for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;if(i>0 && i<lHeight-1 && j>0 && j<lWidth-1){pixel[0] = (int)*(lpSrc+lLineBytes-1);pixel[1] = (int)*(lpSrc+lLineBytes);pixel[2] = (int)*(lpSrc+lLineBytes+1);pixel[3] = (int)*(lpSrc+1);pixel[4] = (int)*(lpSrc - lLineBytes+1);pixel[5] = (int)*(lpSrc - lLineBytes);pixel[6] = (int)*(lpSrc - lLineBytes-1);pixel[7] = (int)*(lpSrc-1);int Tmp=0;for(int k=0;k<8;k++)Tmp+=pixel[k];Tmp-=8*((int)*lpSrc);if(Tmp>0) Tmp=*lpSrc+Tmp;else Tmp=*lpSrc-Tmp;if(Tmp>255) Tmp=255;*lpDst=(unsigned char)Tmp;}}}CString str=pDoc->GetTitle();DisplayNewImg(lpNewDIBBits,lLineBytes,lHeight,str+"Laplace 锐化");// 恢复光标EndWaitCursor();// 释放内存delete []lpNewDIBBits;}void CImageProcessView::OnUpdatePreprocessLaplacesharpen(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnSmoothMeanfilter(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();//copy imgunsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL)return ;memcpy( lpNewDIBBits,pDoc->m_pDib->m_lpImage, lLineBytes * lHeight);const int M=5;//oddconst int N=5;//oddMeanFilter(M,N);CString str=pDoc->GetTitle();DisplayNewImg(pDoc->m_pDib->m_lpImage,lLineBytes,lHeight,str+"--+均值滤波");//display orignal image//get img backpDoc->SetTitle(str);memcpy( pDoc->m_pDib->m_lpImage,lpNewDIBBits, lLineBytes * lHeight);delete []lpNewDIBBits;// 恢复光标EndWaitCursor();}void CImageProcessView::OnUpdateSmoothMeanfilter(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}//不计算图像边界(选择的区域边界要计算!)//利用两次卷积合成,递归完成卷积void CImageProcessView::MeanFilter(int M,int N){CImageProcessDoc* pDoc = GetDocument();int*lpNewDIBBits;lpNewDIBBits=new int [lLineBytes*lHeight];if (lpNewDIBBits == NULL){return ;}unsigned char*lpSrc;int*lpDst;int v;int half_M=M/2;int half_N=N/2;//若选择区域,顶、低部需要多算几行for (int i = max(pDoc->StartPoint.y-half_N,0); i <=min(pDoc->EndPoint.y+half_N,lHeight-1); i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) +max(pDoc->StartPoint.x,half_M);//get first pointlpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+max(pDoc->StartPoint.x,half_M);v=0;for(int k=-half_M;k<=half_M;k++){//addv+=*(lpSrc+k);}*lpDst=v;for (int j =max(pDoc->StartPoint.x,half_M)+1; j <min(pDoc->EndPoint.x,lWidth-half_M); j ++){lpSrc++;lpDst++;v+=(*(lpSrc+half_M)-*(lpSrc-half_M-1));*lpDst=v;}}int size=M*N;for (int j =max(pDoc->StartPoint.x,half_M); j <min(pDoc->EndPoint.x,lWidth-half_M); j ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-max(pDoc->StartPoint.y,half_N)) + j;lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - max(pDoc->StartPoint.y,half_N))+ j;v=0;for(int k=-half_N;k<=half_N;k++)v+=*(lpDst+k*lLineBytes);*lpSrc=(BYTE)(v/size);for (int i = max(pDoc->StartPoint.y,half_N)+1; i <min(pDoc->EndPoint.y,lHeight-half_N); i ++){lpDst-=lLineBytes;v+=(*(lpDst-(half_N)*lLineBytes)-*(lpDst+(half_N+1)*lLineBytes));lpSrc-=lLineBytes;*lpSrc=(BYTE)(v/size);}}// 释放内存delete []lpNewDIBBits;}void CImageProcessView::OnSmoothGaussfilter(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();//copy imgunsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL)return ;memcpy( lpNewDIBBits,pDoc->m_pDib->m_lpImage, lLineBytes * lHeight);const int M=7;//oddconst int N=7;//oddconst double Sigma=1.414;GaussFilter(M,N,Sigma);CString str=pDoc->GetTitle();DisplayNewImg(pDoc->m_pDib->m_lpImage,lLineBytes,lHeight,str+"--+高斯滤波");//display orignal image//get img backpDoc->SetTitle(str);memcpy( pDoc->m_pDib->m_lpImage,lpNewDIBBits, lLineBytes * lHeight);delete []lpNewDIBBits;// 恢复光标EndWaitCursor();}void CImageProcessView::OnUpdateSmoothGaussfilter(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}//利用两次卷积合成,M!=N 模板计算(方差也不同?不考虑)void CImageProcessView::GaussFilter(int M,int N,double Sigma){CImageProcessDoc* pDoc = GetDocument();int*lpNewDIBBits;lpNewDIBBits=new int [lLineBytes*lHeight];if (lpNewDIBBits == NULL){return ;}unsigned char*lpSrc;int*lpDst;int* model;if(Sigma<0.3) Sigma=0.3;if(M<3) M=3;if(N<3) N=3;N=M;model=new int [M];int half_M=M/2;int half_N=N/2;for(int i=-half_M;i<=half_M;i++){double G=exp(-(i*i)/(2.0*Sigma*Sigma))/ (sqrt(2 * Pi) * Sigma);model[i+half_M]=(int)(G*100+0.5);}int num=0;for(int i=0;i<M;i++)num+=model[i];num*=num;for (int i = max(pDoc->StartPoint.y-half_N,0); i <=min(pDoc->EndPoint.y+half_N,lHeight-1); i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) +max(pDoc->StartPoint.x,half_M);//get first pointlpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+max(pDoc->StartPoint.x,half_M);for (int j =max(pDoc->StartPoint.x,half_M); j <min(pDoc->EndPoint.x,lWidth-half_M); j ++){int v=0;for(int k=-half_M;k<=half_M;k++){//addv+=(*(lpSrc+k)*model[k+half_M]);}*lpDst=v;lpSrc++;lpDst++;}}for (int j =max(pDoc->StartPoint.x,half_M); j <min(pDoc->EndPoint.x,lWidth-half_M); j ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-max(pDoc->StartPoint.y,half_N)) + j;lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - max(pDoc->StartPoint.y,half_N))+ j;for (int i = max(pDoc->StartPoint.y,half_N); i <min(pDoc->EndPoint.y,lHeight-half_N); i ++){int v=0;for(int k=-half_N;k<=half_N;k++)v+=(*(lpDst+k*lLineBytes)*model[k+half_N]);*lpSrc=(BYTE)(v/num);lpDst-=lLineBytes;lpSrc-=lLineBytes;}}// 释放内存delete []lpNewDIBBits;delete []model;}void CImageProcessView::GaussFilter(double* pData,int M,int N,double Sigma){CImageProcessDoc* pDoc = GetDocument();double*lpNewDIBBits;lpNewDIBBits=new double [lLineBytes*lHeight];if (lpNewDIBBits == NULL){return ;}memcpy(lpNewDIBBits,pData,lLineBytes*lHeight*sizeof(double));double*lpSrc;double*lpDst;double* model;if(Sigma<0.3) Sigma=0.3;if(M<3) M=3;if(N<3) N=3;N=M;model=new double [M];int half_M=M/2;int half_N=N/2;for(int i=-half_M;i<=half_M;i++){double G=exp(-(i*i)/(2.0*Sigma*Sigma))/ (sqrt(2 * Pi) * Sigma);model[i+half_M]=G;}for (int i = max(pDoc->StartPoint.y-half_N,0); i <=min(pDoc->EndPoint.y+half_N,lHeight-1); i ++){lpSrc =pData  +  lLineBytes* (lHeight-1-i) +max(pDoc->StartPoint.x,half_M);//get first pointlpDst =lpNewDIBBits+ lLineBytes * (lHeight - 1 - i)+max(pDoc->StartPoint.x,half_M);for (int j =max(pDoc->StartPoint.x,half_M); j <min(pDoc->EndPoint.x,lWidth-half_M); j ++){double v=0;for(int k=-half_M;k<=half_M;k++){//addv+=(*(lpSrc+k)*model[k+half_M]);}*lpDst=v;lpSrc++;lpDst++;}}for (int j =max(pDoc->StartPoint.x,half_M); j <min(pDoc->EndPoint.x,lWidth-half_M); j ++){lpSrc = pData +  lLineBytes* (lHeight-1-max(pDoc->StartPoint.y,half_N)) + j;lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - max(pDoc->StartPoint.y,half_N))+ j;for (int i = max(pDoc->StartPoint.y,half_N); i <min(pDoc->EndPoint.y,lHeight-half_N); i ++){double v=0;for(int k=-half_N;k<=half_N;k++)v+=(*(lpDst+k*lLineBytes)*model[k+half_N]);*lpSrc=v;lpDst-=lLineBytes;lpSrc-=lLineBytes;}}// 释放内存delete []lpNewDIBBits;delete []model;}void CImageProcessView::OnSmoothMedianfilter(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();//copy imgunsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL)return ;memcpy( lpNewDIBBits,pDoc->m_pDib->m_lpImage, lLineBytes * lHeight);CDemoTimer exeTimer;exeTimer.Reset();const int M=3;//oddconst int N=3;//oddMedianFilter(M,N);TRACE("\nUsed Time is %.3f ms\n",exeTimer.GetTime(false)*1000);CString str=pDoc->GetTitle();DisplayNewImg(pDoc->m_pDib->m_lpImage,lLineBytes,lHeight,str+"--+中值滤波");//display orignal image//get img backpDoc->SetTitle(str);memcpy( pDoc->m_pDib->m_lpImage,lpNewDIBBits, lLineBytes * lHeight);delete []lpNewDIBBits;// 恢复光标EndWaitCursor();}void CImageProcessView::OnUpdateSmoothMedianfilter(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::MedianFilter(int M,int N){CImageProcessDoc* pDoc = GetDocument();unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){return ;}unsigned char*lpSrc;unsigned char*lpDst;lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);//unsigned char *v=new unsigned char[M*N];//[N*M];//line N Column M not rect (int err) vector<unsigned char> v(M*N,0);const int Th=(M*N)/2;//Mid Posfor (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpDst = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpSrc =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;if(i>=M/2 && i<lHeight-M/2 && j>=N/2 && j<lWidth-N/2){//Get M*N data to v[]int vSize=0;for(int m=-M/2;m<=M/2;m++)for(int n=-N/2;n<=N/2;n++){v[vSize]=*(lpSrc+lLineBytes*m+n);vSize++;}//sort v[]for(int m=0;m<M*N-1;m++)for(int n=m+1;n<M*N;n++){if(v[m]>v[n]){//swapBYTE tmp=v[m];v[m]=v[n];v[n]=tmp;}}*(lpDst)=(unsigned char)v[Th];}}}// 释放内存delete []lpNewDIBBits;//delete []v;}//邻域内求与其它点距离最短的色点替代该点void CImageProcessView::OnSmoothColorfilter(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();// 更改光标形状BeginWaitCursor();unsigned char*lpSrc;unsigned char*lpDst;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lHeight * lLineBytes];if (lpNewDIBBits == NULL)return ;memcpy(lpNewDIBBits,pDoc->m_pDib->m_lpImage,lHeight * lLineBytes);// 针对图像每行进行操作for (int j =pDoc->StartPoint.x+1; j <pDoc->EndPoint.x; j ++){for (int i = pDoc->StartPoint.y+1; i <pDoc->EndPoint.y; i ++){// 指向源DIB第i行,第j个象素的指针lpSrc =lpNewDIBBits  + lLineBytes*(lHeight-1-i)+ j*3;double d;double mind=10000;int mm=0;int mn=0;for(int m=-1;m<=1;m++)for(int n=-1;n<=1;n++){d=0.0;unsigned char*lpDst1=lpSrc+lLineBytes*n+m*3;for(int s=-1;s<=1;s++)for(int t=-1;t<=1;t++){   unsigned char*lpDst2=lpSrc+lLineBytes*t+s*3;double dtmp=(double)((*(lpDst1)-*(lpDst2))*(*(lpDst1)-*(lpDst2))+//^ is't Pow(x,y)(*(lpDst1+1)-*(lpDst2+1))*(*(lpDst1+1)-*(lpDst2+1))+(*(lpDst1+2)-*(lpDst2+2))*(*(lpDst1+2)-*(lpDst2+2)));d+=sqrt(dtmp);}if(d<mind){mind=d;mm=m;mn=n;}}lpSrc=lpSrc+ lLineBytes*mn+ mm*3;lpDst =pDoc->m_pDib->m_lpImage+ lLineBytes *(lHeight-1-i) + j*3;*lpDst=*lpSrc;*(lpDst+1)=*(lpSrc+1);*(lpDst+2)=*(lpSrc+2);}}DisplayNewImg(lpNewDIBBits,(lWidth+3)/4*4,lHeight,"原图",true);//display orignal imageCString str=pDoc->GetTitle();pDoc->SetTitle(str+"--Color Filtering");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);delete []lpNewDIBBits;// 恢复光标EndWaitCursor();}void CImageProcessView::OnUpdateSmoothColorfilter(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==24)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnFrequencydomainFft(){// TODO: Add your command handler code here//CImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();CPoint wh=FrequencydomainSelectarea();int w=wh.x;int h=wh.y;// 分配内存complex<double> *TD = new complex<double>[w * h];complex<double> *FD = new complex<double>[w * h];TD[0]=complex<double>(1.0,2.0);;DoFFT( TD,  FD, w,h);DisplayFw(FD,w, h,0.6,"|F(u,v)|");// 恢复光标EndWaitCursor();// 删除临时变量delete []TD;delete []FD;}void CImageProcessView::DisplayFw(complex<double> * FD, int w, int h,double c,CString title){//显示 F(jw)unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [w*h];unsigned char*lpSrc;if (lpNewDIBBits == NULL)return ;for(int i = 0; i < h; i++){for(int j = 0; j < w; j++){// 计算频谱double dTemp =c*log(1+ sqrt((double)FD[i *w  + j].real() * FD[i *w  + j].real() + FD[i *w  + j].imag() * FD[i *w  + j].imag()));// c ln(1+r)  dTemp=exp(dTemp*log(2.0));//log | log10if(dTemp>255) dTemp=255;//freqlpSrc = lpNewDIBBits + w * (h - 1 - i) + j;* (lpSrc) = (BYTE)(dTemp);}}DisplayNewImg(lpNewDIBBits,w,h,title);delete []lpNewDIBBits;}void CImageProcessView::OnUpdateFrequencydomainFft(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}CPoint CImageProcessView::FrequencydomainSelectarea(){//获取付立叶变换的宽度和高度(2的整数次方)CImageProcessDoc* pDoc = GetDocument();intw;inth;int wp=int(log((double) pDoc->EndPoint.x-pDoc->StartPoint.x+1)/log(2.0));int hp=int(log((double) pDoc->EndPoint.y-pDoc->StartPoint.y+1)/log(2.0));w=(int)pow(2.0,wp);h=(int)pow(2.0,hp);if((pDoc->EndPoint.x-pDoc->StartPoint.x+1==lWidth) && (pDoc->EndPoint.y-pDoc->StartPoint.y+1==lHeight)){  //整幅图像处理if(w<lWidth) w*=2;//add 0if(h<lHeight) h*=2;}else{if(w<256 && w<(pDoc->EndPoint.x-pDoc->StartPoint.x+1)){w *= 2;}if(h<256 && h<(pDoc->EndPoint.y-pDoc->StartPoint.y+1)){h *= 2;}//若非取全区域,修正区域使满足w、h整数次方int dy=(pDoc->EndPoint.y-pDoc->StartPoint.y+1-h)/2-1;pDoc->StartPoint.y+=dy;if(pDoc->StartPoint.y<0) pDoc->StartPoint.y=0;pDoc->EndPoint.y=pDoc->StartPoint.y+h-1;int dx=(pDoc->EndPoint.x-pDoc->StartPoint.x+1-w)/2;pDoc->StartPoint.x+=dx;//若不在区域内,补0if(pDoc->StartPoint.x<0) pDoc->StartPoint.x=0;pDoc->EndPoint.x=pDoc->StartPoint.x+w-1;if(pDoc->EndPoint.x>lWidth-1){pDoc->EndPoint.x=lWidth-1;pDoc->StartPoint.x=max(0,lWidth-1-w);}if(pDoc->EndPoint.y>lHeight-1){pDoc->EndPoint.y=lHeight-1;pDoc->StartPoint.y=max(0,lHeight-1-h);}}//display select area changeInvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);return(CPoint(w,h));}void CImageProcessView::DoFFT(complex<double> * TD, complex<double> * FD, int w, int h){CImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;// 行for(int i = 0; i < h; i++){// 列for(int j = 0; j < w; j++){// 指向DIB第i行,第j个象素的指针if(i+pDoc->StartPoint.y<lHeight && pDoc->StartPoint.x+j<lWidth){lpSrc = (unsigned char*)pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - i-pDoc->StartPoint.y) + pDoc->StartPoint.x+j;// 给时域赋值TD[j + w * i] = complex<double>(*(lpSrc), 0);//w*h}else{TD[j + w * i] = complex<double>(0,0);}}}FFT2(TD,FD, w, h);}void CImageProcessView::FFT2(complex<double> * TD, complex<double> * FD, int w,int h){int wp=int(log((double) w)/log(2.0));int hp=int(log((double) h)/log(2.0));//1: move to centerfor(int y=0; y<h; y++)for(int x=0; x<w; x++)if((x+y)%2) TD[y*w + x]=-TD[y*w + x];//2:FFTfor(int i = 0; i < h; i++){// 对y方向进行快速付立叶变换FFT(&TD[w * i], &FD[w * i], wp);//w}// 保存变换结果for(int i = 0; i < h; i++){for(int j = 0; j < w; j++){TD[i + h * j] = FD[j + w * i];//转置}}for(int i = 0; i < w; i++){// 对x方向进行快速付立叶变换FFT(&TD[i * h], &FD[i * h], hp);//h}//再转置还原for(int i = 0; i < h; i++){for(int j = 0; j < w; j++){TD[j + w * i] = FD[i + h * j];//转置}}for(int i = 0; i < h; i++){for(int j = 0; j < w; j++){FD[j + w * i] = TD[j + w * i];}}//FD=TD;  err!!}void CImageProcessView::FFT(complex<double> * TD, complex<double> * FD, int r){// 付立叶变换点数LONGcount;const double PI=3.14159;// 中间变量intbfsize,p;// 角度doubleangle;complex<double> *W,*X1,*X2,*X;// 计算付立叶变换点数count = 1 << r;// 分配运算所需存储器W  = new complex<double>[count / 2];X1 = new complex<double>[count];X2 = new complex<double>[count];// 计算加权系数for(int i = 0; i < count / 2; i++){angle = -i * PI * 2 / count;W[i] = complex<double> (cos(angle), sin(angle));}// 将时域点写入X1memcpy(X1, TD, sizeof(complex<double>) * count);// 采用蝶形算法进行快速付立叶变换for(int k = 0; k < r; k++){for(int j = 0; j < 1 << k; j++){bfsize = 1 << (r-k);for(int i = 0; i < bfsize / 2; i++){p = j * bfsize;X2[i + p] = X1[i + p] + X1[i + p + bfsize / 2];X2[i + p + bfsize / 2] = (X1[i + p] - X1[i + p + bfsize / 2]) * W[i * (1<<k)];}}X  = X1;X1 = X2;X2 = X;}// 重新排序for(int j = 0; j < count; j++){p = 0;for(int i = 0; i < r; i++){if (j&(1<<i)){p+=1<<(r-i-1);}}FD[j]=X1[p];}// 释放内存delete [] W;delete [] X1;delete [] X2;}void CImageProcessView::IFFT(complex<double> * FD, complex<double> * TD, int r){// 付立叶变换点数LONGcount;complex<double> *X;// 计算付立叶变换点数count = 1 << r;// 分配运算所需存储器X = new complex<double>[count];// 将频域点写入Xmemcpy(X, FD, sizeof(complex<double>) * count);// 求共轭for(int i = 0; i < count; i++){X[i] = complex<double> (X[i].real(), -X[i].imag());}// 调用快速付立叶变换FFT(X, TD, r);// 求时域点的共轭for(int i = 0; i < count; i++){TD[i] = complex<double> (TD[i].real() / count, -TD[i].imag() / count);}// 释放内存delete [] X;}void CImageProcessView::OnButterworthLowfilter(){// TODO: Add your command handler code here//CImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();CPoint wh=FrequencydomainSelectarea();int w=wh.x;int h=wh.y;// 分配内存complex<double> *TD = new complex<double>[w * h];complex<double> *FD = new complex<double>[w * h];DoFFT( TD,  FD, w,h);//DisplayFw(FD,w, h,0.6,"|F(u,v)|");//filterconst double D0=30;for(int y=0; y<h; y++){for(int x=0; x<w; x++){doubleD = (double)((y-h/2)*(y-h/2)+(x-w/2)*(x-w/2)) ; D = D / (D0 * D0);//(D/D0)^2//ButterWorth低通滤波double H = 1/(1+D*D);//n=2FD[x + y*w]=complex<double>(FD[x + y*w].real()*H,FD[x + y*w].imag()*H);//h*w}}//DisplayFw(FD,w, h,0.6,"|F(u,v)H(u,v)|");DoIFFT( TD,  FD, w,h,"ButtWorth低通",CPoint(0,0));// 恢复光标EndWaitCursor();// 删除临时变量delete [] TD;delete [] FD;}void CImageProcessView::OnButterworthHighfilter(){// TODO: Add your command handler code here//CImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();CPoint wh=FrequencydomainSelectarea();int w=wh.x;int h=wh.y;// 分配内存complex<double> *TD = new complex<double>[w * h];complex<double> *FD = new complex<double>[w * h];DoFFT( TD,  FD, w,h);//filterconst double D0=30;for(int y=0; y<h; y++){for(int x=0; x<w; x++){doubleD = (double)((y-h/2)*(y-h/2)+(x-w/2)*(x-w/2)) ; D = (D0 * D0)/D;//(D0/D)^2if(D<0.00001) D=0.00001;//ButterWorth高通滤波double H = 1/(1+D*D);//n=2FD[x + y*w]=complex<double>(FD[x + y*w].real()*H,FD[x + y*w].imag()*H);//h*w}}DoIFFT( TD,  FD, w,h,"ButtWorth低通",CPoint(0,0));// 恢复光标EndWaitCursor();// 删除临时变量delete [] TD;delete [] FD;}void CImageProcessView::OnUpdateButterworthLowfilter(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnUpdateButterworthHighfilter(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::DoIFFT(complex<double>* TD, complex<double>* FD, int w, int h,CString title,CPoint startP)//del 0,0-startP-1 {CImageProcessDoc* pDoc = GetDocument();unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){return ;}unsigned char*lpSrc;lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);int wp=int(log((double) w)/log(2.0));int hp=int(log((double) h)/log(2.0));for(int i = 0; i < h; i++){// 对x方向进行快速付立叶变换IFFT( &FD[i * w],&TD[i * w], wp);}// 保存变换结果for(int i = 0; i < h; i++){for(int j = 0; j < w; j++){FD[i + h * j] = TD[j + w * i];//w*h }}for(int i = 0; i < w; i++){// 对y方向进行快速付立叶变换IFFT(&FD[h * i],&TD[h * i],hp);}//TD hxw //转置double dTemp;double dmax=0.0;for(int i = 0; i < h; i++){for(int j = 0; j < w; j++){dTemp=TD[j * h + i].real();//move backif((i+j)%2) dTemp=-dTemp;if(dTemp>dmax) dmax=dTemp;}}if(dmax<255) dmax=255;//no make bright for(int i = 0; i < h; i++){for(int j = 0; j < w; j++){dTemp=TD[j * h + i].real();//move backif((i+j)%2) dTemp=-dTemp;dTemp=dTemp/dmax*255.0;if (dTemp<0)dTemp=0;if(j<lWidth-pDoc->StartPoint.x && i<lHeight-pDoc->StartPoint.y){lpSrc =lpNewDIBBits + lLineBytes* (lHeight - 1 - i-pDoc->StartPoint.y) + j+pDoc->StartPoint.x;// 更新源图像if(j<startP.x || i<startP.y)*(lpSrc) =0;//错误处置0else*(lpSrc) = (BYTE)(dTemp);}}}CString str=pDoc->GetTitle();str+=title;DisplayNewImg(lpNewDIBBits, lLineBytes,lHeight,str);delete []lpNewDIBBits;return ;}void CImageProcessView::OnFrequencydomainHomomorphicfilter(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();//copy imgunsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL)return ;memcpy( lpNewDIBBits,pDoc->m_pDib->m_lpImage, lLineBytes * lHeight);//processCPoint wh=FrequencydomainSelectarea();int w=wh.x;int h=wh.y;// 分配内存complex<double> *TD = new complex<double>[w * h];complex<double> *FD = new complex<double>[w * h];//1 lnf(x,y)unsigned char*lpSrc;for(int i = 0; i < h; i++){for(int j = 0; j < w; j++){if(i+pDoc->StartPoint.y<lHeight && pDoc->StartPoint.x+j<lWidth){lpSrc = (unsigned char*)pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - i-pDoc->StartPoint.y) + pDoc->StartPoint.x+j;// 给时域赋值TD[j + w * i] = complex<double>(log((double)(max(*lpSrc,1))), 0);//w*h}else{TD[j + w * i] = complex<double>(0,0);}}}//2:FFT//move to centerfor(int y=0; y<h; y++)for(int x=0; x<w; x++)if((x+y)%2) TD[y*w + x]=-TD[y*w + x];int wp=int(log((double) w)/log(2.0));int hp=int(log((double) h)/log(2.0));for(int i = 0; i < h; i++){// 对y方向进行快速付立叶变换FFT(&TD[w * i], &FD[w * i], wp);//w}// 保存变换结果for(int i = 0; i < h; i++){for(int j = 0; j < w; j++){TD[i + h * j] = FD[j + w * i];//h*w}}for(int i = 0; i < w; i++){// 对x方向进行快速付立叶变换FFT(&TD[i * h], &FD[i * h], hp);//h}//3. filterconst double D0=5;const double rH=2.0;const double rL=.5;const double c=1.0;for(int y=0; y<h; y++){for(int x=0; x<w; x++){doubleD = (double)((y-h/2)*(y-h/2)+(x-w/2)*(x-w/2)) ; D = D/(D0 * D0);double H =(rH-rL)*(1-exp(-c*D))+rL;if(D==0.0) H=1.0;//get brightFD[y + x*h]=complex<double>(FD[y + x*h].real()*H,FD[y + x*h].imag()*H);//h*w}}//4.IFFTfor(int i = 0; i < w; i++){// 对x方向进行快速付立叶变换IFFT( &FD[i * h],&TD[i * h], hp);}// 保存变换结果for(int i = 0; i < h; i++){for(int j = 0; j < w; j++){FD[j + w * i] = TD[i + h * j];//w*h }}for(int i = 0; i < h; i++){// 对y方向进行快速付立叶变换IFFT(&FD[w * i],&TD[w * i],wp);}//5.expdouble dTemp;for(int i = 0; i < h; i++){for(int j = 0; j < w; j++){dTemp=TD[i * w + j].real();//move backif((i+j)%2) dTemp=-dTemp;dTemp=exp(dTemp);if (dTemp > 255)dTemp = 255;if(j<lWidth-pDoc->StartPoint.x && i<lHeight-pDoc->StartPoint.y){lpSrc =pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - i-pDoc->StartPoint.y) + j+pDoc->StartPoint.x;// 更新源图像* (lpSrc) = (BYTE)dTemp;}}}CString str=pDoc->GetTitle();DisplayNewImg(pDoc->m_pDib->m_lpImage,lLineBytes,lHeight,str+"--+同态滤波");//display orignal image//get img backpDoc->SetTitle(str);memcpy( pDoc->m_pDib->m_lpImage,lpNewDIBBits, lLineBytes * lHeight);delete [] lpNewDIBBits;// 恢复光标EndWaitCursor();// 删除临时变量delete [] TD;delete [] FD;}void CImageProcessView::OnUpdateFrequencydomainHomomorphicfilter(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnFileGetmodal(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();m_ModelWidth=pDoc->EndPoint.x-pDoc->StartPoint.x+1;m_ModelWidth=(m_ModelWidth+3)/4*4;m_ModelHeight=pDoc->EndPoint.y- pDoc->StartPoint.y+1;if(m_pModelData)delete []m_pModelData;m_pModelData=new unsigned char [m_ModelWidth*m_ModelHeight];unsigned char*lpSrc;unsigned char* lpDst;lpDst=m_pModelData;;for (int i = 0; i <m_ModelHeight; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i-pDoc->StartPoint.y) + pDoc->StartPoint.x-1;for (int j =0; j <m_ModelWidth; j ++){lpSrc++;*lpDst=*lpSrc;lpDst++;}}//DisplayNewImg(m_pModelData,m_ModelWidth,m_ModelHeight,"Moda");}void CImageProcessView::OnUpdateFileGetmodal(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnSpatialdomainImage(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;unsigned char*lpDst;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){return ;}BeginWaitCursor();lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);for (int i = pDoc->StartPoint.y; i <=min(pDoc->EndPoint.y,m_ModelHeight-1+pDoc->StartPoint.y); i ++){lpSrc = lpNewDIBBits +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpDst = m_pModelData+ m_ModelWidth * (i-pDoc->StartPoint.y)-1;for (int j =pDoc->StartPoint.x; j <=min(pDoc->EndPoint.x,m_ModelWidth-1+pDoc->StartPoint.x); j ++){lpSrc++;lpDst++;int Tmp=128+*(lpSrc)-*lpDst;if(Tmp>255) Tmp=255;else if(Tmp<0)Tmp=0;*lpSrc=(unsigned char)Tmp;}}CString str=pDoc->GetTitle();DisplayNewImg(lpNewDIBBits,lLineBytes,lHeight,str+"-Moda");// 恢复光标EndWaitCursor();// 释放内存delete []lpNewDIBBits;}void CImageProcessView::OnUpdateSpatialdomainImage(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)if(m_pModelData)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnConvolutionMean(){// TODO: Add your command handler code here//CImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();CPoint wh=FrequencydomainSelectarea();int w=wh.x;int h=wh.y;// 分配内存complex<double> *TD = new complex<double>[w * h];complex<double> *FD = new complex<double>[w * h];DoFFT( TD,  FD, w,h);complex<double> *HTD = new complex<double>[w * h];complex<double> *HFD = new complex<double>[w * h];for(int i = 0; i < h; i++)for(int j = 0; j < w; j++)HTD[j + w * i]=0.0;for(int i = 0; i < 3; i++)for(int j = 0; j < 3; j++)HTD[j + w * i]=1.0/9;FFT2( HTD, HFD, w,h);DisplayFw(HFD,w, h,20.0,"均值滤波|H(u,v)|");//procfor(int i = 0; i < h; i++){for(int j = 0; j < w; j++){FD[j + w * i]*=HFD[j + w * i];}}DoIFFT( TD,  FD, w,h,"频域均值滤波",CPoint(2,2));//0,1 err// 恢复光标EndWaitCursor();// 删除临时变量delete [] TD;delete [] FD;delete [] HTD;delete [] HFD;}void CImageProcessView::OnUpdateConvolutionMean(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnConvolutionGauss(){// TODO: Add your command handler code here//CImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();CPoint wh=FrequencydomainSelectarea();int w=wh.x;int h=wh.y;// 分配内存complex<double> *TD = new complex<double>[w * h];complex<double> *FD = new complex<double>[w * h];DoFFT( TD,  FD, w,h);complex<double> *HTD = new complex<double>[w * h];complex<double> *HFD = new complex<double>[w * h];for(int i = 0; i < h; i++)for(int j = 0; j < w; j++)HTD[j + w * i]=0.0;//Gauss 5*5HTD[2 + w * 2]=12.0/76.0;HTD[1 + w * 2]=HTD[3 + w * 2]=HTD[2 + w * 1]=HTD[2 + w * 3]=7.0/76.0;HTD[1 + w * 1]=HTD[1 + w * 3]=HTD[3 + w * 1]=HTD[3 + w * 3]=5.0/76.0;HTD[0 + w * 2]=HTD[2 + w * 0]=HTD[4 + w * 2]=HTD[2 + w * 4]=2.0/76.0;HTD[0 + w * 1]=HTD[1 + w * 0]=HTD[0 + w * 3]=HTD[3 + w * 0]=1.0/76.0;HTD[1 + w * 4]=HTD[4 + w * 1]=HTD[4 + w * 3]=HTD[3 + w * 4]=1.0/76.0;FFT2( HTD, HFD, w,h);DisplayFw(HFD,w, h,20.0,"高斯滤波|H(u,v)|");//procfor(int i = 0; i < h; i++){for(int j = 0; j < w; j++){FD[j + w * i] *=HFD[j + w * i];}}DoIFFT( TD,  FD, w,h,"频域高斯滤波",CPoint(4,4));// 恢复光标EndWaitCursor();// 删除临时变量delete [] TD;delete [] FD;delete [] HTD;delete [] HFD;}void CImageProcessView::OnUpdateConvolutionGauss(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnConvolutionLaplace(){// TODO: Add your command handler code here//CImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();CPoint wh=FrequencydomainSelectarea();int w=wh.x;int h=wh.y;// 分配内存complex<double> *TD = new complex<double>[w * h];complex<double> *FD = new complex<double>[w * h];DoFFT( TD,  FD, w,h);complex<double> *HTD = new complex<double>[w * h];complex<double> *HFD = new complex<double>[w * h];for(int i = 0; i < h; i++)for(int j = 0; j < w; j++)HTD[j + w * i]=0.0;//LaplaceHTD[1 + w * 1]=4.0;HTD[1 + w * 0]=HTD[0 + w * 1]=HTD[2 + w * 1]=HTD[1 + w * 2]=-1.0;FFT2( HTD, HFD, w,h);DisplayFw(HFD,w, h,20.0,"Laplace滤波|H(u,v)|");//procfor(int i = 0; i < h; i++){for(int j = 0; j < w; j++){FD[j + w * i]*=HFD[j + w * i];}}DoIFFT( TD,  FD, w,h,"频域Laplace滤波",CPoint(2,2));//0,1 err// 恢复光标EndWaitCursor();// 删除临时变量delete [] TD;delete [] FD;delete [] HTD;delete [] HFD;}void CImageProcessView::OnUpdateConvolutionLaplace(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnConvolutionMarr(){// TODO: Add your command handler code here//CImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();CPoint wh=FrequencydomainSelectarea();int w=wh.x;int h=wh.y;// 分配内存complex<double> *TD = new complex<double>[w * h];complex<double> *FD = new complex<double>[w * h];DoFFT( TD,  FD, w,h);complex<double> *HTD = new complex<double>[w * h];complex<double> *HFD = new complex<double>[w * h];for(int i = 0; i < h; i++)for(int j = 0; j < w; j++)HTD[j + w * i]=0.0;//Marr 5*5HTD[2 + w * 2]=24.0;HTD[1 + w * 2]=HTD[3 + w * 2]=HTD[2 + w * 1]=HTD[2 + w * 3]=8.0;HTD[1 + w * 1]=HTD[1 + w * 3]=HTD[3 + w * 1]=HTD[3 + w * 3]=0.0;HTD[0 + w * 1]=HTD[0 + w * 2]=HTD[0 + w * 3]=-4.0;HTD[1 + w * 0]=HTD[2 + w * 0]=HTD[3 + w * 0]=-4.0;HTD[4 + w * 1]=HTD[4 + w * 2]=HTD[4 + w * 3]=-4.0;HTD[1 + w * 4]=HTD[2 + w * 4]=HTD[3 + w * 4]=-4.0;HTD[0 + w * 0]=HTD[4 + w * 0]=HTD[0 + w * 4]=HTD[4 + w * 4]=-2.0;FFT2( HTD, HFD, w,h);DisplayFw(HFD,w, h,10.0,"Marr滤波|H(u,v)|");//procfor(int i = 0; i < h; i++){for(int j = 0; j < w; j++){FD[j + w * i] *=HFD[j + w * i];}}DoIFFT( TD,  FD, w,h,"频域Marr滤波",CPoint(4,4));// 恢复光标EndWaitCursor();// 删除临时变量delete [] TD;delete [] FD;delete [] HTD;delete [] HFD;}void CImageProcessView::OnUpdateConvolutionMarr(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnConvolutionCorrelation(){// TODO: Add your command handler code here//CImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();CPoint wh=FrequencydomainSelectarea();int w=wh.x;int h=wh.y;// 分配内存complex<double> *TD = new complex<double>[w * h];complex<double> *FD = new complex<double>[w * h];DoFFT( TD,  FD, w,h);complex<double> *HTD = new complex<double>[w * h];complex<double> *HFD = new complex<double>[w * h];unsigned char *lpSrc;for(int i = 0; i < h; i++){for(int j = 0; j < w; j++){if(i<m_ModelHeight && j<m_ModelWidth){lpSrc = m_pModelData + m_ModelWidth * i + j;// 给时域赋值HTD[j + w * i] = complex<double>(*(lpSrc), 0);//}else{HTD[j + w * i] = complex<double>(0,0);}}}FFT2( HTD, HFD, w,h);//DisplayFw(FD,w, h,.6,"|F(u,v)|");//DisplayFw(HFD,w, h,.6,"|H(u,v)|");//DoIFFT( TD,  FD, w,h,"F(x,y)",CPoint(0,0));//procfor(int i = 0; i < h; i++){for(int j = 0; j < w; j++){   HFD[j + w * i]=complex<double>(HFD[j + w * i].real(), -HFD[j + w * i].imag());//共轭FD[j + w * i]*=HFD[j + w * i];//FD[j + w * i]=FD[j + w * i]*HFD[j + w * i] ; 错!//FD[j + w * i]=complex<double>(FD[j + w * i].real(), -FD[j + w * i].imag());//共轭//FD[j + w * i]*=HFD[j + w * i];//FD[j + w * i]=FD[j + w * i]*HFD[j + w * i] ; 错!}}//DisplayFw(FD,w, h,.6,"|F*(u,v)H(u,v)|");//DoIFFT( HTD,  HFD, w,h,"h(x,y)",CPoint(0,0));DoIFFT( TD,  FD, w,h,"频域相关运算",CPoint(m_ModelWidth/2,m_ModelHeight/2));// 恢复光标EndWaitCursor();// 删除临时变量delete [] TD;delete [] FD;delete [] HTD;delete [] HFD;}void CImageProcessView::OnUpdateConvolutionCorrelation(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)if(m_pModelData)bAvail=true;pCmdUI->Enable(bAvail);}//利用噪声方差,判断局部方差,噪声处进行平滑,边缘处不处理void CImageProcessView::OnAdaptiveNoisereduction(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();//copy imgunsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL)return ;memcpy( lpNewDIBBits,pDoc->m_pDib->m_lpImage, lLineBytes * lHeight);const int M=7;//oddconst int N=7;//odddouble mean;double Dev2;unsigned char*lpSrc;unsigned char*lpDst;const double Dev_Noise2=1000.0;for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;if(i>=M/2 && i<lHeight-M/2 && j>=N/2 && j<lWidth-N/2){//Get M*N meanmean=0.0;for(int m=-M/2;m<=M/2;m++)for(int n=-N/2;n<=N/2;n++)mean+=*(lpSrc+ lLineBytes* m+n);mean/=(M*N);Dev2=0.0;for(int m=-M/2;m<=M/2;m++)for(int n=-N/2;n<=N/2;n++)Dev2+=((*(lpSrc+ lLineBytes* m+n)-mean)*(*(lpSrc+ lLineBytes*m+n)-mean));Dev2/=(M*N);double dtmp;if(Dev_Noise2>Dev2)dtmp=mean;elsedtmp=*lpSrc-Dev_Noise2/Dev2*(*lpSrc-mean);if(dtmp<0) {dtmp=0;//can get min adjust }else if(dtmp>255) dtmp=255;*lpDst=(unsigned char)dtmp;//}}}CString str=pDoc->GetTitle();DisplayNewImg(lpNewDIBBits,lLineBytes,lHeight,str+"--+自适应局部噪声消除滤波");//delete [] lpNewDIBBits;// 恢复光标EndWaitCursor();}void CImageProcessView::OnUpdateAdaptiveNoisereduction(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}//判断某点是否为脉冲,若是,其中值是否为脉冲,y,扩大(小于最大值)邻域使其非脉冲void CImageProcessView::OnAdaptiveMedian(){CImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();const int Mmax=7;//maxconst int Nmax=7;//oddconst int Mmin=5;//maxconst int Nmin=5;//oddconst int PluseL=20;const int PluseH=220;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){return ;}unsigned char*lpSrc;unsigned char*lpDst;lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);unsigned char *v=new unsigned char[Mmax*Nmax];//[N*M];//line N Column M not rect (int err) for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;if(*lpSrc>PluseL && *lpSrc<PluseH) continue;int M=Mmin;int N=Nmin;bool bOver=false;while(!bOver){//Get M*N data to v[]int vSize=0;for(int m=-M/2;m<=M/2;m++){for(int n=-N/2;n<=N/2;n++){if(i-m>=0 && i-m<lHeight && j+n>=0 && j+n<lWidth){v[vSize]=*(lpSrc+lLineBytes*m+n);vSize++;}}}//sort v[]for(int m=0;m<vSize-1;m++){for(int n=m+1;n<vSize;n++)if(v[m]>v[n]){//swapBYTE tmp=v[m];v[m]=v[n];v[n]=tmp;}}int Th=vSize/2;if(v[Th]>max(v[0],PluseL) && v[Th]<min(v[vSize-1],PluseH)){*lpDst=v[Th];bOver=true;}else{//need change M,N biggerM+=2;N+=2;if(M>Mmax){bOver=true;*lpDst=v[Th];}}}}}CString str=pDoc->GetTitle();DisplayNewImg(lpNewDIBBits,lLineBytes,lHeight,str+"--+自适应中值滤波");//// 释放内存delete []lpNewDIBBits;delete []v;// 恢复光标EndWaitCursor();}void CImageProcessView::OnUpdateAdaptiveMedian(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnFrequencydomainNotchpassfilter(){// TODO: Add your command handler code here//CImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();CPoint wh=FrequencydomainSelectarea();int w=wh.x;int h=wh.y;// 分配内存complex<double> *TD = new complex<double>[w * h];complex<double> *FD = new complex<double>[w * h];DoFFT( TD,  FD, w,h);//DisplayFw(FD,w, h,0.6,"|F(u,v)|");//filter//去除水平扫描线//const double D0=30.0;for(int y=0; y<h; y++){for(int x=w/2-3; x<=w/2+3; x++){if(y<h/2-10 || y>h/2+10)FD[x + y*w]=complex<double>(0,0);//h*w}}//DisplayFw(FD,w, h,0.6,"|F(u,v)H(u,v)|");DoIFFT( TD,  FD, w,h,"陷波滤波器",CPoint(0,0));// 恢复光标EndWaitCursor();// 删除临时变量delete [] TD;delete [] FD;}void CImageProcessView::OnUpdateFrequencydomainNotchpassfilter(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}//不太理想,无书中图像//提取噪声图像,利用方差最小获取比例参数w,f=g-w*nvoid CImageProcessView::OnFrequencydomainOptimumnotchfilter(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();CPoint wh=FrequencydomainSelectarea();int w=wh.x;int h=wh.y;// 分配内存complex<double> *TD = new complex<double>[w * h];complex<double> *FD = new complex<double>[w * h];DoFFT( TD,  FD, w,h);//DisplayFw(FD,w, h,0.6,"|F(u,v)|");//filter//const double F0=FD[h/2*w + w/2].real();for(int y=0; y<h; y++){for(int x=0; x<w; x++){//if((y-h/2)*(y-h/2)+(x-w/2)*(x-w/2)<400)if(!((y<h/2-20 || y>h/2+20) && (x>w/2-5 && x<w/2+5)))FD[x + y*w]=complex<double>(0,0);}}//DisplayFw(FD,w, h,0.6,"|F(u,v)H(u,v)|");//IFFTint wp=int(log((double) w)/log(2.0));int hp=int(log((double) h)/log(2.0));for(int i = 0; i < w; i++){// 对x方向进行快速付立叶变换IFFT( &FD[i * h],&TD[i * h], hp);}// 保存变换结果for(int i = 0; i < h; i++){for(int j = 0; j < w; j++){FD[j + w * i] = TD[i + h * j];//w*h }}for(int i = 0; i < h; i++){// 对y方向进行快速付立叶变换IFFT(&FD[w * i],&TD[w * i],wp);}//再转置还原for(int i = 0; i < h; i++){for(int j = 0; j < w; j++){FD[j + w * i] = TD[i + h * j];//转置}}for(int i = 0; i < h; i++){for(int j = 0; j < w; j++){TD[j + w * i] = FD[j + w * i];}}//1.noiseunsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL)return ;unsigned char* lpSrc;unsigned char* lpSrc1;double dTemp;for(int i = 0; i < h; i++){for(int j = 0; j < w; j++){dTemp=TD[i * w + j].real();//move backif((i+j)%2) dTemp=-dTemp;if (dTemp > 255)dTemp = 255;if (dTemp < 0) dTemp=0;if(j<lWidth-pDoc->StartPoint.x && i<lHeight-pDoc->StartPoint.y){lpSrc =lpNewDIBBits + lLineBytes * (lHeight - 1 - i-pDoc->StartPoint.y) + j+pDoc->StartPoint.x;lpSrc1 =pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - i-pDoc->StartPoint.y) + j+pDoc->StartPoint.x;// 更新源图像* (lpSrc) = (BYTE)dTemp;}}}//2.方差最小unsigned char*lpNewDIBBits1;lpNewDIBBits1=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits1 == NULL)return ;lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits1,lpSrc, lLineBytes * lHeight);unsigned char* lpDst;const int M=15;const int N=15;int size=M*N;for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpSrc1 =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;lpDst =lpNewDIBBits1 + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpSrc1++;lpDst++;if(i>M/2 && i<lHeight-M/2 && j>N/2 && j<lWidth-N/2){//double gAv=0.0,nAv=0.0,gnAv=0.0,n2Av=0.0; for(int m=-M/2;m<=M/2;m++){for(int n=-N/2;n<=N/2;n++){gAv+=*(lpSrc-lLineBytes*m+n);nAv+=*(lpSrc1-lLineBytes*m+n);gnAv+=(*(lpSrc-lLineBytes*m+n)*(*(lpSrc1-lLineBytes*m+n)));n2Av+=(*(lpSrc1-lLineBytes*m+n)*(*(lpSrc1-lLineBytes*m+n)));}}gAv/=size;nAv/=size;gnAv/=size;n2Av/=size;double wi=n2Av-nAv*nAv;if(wi>0.001 || wi<-0.001)wi=(gnAv-gAv*nAv)/wi;else wi=0.0;int v=(int)(*lpSrc-wi*(*lpSrc1));if(v>255) v=255;else if(v<0) v=0;*lpDst=(BYTE) v;}}}CString str=pDoc->GetTitle();DisplayNewImg(lpNewDIBBits1,lLineBytes,lHeight,str+"最佳陷波滤波器");DisplayNewImg(lpNewDIBBits,lLineBytes,lHeight,str+"噪声图像");// 恢复光标EndWaitCursor();// 删除临时变量delete [] TD;delete [] FD;delete [] lpNewDIBBits;delete [] lpNewDIBBits1;}void CImageProcessView::OnUpdateFrequencydomainOptimumnotchfilter(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}//最小均方误差//已知退化系统函数,添加噪声(假设为白噪声),恢复图像//K很难调,K=0为逆滤波void CImageProcessView::OnFrequencydomainWinnerfilter(){// TODO: Add your command handler code here//CImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();CPoint wh=FrequencydomainSelectarea();int w=wh.x;int h=wh.y;// 分配内存complex<double> *TD = new complex<double>[w * h];complex<double> *FD = new complex<double>[w * h];DoFFT( TD,  FD, w,h);//DisplayFw(FD,w, h,0.6,"|F(u,v)|");//filterdouble c1=0.1;double c2=0.1;double T=1.0;double K=.025;//chgdouble minH=0.001;for(int y=0; y<h; y++){for(int x=0; x<w; x++){doubleuv=Pi*(c1*(x-w/2)+c2*(y-h/2)) ; complex<double> H ;if(uv==0.0)H= complex<double>(T,0.0);else H= complex<double>(T/(uv)*sin(uv)*cos(uv),-T/(uv)*sin(uv)*sin(uv)); if(H.real()>=0 && H.real()<=minH)H= complex<double>(minH,H.imag());if(H.imag()>=0 && H.imag()<=minH)H= complex<double>(H.real(),minH);if(H.real()<0 && H.real()>=-minH)H= complex<double>(-minH,H.imag());if(H.imag()<0 && H.imag()>=-minH)H= complex<double>(H.real(),-minH);// |H(u,v)|*|H(u,v)|double norm = abs(H);// |H(u,v)|*|H(u,v)|/(|H(u,v)|*|H(u,v)|+K)double temp  = (norm*norm ) / (norm*norm +K);// 求得f(u,v)FD[y*w + x]*=temp;FD[y*w + x]/=H;}}//DisplayFw(FD,w, h,0.6,"|F(u,v)H(u,v)|");DoIFFT( TD,  FD, w,h,"维纳滤波器",CPoint(0,0));// 恢复光标EndWaitCursor();// 删除临时变量delete [] TD;delete [] FD;}void CImageProcessView::OnUpdateFrequencydomainWinnerfilter(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnFrequencydomainLeastsquaresfilter(){// TODO: Add your command handler code here//CImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();CPoint wh=FrequencydomainSelectarea();int w=wh.x;int h=wh.y;// 分配内存complex<double> *TD = new complex<double>[w * h];complex<double> *FD = new complex<double>[w * h];DoFFT( TD,  FD, w,h);//DisplayFw(FD,w, h,0.6,"|F(u,v)|");complex<double> *PTD = new complex<double>[w * h];complex<double> *PFD = new complex<double>[w * h];//Laplacefor(int y=0; y<h; y++)for(int x=0; x<w; x++)PTD[x + w * y]=0.0;PTD[1 + w * 1]=4.0;PTD[1 + w * 0]=PTD[0 + w * 1]=PTD[2 + w * 1]=PTD[1 + w * 2]=-1.0;FFT2(PTD,PFD, w, h);//filterdouble c1=0.1;double c2=0.1;double T=1.0;double r=0.2;double minH=0.001;for(int y=0; y<h; y++){for(int x=0; x<w; x++){doubleuv=Pi*(c1*(x-w/2)+c2*(y-h/2)) ; complex<double> H ;if(uv==0.0)H= complex<double>(T,0.0);else H= complex<double>(T/(uv)*sin(uv)*cos(uv),-T/(uv)*sin(uv)*sin(uv)); if(H.real()>=0 && H.real()<=minH)H= complex<double>(minH,H.imag());if(H.imag()>=0 && H.imag()<=minH)H= complex<double>(H.real(),minH);if(H.real()<0 && H.real()>=-minH)H= complex<double>(-minH,H.imag());if(H.imag()<0 && H.imag()>=-minH)H= complex<double>(H.real(),-minH);// |H(u,v)|double norm = abs(H);// |P(u,v)|double Pnorm = abs(PFD[y*w+x]);// H*(u,v)/(|H(u,v)|^2+r|p(u,v)|^2)complex<double> temp( complex<double>(H.real(),-H.imag()));temp=temp/(norm*norm+r*Pnorm*Pnorm);// 求得f(u,v)FD[y*w + x]*=temp;}}//DisplayFw(FD,w, h,0.6,"|F(u,v)H(u,v)|");DoIFFT( TD,  FD, w,h,"约束最小二乘法滤波器",CPoint(0,0));// 恢复光标EndWaitCursor();// 删除临时变量delete [] TD;delete [] FD;delete [] PTD;delete [] PFD;}void CImageProcessView::OnUpdateFrequencydomainLeastsquaresfilter(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}//设定多个畸变点,获得其校正后坐标//将图像分成多个区域,对应区域满足线性平面//解方程获得线性参数,对图像进行几何变换,可完成图像畸变、畸变校正void CImageProcessView::OnSpatialdomainGeometrictransformations(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();//1.获得对应点//4x4 对称区域const int N=3; CPoint pt1[(N+1)*(N+1)];CPoint pt2[(N+1)*(N+1)];int h=(pDoc->EndPoint.y-pDoc->StartPoint.y+1)/N;int w=(pDoc->EndPoint.x-pDoc->StartPoint.x+1)/N;int k=0;////使图像畸变//for(int j=pDoc->StartPoint.y;j<pDoc->EndPoint.y;j+=h)//for(int i=pDoc->StartPoint.x;i<pDoc->EndPoint.x;i+=w)//{//pt1[k]=CPoint(i,j);//k++;//}////for(int i=0;i<(N+1)*(N+1);i++)//pt2[i]=pt1[i]+CPoint(2,2);////pt2[N+2]+=CPoint(-40,-10);//pt2[N+3]+=CPoint(20,40);////pt2[2*N+3]+=CPoint(-25,-10);//pt2[2*N+4]+=CPoint(15,25);////使畸变图像校正for(int j=pDoc->StartPoint.y;j<pDoc->EndPoint.y;j+=h)for(int i=pDoc->StartPoint.x;i<pDoc->EndPoint.x;i+=w){pt2[k]=CPoint(i,j);k++;}for(int i=0;i<(N+1)*(N+1);i++)pt1[i]=pt2[i]+CPoint(2,2);pt1[N+2]+=CPoint(-40,-10);pt1[N+3]+=CPoint(20,40);pt1[2*N+3]+=CPoint(-25,-10);pt1[2*N+4]+=CPoint(15,25);//2.获得对应变换系数(8)double c[N*N][8];for(int k=0;k<N*N;k++){// 构造矩阵CMatrix mtxA(8,8), mtxB(8,1),mtxC(8,1);double value[64]={0};double value1[8]={0};value[0] =pt1[k+k/3+0].x; value[1]=pt1[k+k/3+0].y;  value[2]=pt1[k+k/3+0].x*pt1[k+k/3+0].y;   value[3]=1;value[12]=pt1[k+k/3+0].x; value[13]=pt1[k+k/3+0].y; value[14]=pt1[k+k/3+0].x*pt1[k+k/3+0].y;  value[15]=1;value[16] =pt1[k+k/3+1].x; value[17]=pt1[k+k/3+1].y;  value[18]=pt1[k+k/3+1].x*pt1[k+k/3+1].y;  value[19]=1;value[28]=pt1[k+k/3+1].x; value[29]=pt1[k+k/3+1].y; value[30]=pt1[k+k/3+1].x*pt1[k+k/3+1].y;    value[31]=1;value[32] =pt1[k+k/3+1+N].x; value[33]=pt1[k+k/3+1+N].y;  value[34]=pt1[k+k/3+1+N].x*pt1[k+k/3+1+N].y;  value[35]=1;value[44]=pt1[k+k/3+1+N].x; value[45]=pt1[k+k/3+1+N].y; value[46]=pt1[k+k/3+1+N].x*pt1[k+k/3+1+N].y;    value[47]=1;value[48] =pt1[k+k/3+2+N].x; value[49]=pt1[k+k/3+2+N].y;  value[50]=pt1[k+k/3+2+N].x*pt1[k+k/3+2+N].y;  value[51]=1;value[60]=pt1[k+k/3+2+N].x; value[61]=pt1[k+k/3+2+N].y; value[62]=pt1[k+k/3+2+N].x*pt1[k+k/3+2+N].y;    value[63]=1;value1[0]=pt2[k+k/3+0].x;value1[1]=pt2[k+k/3+0].y;value1[2]=pt2[k+k/3+1].x;value1[3]=pt2[k+k/3+1].y;value1[4]=pt2[k+k/3+1+N].x;value1[5]=pt2[k+k/3+1+N].y;value1[6]=pt2[k+k/3+2+N].x;value1[7]=pt2[k+k/3+2+N].y;mtxA.SetData(value);mtxB.SetData(value1);// 构造线性方程组CLEquations leqs(mtxA, mtxB);// 全选主元高斯消去法CString m_strResult;if (leqs.GetRootsetGauss(mtxC))m_strResult = mtxC.ToString(" ");else{m_strResult ="求解失败";// 显示数据AfxMessageBox(m_strResult, MB_OK|MB_ICONINFORMATION);return;}memcpy(c[k],mtxC.GetData(),8*sizeof(double));}//3.几何校正unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){return ;}unsigned char*lpSrc;unsigned char*lpDst;lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);for (int i = pDoc->StartPoint.y+2; i <pDoc->EndPoint.y-2; i ++){for (int j =pDoc->StartPoint.x+2; j <pDoc->EndPoint.x-2; j ++){lpDst = (unsigned char*)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j;//为了方便,不去判断具体区域,忍让边界处错误int k=min(((i-pDoc->StartPoint.y)/h),N-1)*3+min((j-pDoc->StartPoint.x)/w,N);double x=c[k][0]*j+c[k][1]*i+c[k][2]*i*j+c[k][3];double y=c[k][4]*j+c[k][5]*i+c[k][6]*i*j+c[k][7];int x1=(int)x;int y1=(int)y;if(x1>=0 && x1<lWidth-1 && y1>=0 && y1<lHeight-1){//inlpSrc = (unsigned char*)pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - y1) + x1;int v=(unsigned char)((y1+1-y)*((x1+1-x)*(*lpSrc)+(x-x1)*(*(lpSrc+1)))+(y-y1)*((x1+1-x)*(*(lpSrc-lLineBytes))+(x-x1)*(*(lpSrc-lLineBytes+1))));//a=x-x1 b=y-y1 if(v<0) v=0;else if(v>255) v=255;*lpDst=(BYTE)v;//*lpDst=*(pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - (int)(y+0.5)) + (int)(x+0.5));//近邻插值}}}CString str=pDoc->GetTitle();DisplayNewImg(lpNewDIBBits,lLineBytes,lHeight,str+"--+运用角点几何校正");//delete [] lpNewDIBBits;// 恢复光标EndWaitCursor();}void CImageProcessView::OnUpdateSpatialdomainGeometrictransformations(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnDwtDwt(){CImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();CPoint wh=FrequencydomainSelectarea();int w=wh.x;int h=wh.y;const int LEVEL=2;CString str=pDoc->GetTitle();DisplayNewImg(pDoc->m_pDib->m_lpImage, lLineBytes,lHeight,str);m_bDWT=!m_bDWT;DoDWT(w,h,LEVEL);// 恢复光标EndWaitCursor();}void CImageProcessView::DoDWT(int w,int h,int LEVEL){CImageProcessDoc* pDoc = GetDocument();//input data// 分配内存double *image = new double [w * h];unsigned char* lpSrc;for(int i = 0; i < h; i++){for(int j = 0; j < w; j++){// 指向DIB第i行,第j个象素的指针if(i+pDoc->StartPoint.y<lHeight && pDoc->StartPoint.x+j<lWidth){lpSrc = (unsigned char*)pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - i-pDoc->StartPoint.y) + pDoc->StartPoint.x+j;image[j + w * i] = (double)*(lpSrc);//w*h}elseimage[j + w * i] = 0;//out of image:add 0}}int wp=int(log((double) w)/log(2.0));int hp=int(log((double) h)/log(2.0));int nDWTCurDepth=0;int nCurWLevel=wp;int nCurHLevel=hp;while( min(nCurWLevel,nCurHLevel)>min(wp,hp)-LEVEL){// 进行小波变换// 计算当前分解的图象的长度和宽度int CurW = 1<<nCurWLevel, CurH = 1<<nCurHLevel;// 对行进行一维DWTfor (int i=0; i<CurH; i++)DWTStep_1D(image+w*i, nCurWLevel, 0, 1,2);// 对列进行一维DWTfor (int i=0; i<CurW; i++)DWTStep_1D(image+i, nCurHLevel, 0, w,2);nDWTCurDepth ++;nCurWLevel=wp-nDWTCurDepth;nCurHLevel=hp-nDWTCurDepth;}// 然后,将数据拷贝回原CDib中,并进行相应的数据转换int lfw;int lfh;lfw = w>>nDWTCurDepth, lfh = h>>nDWTCurDepth;for(int i = 0; i < h; i++){// 列for(int j = 0; j < w; j++){double f=image[i * w + j];unsigned char tmp;if (i<lfh && j<lfw){//FloatToByteif (f<=0) tmp=(BYTE)0;else if (f>=255) tmp=(BYTE)255;else tmp=(BYTE)(f+0.5);}else{//FloatToCharchar temp;if (f>=0){if (f>=127.5)temp= (char)127;else temp=(char)(f+0.5);}else{if (f<=-128)temp= (char)-128;else temp= -(char)(-f+0.5);}tmp=(BYTE)(temp ^0x80);//+128}if(j<lWidth-pDoc->StartPoint.x && i<lHeight-pDoc->StartPoint.y){lpSrc =  pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - i-pDoc->StartPoint.y) + j+pDoc->StartPoint.x;* (lpSrc) = tmp;}}}CString str=pDoc->GetTitle();pDoc->SetTitle(str+"DWT");// 删除临时变量delete [] image;}/*************************************************************************** \函数名称:*   DWTStep_1D()** \输入参数:*   double * pDbSrc- 指向源数据的指针*   int nCurLevel- 当前分界的层数*   int nInv- 是否为DWT,1表示为IDWT,0表示DWT*   int nStep- 当前的计算层数*   int nSupp- 小波基的紧支集的长度** \返回值:*   BOOL- 成功则返回TRUE,否则返回FALSE** \说明:*   该函数用对存放在pDBSrc中的数据进行一层的一维DWT或者IDWT。其中,nInv为表示进行*   DWT或者IDWT的标志。nCurLevel为当前需要进行分界的层数。nStep为已经分界的层数*   计算后数据仍存放在pDbSrc中***************************************************************************/BOOL  CImageProcessView::DWTStep_1D(double* pDbSrc, int nCurLevel,int nInv, int nStep,int nSupp){// 小波变换函数原型// Daubechies紧致正交小波基//不同支撑区间长度下的滤波器系数如下//only use hCoef[0][]const double hCoef[10][20] ={{ .707106781187,  .707106781187},{ .482962913145,  .836516303738,  .224143868042, -.129409522551 },//use { .332670552950,  .806891509311,  .459877502118, -.135011020010, -.085441273882,  .035226291882 },{ .230377813309,  .714846570553,  .630880767930, -.027983769417,-.187034811719,  .030841381836,  .032883011667, -.010597401785 },{ .160102397974,  .603829269797,  .724308528438,  .138428145901, -.242294887066,-.032244869585,  .077571493840, -.006241490213, -.012580751999,  .003335725285 },{ .111540743350,  .494623890398,  .751133908021,  .315250351709, -.226264693965,-.129766867567,  .097501605587,  .027522865530, -.031582039318,  .000553842201,.004777257511, -.001077301085 },{ .077852054085,  .396539319482,  .729132090846,  .469782287405, -.143906003929,-.224036184994,  .071309219267,  .080612609151, -.038029936935, -.016574541631,.012550998556,  .000429577973, -.001801640704,  .000353713800 },{ .054415842243,  .312871590914,  .675630736297,  .585354683654, -.015829105256,-.284015542962,  .000472484574,  .128747426620, -.017369301002, -.044088253931,.013981027917,  .008746094047, -.004870352993, -.000391740373,  .000675449406,-.000117476784 },{ .038077947364,  .243834674613,  .604823123690,  .657288078051,  .133197385825,-.293273783279, -.096840783223,  .148540749338,  .030725681479, -.067632829061,.000250947115,  .022361662124, -.004723204758, -.004281503682,  .001847646883,.000230385764, -.000251963189,  .000039347320 },{ .026670057901,  .188176800078,  .527201188932,  .688459039454,  .281172343661,-.249846424327, -.195946274377,  .127369340336,  .093057364604, -.071394147166,-.029457536822,  .033212674059,  .003606553567, -.010733175483,  .001395351747,.001992405295, -.000685856695, -.000116466855,  .000093588670, -.000013264203 }};double s = sqrt(2.0);// 获得小波基的指针double* h = (double*)hCoef[nSupp-1];// 确认当前层数有效ASSERT(nCurLevel>=0);// 计算当前层数的长度int CurN = 1<<nCurLevel;if (nInv) CurN <<= 1;// 确认所选择的小波基和当前层数的长度有效if (nSupp<1 || nSupp>10 || CurN<2*nSupp) return FALSE;// 分配临时内存用于存放结果double *ptemp = new double[CurN];if (!ptemp) return FALSE;doubles1, s2;intIndex1, Index2;// 判断是进行DWT还是IDWTif (!nInv){// DWTIndex1=0;Index2=2*nSupp-1;// 进行卷积,其中s1为低频部分,s2为高频部分的结果for (int i=0; i<CurN/2; i++){s1 = s2 = 0;double t = -1;for (int j=0; j<2*nSupp; j++, t=-t){s1 += h[j]*pDbSrc[(Index1 & CurN-1) * nStep];s2 += t*h[j]*pDbSrc[(Index2 & CurN-1) * nStep];Index1++;Index2--;}// 将结果存放在临时内存中ptemp[i] = s1/s;ptemp[i+CurN/2] = s2/s;Index1 -= 2*nSupp;Index2 += 2*nSupp;Index1 += 2;Index2 += 2;}}// 否则进行IDWTelse{// IDWTIndex1 = CurN/2;Index2 = CurN/2-nSupp+1;// 进行卷积,其中其中s1为低频部分,s2为高频部分的结果for (int i=0; i<CurN/2; i++){s1 = s2 = 0;int Index3 = 0;for (int j=0; j<nSupp; j++){s1 += h[Index3]*pDbSrc[(Index1 & CurN/2-1) * nStep]+h[Index3+1]*pDbSrc[((Index2 & CurN/2-1) + CurN/2) * nStep];s2 += h[Index3+1]*pDbSrc[(Index1 & CurN/2-1) * nStep]-h[Index3]*pDbSrc[((Index2 & CurN/2-1) + CurN/2) * nStep];Index3+=2;Index1--,Index2++;}// 将结果存入临时内存ptemp[2*i] = s1*s;ptemp[2*i+1] = s2*s;Index1 += nSupp;Index2 -= nSupp;Index1++;Index2++;}}// 将结果存入源图象中for (long int i=0; i<CurN; i++)pDbSrc[i*nStep] = ptemp[i];// 释放临时内存,并返回delete[] ptemp;return TRUE;}void CImageProcessView::OnUpdateDwtDwt(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)if(!m_bDWT)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnDwtIdwt(){CImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();CString str=pDoc->GetTitle();DisplayNewImg(pDoc->m_pDib->m_lpImage, lLineBytes,lHeight,str);m_bDWT=!m_bDWT;const int LEVEL=2;int w=pDoc->EndPoint.x-pDoc->StartPoint.x+1;int h=pDoc->EndPoint.y-pDoc->StartPoint.y+1;DoIDWT(w,h,LEVEL);// 恢复光标EndWaitCursor();}void CImageProcessView::DoIDWT(int w,int h,int LEVEL){CImageProcessDoc* pDoc = GetDocument();//input data// 分配内存double *image = new double [w * h];unsigned char* lpSrc;int wp=int(log((double) w)/log(2.0));int hp=int(log((double) h)/log(2.0));int nDWTCurDepth=LEVEL;int lfw = 1<<(wp-nDWTCurDepth), lfh = 1<<(hp-nDWTCurDepth);for(int i = 0; i < h; i++){for(int j = 0; j < w; j++){lpSrc = (unsigned char*)pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - i-pDoc->StartPoint.y) + j+pDoc->StartPoint.x;if (i>=lfh || j>=lfw){//CharToFloatimage[j + w * i] = (double)*(lpSrc)-128;//高频}elseimage[j + w * i] = (double)*(lpSrc);//低频}}int nCurWLevel=wp-nDWTCurDepth;int nCurHLevel=hp-nDWTCurDepth;while(nDWTCurDepth>0){// 进行小波反变换// 计算当前分解的图象的长度和宽度int CurW = 1<<nCurWLevel, CurH = 1<<nCurHLevel;CurW <<= 1;CurH <<= 1;// 对列进行IDWTfor (int i=0; i<CurW; i++)DWTStep_1D(image+i, nCurHLevel, 1, w,2);// 对行进行IDWTfor (int i=0; i<CurH; i++)DWTStep_1D(image+w*i, nCurWLevel, 1,1,2);nDWTCurDepth --;nCurWLevel=wp-nDWTCurDepth;nCurHLevel=hp-nDWTCurDepth;}// 然后,将数据拷贝回原CDib中,并进行相应的数据转换for(int i = 0; i < h; i++){// 列for(int j = 0; j < w; j++){double f=image[i * w + j];unsigned char tmp;if (f<=0) tmp=(BYTE)0;else if (f>=255) tmp=(BYTE)255;else tmp=(BYTE)(f+0.5);if(j<lWidth-pDoc->StartPoint.x && i<lHeight-pDoc->StartPoint.y){lpSrc =  pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - i-pDoc->StartPoint.y) + j+pDoc->StartPoint.x;* (lpSrc) = tmp;}}}CString str=pDoc->GetTitle();pDoc->SetTitle(str+"IDWT");// 删除临时变量delete [] image;}void CImageProcessView::OnUpdateDwtIdwt(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)if(m_bDWT)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnEdgeAll(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();unsigned char* lpSrc;int w=pDoc->EndPoint.x-pDoc->StartPoint.x+1;int h=pDoc->EndPoint.y-pDoc->StartPoint.y+1;int wp=int(log((double) w)/log(2.0));int hp=int(log((double) h)/log(2.0));const int LEVEL=2;int nDWTCurDepth=LEVEL;int lfw = 1<<(wp-nDWTCurDepth), lfh = 1<<(hp-nDWTCurDepth);for(int i = 0; i < h; i++){for(int j = 0; j < w; j++){lpSrc = (unsigned char*)pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - i-pDoc->StartPoint.y) + j+pDoc->StartPoint.x;if (i<lfh && j<lfw)*lpSrc = 128;//0}}InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);}void CImageProcessView::OnUpdateEdgeAll(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)if(m_bDWT)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnEdgeH(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();unsigned char* lpSrc;int w=pDoc->EndPoint.x-pDoc->StartPoint.x+1;int h=pDoc->EndPoint.y-pDoc->StartPoint.y+1;int wp=int(log((double) w)/log(2.0));int hp=int(log((double) h)/log(2.0));const int LEVEL=2;int nDWTCurDepth=LEVEL;int lfw = 1<<(wp-nDWTCurDepth), lfh = 1<<(hp-nDWTCurDepth);for(int i = 0; i < h; i++){for(int j = 0; j < w; j++){lpSrc = (unsigned char*)pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - i-pDoc->StartPoint.y) + j+pDoc->StartPoint.x;if (i<lfh && j<lfw)*lpSrc = 64;//0else if (j<lfw || (j>=lfw  && j<lfw*2 && i>lfh*2))*lpSrc = 128;}}InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);}void CImageProcessView::OnUpdateEdgeH(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)if(m_bDWT)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnEdgeV(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();unsigned char* lpSrc;int w=pDoc->EndPoint.x-pDoc->StartPoint.x+1;int h=pDoc->EndPoint.y-pDoc->StartPoint.y+1;int wp=int(log((double) w)/log(2.0));int hp=int(log((double) h)/log(2.0));const int LEVEL=2;int nDWTCurDepth=LEVEL;int lfw = 1<<(wp-nDWTCurDepth), lfh = 1<<(hp-nDWTCurDepth);for(int i = 0; i < h; i++){for(int j = 0; j < w; j++){lpSrc = (unsigned char*)pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - i-pDoc->StartPoint.y) + j+pDoc->StartPoint.x;if (i<lfh && j<lfw)*lpSrc = 64;//0else if (i<lfh || (i>=lfh  && i<lfh*2 && j>lfw*2))*lpSrc = 128;}}InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);}void CImageProcessView::OnUpdateEdgeV(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)if(m_bDWT)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnDwtSmooth(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();unsigned char* lpSrc;int w=pDoc->EndPoint.x-pDoc->StartPoint.x+1;int h=pDoc->EndPoint.y-pDoc->StartPoint.y+1;int wp=int(log((double) w)/log(2.0));int hp=int(log((double) h)/log(2.0));const int LEVEL=2;int nDWTCurDepth=LEVEL;int lfw = 1<<(wp-nDWTCurDepth), lfh = 1<<(hp-nDWTCurDepth);const int  Th=20;for(int i = 0; i < h; i++){for(int j = 0; j < w; j++){lpSrc = (unsigned char*)pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - i-pDoc->StartPoint.y) + j+pDoc->StartPoint.x;if (!(i<lfh && j<lfw))if(*lpSrc>128-Th && *lpSrc<128+Th) *lpSrc = 128;else if(*lpSrc>128)*lpSrc-=Th;else*lpSrc+=Th;}}InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);}void CImageProcessView::OnUpdateDwtSmooth(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)if(m_bDWT)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnMorphologicalDilation(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();int Obj=TWOVALUE_H;int Back=TWOVALUE_L;const int M=3;const int N=3;// 3×3的结构元素int **S;S =  new int * [M];for (int i = 0; i < M; i++) {S[i] = new int[N] ;}for (int i = 0; i < M; i++) for (int j = 0; j < N; j++)S[i][j]=1;Dilation(S,M,N,Obj,Back);CString str=pDoc->GetTitle();pDoc->SetTitle(str+"膨胀运算");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);for(int i=0;i<M;i++)delete []S[i];delete []S;}void CImageProcessView::Dilation(int** S, int M, int N, int Object, int Back){// TODO: 在此添加命令处理程序代码CImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;unsigned char*lpDst;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){// 分配内存失败return ;}lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpDst = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpSrc =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;if(*lpSrc==Back){//obj no need processfor (int m = 0; m < M; m++){for (int n = 0; n < N; n++){if (S[m][n] == 0)continue;if(i+m-M/2>=0 && i+m-M/2<lHeight && j+n -N/2>=0 && j+n-N/2<lWidth)if (*(lpSrc - lLineBytes*(m-M/2)  +(n-N/2) ) ==Object)//R and ~St != Null{  *lpDst=(BYTE)Object;break;}}}}}}// 释放内存delete []lpNewDIBBits;}void CImageProcessView::OnUpdateMorphologicalDilation(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code herepCmdUI->Enable(m_bTwoValue);}void CImageProcessView::OnMorphologicalErosion(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();//int Obj=TWOVALUE_H;int Back=TWOVALUE_L;const int M=3;const int N=3;// 3×3的结构元素int **S;S =  new int * [M];for (int i = 0; i < M; i++) {S[i] = new int[N] ;}for (int i = 0; i < M; i++) for (int j = 0; j < N; j++)S[i][j]=1;Erosion(S,M,N,Back);CString str=pDoc->GetTitle();pDoc->SetTitle(str+"腐蚀运算");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);for(int i=0;i<M;i++)delete []S[i];delete []S;}void CImageProcessView::Erosion(int** S,int M,int N,  int Back){// TODO: 在此添加命令处理程序代码CImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;unsigned char*lpDst;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){// 分配内存失败return ;}lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpDst = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpSrc =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;if (*lpSrc !=Back){for (int m = 0; m < M; m++){for (int n = 0; n < N; n++){if (S[m][n] == 0)continue;else if(i+m-M/2>=0 && i+m-M/2<lHeight && j+n -N/2>=0 && j+n-N/2<lWidth){if (*(lpSrc - lLineBytes*(m-M/2)  +(n-N/2) ) ==Back)//t St in R{ *(lpDst)=(BYTE) Back;break;}}}}}}}// 释放内存delete []lpNewDIBBits;}void CImageProcessView::OnUpdateMorphologicalErosion(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code herepCmdUI->Enable(m_bTwoValue);}void CImageProcessView::OnMorphologicalOpen(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();int Obj=TWOVALUE_H;int Back=TWOVALUE_L;const int M=3;const int N=3;// 3×3的结构元素int **S;S =  new int * [M];for (int i = 0; i < M; i++) {S[i] = new int[N] ;}for (int i = 0; i < M; i++) for (int j = 0; j < N; j++)S[i][j]=1;Erosion(S,M,N,Back);Dilation(S,M,N,Obj,Back);CString str=pDoc->GetTitle();pDoc->SetTitle(str+"开运算");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);for(int i=0;i<M;i++)delete []S[i];delete []S;}void CImageProcessView::OnUpdateMorphologicalOpen(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code herepCmdUI->Enable(m_bTwoValue);}void CImageProcessView::OnMorphologicalClose(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();int Obj=TWOVALUE_H;int Back=TWOVALUE_L;const int M=3;const int N=3;// 3×3的结构元素int **S;S =  new int * [M];for (int i = 0; i < M; i++) {S[i] = new int[N] ;}for (int i = 0; i < M; i++) for (int j = 0; j < N; j++)S[i][j]=1;Dilation(S,M,N,Obj,Back);Erosion(S,M,N,Back);CString str=pDoc->GetTitle();pDoc->SetTitle(str+"闭运算");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);for(int i=0;i<M;i++)delete []S[i];delete []S;}void CImageProcessView::OnUpdateMorphologicalClose(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code herepCmdUI->Enable(m_bTwoValue);}//显示直方图,选择阈值void CImageProcessView::OnSegmentationFixedthreshold(){// TODO: Add your command handler code here//CImageProcessDoc* pDoc = GetDocument();int Hist[256]={0};GetHistgram(Hist,false);DisplayDlg dlg;dlg.pData=&Hist[0];dlg.m_Sizex=256;dlg.m_LinePos=THRESHOLD;dlg.m_Title=_T("选择阈值");dlg.m_Level=1;if(dlg.DoModal()==IDOK)THRESHOLD=dlg.m_LinePos;Fixedthreshold();}void CImageProcessView::Fixedthreshold(){CImageProcessDoc* pDoc = GetDocument();unsigned char*lpDst;unsigned char* lpSrc;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){return ;}lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) +pDoc->StartPoint.x;lpDst = lpNewDIBBits +  lLineBytes* (lHeight-1-i) +pDoc->StartPoint.x;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){if(*lpSrc>THRESHOLD)*lpDst=TWOVALUE_H;else*lpDst=TWOVALUE_L;lpSrc++;lpDst++;}}CString str=pDoc->GetTitle();DisplayNewImg(lpNewDIBBits,lLineBytes,lHeight,str+"--+二值化");//display orignal imagedelete [] lpNewDIBBits;}void CImageProcessView::OnUpdateSegmentationFixedthreshold(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)if(!m_bTwoValue) bAvail=true;pCmdUI->Enable(bAvail);}//A Erosion B1 (原点为1)&&  A~ Erosion B2 (原点为X);(满足 1.不满足0)//同于结构中所有点相同,结构应该含有1和0(查询速度慢)void CImageProcessView::OnMorphologicalHitormiss(){CImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();unsigned char*lpSrc;unsigned char*lpDst;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){// 分配内存失败return ;}lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);//备份int Obj=TWOVALUE_H;int Back=TWOVALUE_L;const int M=m_ModelHeight;const int N=m_ModelWidth;int **S;S =  new int * [M];for (int i = 0; i < M; i++) {S[i] = new int[N] ;}for (int i = 0; i < M; i++) for (int j = 0; j < N; j++)if(m_pModelData[i*m_ModelWidth+j])S[i][j]=1;elseS[i][j]=0;//1 A Erosion B1Erosion(S,M,N,Back);unsigned char*lpNewDIBBits1;lpNewDIBBits1=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits1 == NULL){// 分配内存失败return ;}lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits1,lpSrc, lLineBytes * lHeight);///A Erosion B1memcpy( lpSrc,lpNewDIBBits, lLineBytes * lHeight);//备份还原//B2for (int i = 0; i < M; i++) for (int j = 0; j < N; j++)S[i][j]=1-S[i][j];//A~for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) +pDoc->StartPoint.x;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){*lpSrc=TWOVALUE_H-*lpSrc;lpSrc++;}}//if use lpNewDIBBits1==true,we can get fast!//2 A~ Erosion B2//Erosion(S,M,N,Obj,Back);//for fastfor (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpDst =lpNewDIBBits1 + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;if(*lpDst==Obj)//A Erosion B1==Obj{bool bBack=false;//for (int m = 0; m < M; m++){for (int n = 0; n < N; n++){if (S[m][n] == 0)continue;else if(i-m+M/2>=0 && i-m+M/2<lHeight && j+n -N/2>=0 && j+n -N/2<lWidth){if (*(lpSrc - lLineBytes*(m-M/2)  +(n-N/2) ) ==Back)//t St in R{   bBack=true;;m=M;n=N;//out}}}}if(bBack) *(lpDst)= (BYTE)Back;}}}//displayLPRGBQUAD pDibQuad = (LPRGBQUAD) pDoc->m_pDib->m_lpvColorTable+TWOVALUE_H+1;//pDibQuad->rgbRed = 255;pDibQuad->rgbGreen =0;pDibQuad->rgbBlue = 0;pDibQuad = (LPRGBQUAD) pDoc->m_pDib->m_lpvColorTable+TWOVALUE_L+1;//pDibQuad->rgbRed = 0;pDibQuad->rgbGreen =0;pDibQuad->rgbBlue = 255;for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc =lpNewDIBBits +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;//AlpDst =lpNewDIBBits1 + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;//击中或击不中for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpDst++;lpSrc++;if(*lpDst == Obj) {for (int m = 0; m < m_ModelHeight; m++){for (int n = 0; n <m_ModelWidth; n++){*(lpSrc+ lLineBytes*(m_ModelHeight/2 - m)  +(n - m_ModelWidth/2) )+=1; //=m_ModelData[m*m_ModelWidth+n];}}}}}memcpy( pDoc->m_pDib->m_lpImage,lpNewDIBBits, lLineBytes * lHeight);//显示结果CString str=pDoc->GetTitle();pDoc->SetTitle(str+"击中或击不中运算");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);// 恢复光标EndWaitCursor();for(int i=0;i<M;i++)delete []S[i];delete []S;delete [] lpNewDIBBits;delete [] lpNewDIBBits1;}void CImageProcessView::OnUpdateMorphologicalHitormiss(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereBOOL bAvail=false;if(m_bTwoValue)if(m_pModelData)bAvail=true;pCmdUI->Enable(bAvail);}//利用3x3结构B腐蚀//A-(A腐蚀B)//在原图上显示边缘void CImageProcessView::OnApplicationBoundaryextraction(){CImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;unsigned char*lpDst;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL)return ;//copy imglpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);//int Obj=TWOVALUE_H;int Back=TWOVALUE_L;const int M=3;const int N=3;// 3×3的结构元素int **S;S =  new int * [M];for (int i = 0; i < M; i++) {S[i] = new int[N] ;}for (int i = 0; i < M; i++) for (int j = 0; j < N; j++)S[i][j]=1;//S[0][0]=0;S[0][2]=0;S[2][0]=0;S[2][2]=0;Erosion(S,M,N,Back);for(int i=0;i<M;i++)delete []S[i];delete []S;//A-A Erosion Bfor (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){ lpSrc++;lpDst++;*lpSrc=(*lpDst-*lpSrc);if(*lpSrc) (*lpDst)+=1;//for display}}lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpSrc,lpNewDIBBits, lLineBytes * lHeight);LPRGBQUAD pDibQuad = (LPRGBQUAD) pDoc->m_pDib->m_lpvColorTable+TWOVALUE_H+1;//pDibQuad->rgbRed = 255;pDibQuad->rgbGreen =0;pDibQuad->rgbBlue = 0;CString str=pDoc->GetTitle();pDoc->SetTitle(str+"边缘提取");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);// 释放内存delete []lpNewDIBBits;}void CImageProcessView::OnUpdateApplicationBoundaryextraction(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code herepCmdUI->Enable(m_bTwoValue);}//将背景提取出来,则可以填充非背景区域,利用4个角点为可能背景点,利用十字结构膨胀,将背景填满void CImageProcessView::OnApplicationRegionfilling(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;unsigned char*lpDst;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){// 分配内存失败return ;}BeginWaitCursor();lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);//set init seed 背景(4 角点)lpSrc =pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 -pDoc->StartPoint.y-1)+pDoc->StartPoint.x+1;if(*lpSrc==TWOVALUE_L)*(lpNewDIBBits + lLineBytes * (lHeight - 1 -pDoc->StartPoint.y-1)+pDoc->StartPoint.x+1)=0x1;lpSrc =pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 -pDoc->StartPoint.y-1)+pDoc->EndPoint.x-1;if(*lpSrc==TWOVALUE_L)*(lpNewDIBBits + lLineBytes * (lHeight - 1 -pDoc->StartPoint.y-1)+pDoc->EndPoint.x-1)=0x1;lpSrc =pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 -pDoc->EndPoint.y+1)+pDoc->StartPoint.x+1;if(*lpSrc==TWOVALUE_L)*(lpNewDIBBits + lLineBytes * (lHeight - 1 -pDoc->EndPoint.y+1)+pDoc->StartPoint.x+1)=0x1;lpSrc =pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 -pDoc->EndPoint.y+1)+pDoc->EndPoint.x-1;if(*lpSrc==TWOVALUE_L)*(lpNewDIBBits + lLineBytes * (lHeight - 1 -pDoc->EndPoint.y+1)+pDoc->EndPoint.x-1)=0x1;bool bchg=true;//提取背景while(bchg){bchg=false;for (int i = pDoc->StartPoint.y+1; i <pDoc->EndPoint.y; i ++){lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x;lpSrc =pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x;for (int j =pDoc->StartPoint.x+1; j <pDoc->EndPoint.x; j ++){ lpDst++;lpSrc++;if(((*lpSrc)==TWOVALUE_L) && ((*lpDst)==0x1)){   bchg=true;*lpSrc|=0x1;//visited//若边缘为1个像数,可能出错//for(int m=-1;m<2;m++)//for(int n=-1;n<2;n++)//if((*(lpSrc+m*lLineBytes+n))==TWOVALUE_L) (*(lpDst+m*lLineBytes+n))=0x1;//十字结构if((*(lpSrc+lLineBytes))==TWOVALUE_L) *(lpDst+lLineBytes)=0x1;if((*(lpSrc-lLineBytes))==TWOVALUE_L) *(lpDst-lLineBytes)=0x1;if((*(lpSrc+1))==TWOVALUE_L) *(lpDst+1)=0x1;if((*(lpSrc-1))==TWOVALUE_L) *(lpDst-1)=0x1;}}}}//非背景0置128//change all black to whitefor (int i = pDoc->StartPoint.y+1; i <pDoc->EndPoint.y; i ++){for (int j =pDoc->StartPoint.x+1; j <pDoc->EndPoint.x; j ++){ lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ j;if(*lpDst==TWOVALUE_L){*lpDst=TWOVALUE_H;}}}//display for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){ lpSrc++;lpDst++;if(!*lpSrc && *lpDst>=TWOVALUE_H)(*lpDst)+=1;}}lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpSrc,lpNewDIBBits, lLineBytes * lHeight);LPRGBQUAD pDibQuad = (LPRGBQUAD) pDoc->m_pDib->m_lpvColorTable+TWOVALUE_H+1;//outpDibQuad->rgbRed = 255;pDibQuad->rgbGreen =0;pDibQuad->rgbBlue = 0;EndWaitCursor();// 释放内存delete []lpNewDIBBits;CString str=pDoc->GetTitle();pDoc->SetTitle(str+"区域填充");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);}void CImageProcessView::OnUpdateApplicationRegionfilling(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code herepCmdUI->Enable(m_bTwoValue);}//顺序扫描,找到一未访问的物体点,No++,利用膨胀获取相连部分,全设置为N,且设置为访问过;直到全部访问过//统计每个区域面积;可以求区域中心、周长、矩等void CImageProcessView::OnApplicationConnectedcomponents(){// TODO: Add your command handler code here//CImageProcessDoc* pDoc = GetDocument();int ObjNum=Connectedcomponents();DisplayObjLabel(ObjNum+1);}int CImageProcessView::Connectedcomponents(){CImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;unsigned char*lpDst;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL)return 0;memset( lpNewDIBBits,0, lLineBytes * lHeight);int No=0;bool bProcOver=false;while(!bProcOver){bProcOver=true;for (int i = pDoc->StartPoint.y+1; i <pDoc->EndPoint.y; i ++){lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x;lpSrc =pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x;for (int j =pDoc->StartPoint.x+1; j <pDoc->EndPoint.x; j ++){ lpDst++;lpSrc++;if(((*lpSrc)==TWOVALUE_H) && (!*lpDst)){   No++;*lpDst=(BYTE)No;//set first ptbProcOver=false;break;}}if(!bProcOver)break;}if(bProcOver) break;bool bchg=true;while(bchg){bchg=false;for (int i = pDoc->StartPoint.y+1; i <pDoc->EndPoint.y; i ++){lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x;lpSrc =pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x;for (int j =pDoc->StartPoint.x+1; j <pDoc->EndPoint.x; j ++){ lpDst++;lpSrc++;if(((*lpSrc)==TWOVALUE_H) && ((*lpDst)==No)){   bchg=true;*lpSrc|=0x1;//visited//must be 8 pointfor(int m=-1;m<2;m++)for(int n=-1;n<2;n++)if((*(lpSrc+m*lLineBytes+n))==TWOVALUE_H) (*(lpDst+m*lLineBytes+n))=(BYTE)No;}}}}}memcpy(pDoc->m_pDib->m_lpImage, lpNewDIBBits, lLineBytes * lHeight);// 释放内存delete []lpNewDIBBits;return No;//object number}void CImageProcessView::OnUpdateApplicationConnectedcomponents(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code herepCmdUI->Enable(m_bTwoValue);}//凸壳:区域内任意两点落在区域内//该方法不是最小区域//获取包含区域最小长方形区域,限制在该区域//4个结构,击中点包含,反复运算直到不改变//仅进行一个凸壳运算,故先选择区域,可以方便的求取多个凸壳void CImageProcessView::OnApplicationConvexhull(){CImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;unsigned char*lpDst;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){// 分配内存失败return ;}unsigned char*lpNewDIBBits1;lpNewDIBBits1=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits1 == NULL){// 分配内存失败return ;}BeginWaitCursor();lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);memcpy( lpNewDIBBits1,lpNewDIBBits, lLineBytes * lHeight);//Get max areaCRect rectArea(512,512,0,0);for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){ lpSrc++;if(*lpSrc & TWOVALUE_H) //{if(i<rectArea.top)rectArea.top=i;else if(i>rectArea.bottom)rectArea.bottom=i;if(j<rectArea.left)rectArea.left=j;else if(j>rectArea.right)rectArea.right=j;}}}pDoc->StartPoint.x=rectArea.left-1;pDoc->EndPoint.x=rectArea.right+1;pDoc->StartPoint.y=rectArea.top-1;pDoc->EndPoint.y=rectArea.bottom+1;// |// |o// | bool bOver=false;while(!bOver){bOver=true;for (int j =pDoc->StartPoint.x+1; j <pDoc->EndPoint.x; j ++){ for (int i = pDoc->StartPoint.y+1; i <pDoc->EndPoint.y; i ++){lpDst=lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ j;if(*lpDst == TWOVALUE_L)if (*(lpDst-1) ==TWOVALUE_H && *(lpDst-1+ lLineBytes) ==TWOVALUE_H && *(lpDst-1- lLineBytes) ==TWOVALUE_H){*lpDst = TWOVALUE_H;lpDst=lpNewDIBBits1 + lLineBytes * (lHeight - 1 - i)+ j;;*lpDst = TWOVALUE_H;bOver=false;}}}}lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);//---// obOver=false;while(!bOver){bOver=true;for (int i = pDoc->StartPoint.y+1; i <pDoc->EndPoint.y; i ++){for (int j =pDoc->StartPoint.x+1; j <pDoc->EndPoint.x; j ++){ lpDst=lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ j;;if(*lpDst == TWOVALUE_L)if (*(lpDst-1+lLineBytes) ==TWOVALUE_H && *(lpDst+ lLineBytes) ==TWOVALUE_H && *(lpDst+1+ lLineBytes) ==TWOVALUE_H){*lpDst = TWOVALUE_H;lpDst=lpNewDIBBits1 + lLineBytes * (lHeight - 1 - i)+ j;;*lpDst = TWOVALUE_H;bOver=false;}}}}lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);//  |// o|//  | bOver=false;while(!bOver){bOver=true;for (int i = pDoc->StartPoint.y+1; i <pDoc->EndPoint.y; i ++){for (int j =pDoc->EndPoint.x-1; j >pDoc->StartPoint.x; j --){ lpDst=lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ j;;if(*lpDst == TWOVALUE_L)if (*(lpDst+1) ==TWOVALUE_H && *(lpDst+1+ lLineBytes) ==TWOVALUE_H && *(lpDst+1- lLineBytes) ==TWOVALUE_H){*lpDst = TWOVALUE_H;lpDst=lpNewDIBBits1 + lLineBytes * (lHeight - 1 - i)+ j;;*lpDst = TWOVALUE_H;bOver=false;}}}}lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);// o//---bOver=false;while(!bOver){bOver=true;for (int j =pDoc->StartPoint.x+1; j <pDoc->EndPoint.x; j ++){ for (int i =pDoc->EndPoint.y-1 ; i >pDoc->StartPoint.y; i --){lpDst=lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ j;;if(*lpDst == TWOVALUE_L)if (*(lpDst-1-lLineBytes) ==TWOVALUE_H && *(lpDst-lLineBytes) ==TWOVALUE_H && *(lpDst+1- lLineBytes) ==TWOVALUE_H){*lpDst = TWOVALUE_H;lpDst=lpNewDIBBits1 + lLineBytes * (lHeight - 1 - i)+ j;;*lpDst = TWOVALUE_H;bOver=false;}}}}CString str=pDoc->GetTitle();DisplayNewImg(lpNewDIBBits1,lLineBytes,lHeight,str+"凸壳");//EndWaitCursor();// 释放内存delete []lpNewDIBBits;delete []lpNewDIBBits1;}void CImageProcessView::OnUpdateApplicationConvexhull(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code herepCmdUI->Enable(m_bTwoValue);}//利用8结构进行击中运算,重复直到没有改变//删除击中点//不是单像数,利用保持连通性的结构删除多余像数void CImageProcessView::OnApplicationThin(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;unsigned char*lpDst;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){// 分配内存失败return ;}// 更改光标形状BeginWaitCursor();lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);//击中 0--0   1---1  2--X(0\1)// 3×3的结构元素int B[8][9] = {{ 0, 0, 0,2, 1, 2,1, 1, 1},{ 2, 0, 0,1, 1, 0,1, 1, 2},{ 1, 2, 0,1, 1, 0,1, 2, 0},{ 1, 1, 2,1, 1, 0,2, 0, 0},{ 1, 1, 1,2, 1, 2,0, 0, 0},{ 2, 1, 1,0, 1, 1,0, 0, 2},{ 0, 2, 1,0, 1, 1,0, 2, 1},{ 0, 0, 2,0, 1, 1,2, 1, 1},};BOOL bOver=false;while(!bOver){bOver=true;for(int si=0;si<8;si++){for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpDst++;lpSrc++;if(i>0 && i<lHeight-1 && j>0 && j<lWidth-1){if(*lpSrc == TWOVALUE_H) //{   bool bchg=true;for (int m = 0; m < 3; m++){for (int n = 0; n < 3; n++){if (B[si][m *3+ n] == 2)continue;elseif (B[si][m *3+ n] == 0){if (*(lpSrc + lLineBytes*(1 - m) +(n - 1) ) ==TWOVALUE_H){bchg=false;m=3;n=3;//out}}elseif (B[si][m *3+ n] == 1)if (*(lpSrc + lLineBytes*(1 - m) +(n - 1) ) ==TWOVALUE_L){bchg=false;m=3;n=3;//out}}}if(bchg) {*lpDst = TWOVALUE_L;bOver=false;}}}}}//lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy(lpSrc, lpNewDIBBits, lLineBytes * lHeight);}}//不是单像数,删除多余像数//m-connectivityint B4[4][9] = {{ 0, 1, 2,1, 1, 0,2, 0, 0},{ 2, 1, 0,0, 1, 1,0, 0, 2},{ 0, 0, 2,0, 1, 1,2, 1, 0},{ 2, 0, 0,1, 1, 0,0, 1, 2}};for(int si=0;si<4;si++){for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpDst =pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpDst++;if(i>0 && i<lHeight-1 && j>0 && j<lWidth-1){if(*lpDst == TWOVALUE_H) //{   bool bchg=true;for (int m = 0; m < 3; m++){for (int n = 0; n < 3; n++){if (B4[si][m *3+ n] == 2)continue;elseif (B4[si][m *3+ n] == 0){if (*(lpDst + lLineBytes*(1 - m) +(n - 1) ) ==TWOVALUE_H){bchg=false;m=3;n=3;//out}}elseif (B4[si][m *3+ n] == 1)if (*(lpDst + lLineBytes*(1 - m) +(n - 1) ) ==TWOVALUE_L){bchg=false;m=3;n=3;//out}}}if(bchg) *lpDst = TWOVALUE_L;}}}}}CString str=pDoc->GetTitle();pDoc->SetTitle(str+"击中击不中-细化");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);EndWaitCursor();// 释放内存delete []lpNewDIBBits;}void CImageProcessView::OnUpdateApplicationThin(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code herepCmdUI->Enable(m_bTwoValue);}//细化后图像有毛刺,利用选择的模板进行3次细化,去除小毛刺,同时对端点处影响//获取端点,在此处进行膨胀,与原图取交集恢复端点处,如毛刺距端点处大于3则消除void CImageProcessView::OnApplicationPruned(){CImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;unsigned char*lpDst;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){// 分配内存失败return ;}unsigned char*lpNewDIBBits1;lpNewDIBBits1=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits1 == NULL){// 分配内存失败return ;}// 更改光标形状BeginWaitCursor();lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);memcpy( lpNewDIBBits1,lpSrc, lLineBytes * lHeight);//细化//击中 0--0   1---1  2--X(0\1)// 3×3的结构元素int B[8][9] = {{ 2, 0, 0,1, 1, 0,2, 0, 0},{ 2, 1, 2,0, 1, 0,0, 0, 0},{ 0, 0, 2,0, 1, 1,0, 0, 2},{ 0, 0, 0,0, 1, 0,2, 1, 2},{ 1, 0, 0,0, 1, 0,0, 0, 0},{ 0, 0, 1,0, 1, 0,0, 0, 0},{ 0, 0, 0,0, 1, 0,0, 0, 1},{ 0, 0, 0,0, 1, 0,1, 0, 0},};//去除3点毛刺int  Num=3;while(Num){Num--;for(int si=0;si<8;si++){for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpDst++;lpSrc++;if(i>0 && i<lHeight-1 && j>0 && j<lWidth-1){if(*lpSrc == TWOVALUE_H) //{   bool bchg=true;for (int m = 0; m < 3; m++){for (int n = 0; n < 3; n++){if (B[si][m *3+ n] == 2)continue;elseif (B[si][m *3+ n] == 0){if (*(lpSrc + lLineBytes*(1 - m) +(n - 1) ) ==TWOVALUE_H){bchg=false;m=3;n=3;//out}}elseif (B[si][m *3+ n] == 1)if (*(lpSrc + lLineBytes*(1 - m) +(n - 1) ) ==TWOVALUE_L){bchg=false;m=3;n=3;//out}}}if(bchg) *lpDst = TWOVALUE_L;}}}}//lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy(lpSrc, lpNewDIBBits, lLineBytes * lHeight);}}//set 0memset(pDoc->m_pDib->m_lpImage,0, lLineBytes * lHeight);//获取端点 //lpNewDIBBits---X1=A细化{B}//pDoc->m_pDib->m_lpImage--端点X2=X1击中{B}for(int si=0;si<8;si++){for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = lpNewDIBBits +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpDst = pDoc->m_pDib->m_lpImage+ lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpDst++;lpSrc++;if(i>0 && i<lHeight-1 && j>0 && j<lWidth-1){if(*lpSrc == TWOVALUE_H) //{   bool bchg=true;for (int m = 0; m < 3; m++){for (int n = 0; n < 3; n++){if (B[si][m *3+ n] == 2)continue;elseif (B[si][m *3+ n] == 0){if (*(lpSrc + lLineBytes*(1 - m) +(n - 1) ) ==TWOVALUE_H){bchg=false;m=3;n=3;//out}}elseif (B[si][m *3+ n] == 1)if (*(lpSrc + lLineBytes*(1 - m) +(n - 1) ) ==TWOVALUE_L){bchg=false;m=3;n=3;//out}}}if(bchg) *lpDst = TWOVALUE_H;}}}}}//膨胀3次// 3×3的结构元素int **S;int M=3;int N=3;S =  new int * [M];for (int i = 0; i < M; i++) {S[i] = new int[N] ;}for (int i = 0; i < M; i++) for (int j = 0; j < N; j++)S[i][j]=1;Dilation(S,M,N,TWOVALUE_H,TWOVALUE_L);Dilation(S,M,N,TWOVALUE_H,TWOVALUE_L);Dilation(S,M,N,TWOVALUE_H,TWOVALUE_L);for(int i=0;i<M;i++)delete []S[i];delete []S;//端点延伸3次U X1unsigned char * lpSrc1;for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = lpNewDIBBits1 +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpSrc1 = lpNewDIBBits +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpDst = pDoc->m_pDib->m_lpImage+ lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpDst++;lpSrc++;if(*lpDst){if(!(*lpSrc)) *lpDst=TWOVALUE_L;}(*lpSrc1)|=(*lpDst);}}lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy(lpSrc, lpNewDIBBits1, lLineBytes * lHeight);CString str=pDoc->GetTitle();DisplayNewImg(lpNewDIBBits,lLineBytes,lHeight,str+"裁剪");//EndWaitCursor();// 释放内存delete []lpNewDIBBits;delete []lpNewDIBBits1;}void CImageProcessView::OnUpdateApplicationPruned(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code herepCmdUI->Enable(m_bTwoValue);}void CImageProcessView::OnGrayDilation(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();const int M=3;const int N=3;// 3×3的结构元素int **S;S =  new int * [M];for (int i = 0; i < M; i++) {S[i] = new int[N] ;}for (int i = 0; i < M; i++) for (int j = 0; j < N; j++)S[i][j]=0;GrayDilation(S,M,N);CString str=pDoc->GetTitle();pDoc->SetTitle(str+"膨胀运算");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);for(int i=0;i<M;i++)delete []S[i];delete []S;}void CImageProcessView::OnUpdateGrayDilation(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnGrayErosion(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();const int M=3;const int N=3;// 3×3的结构元素int **S;S =  new int * [M];for (int i = 0; i < M; i++) {S[i] = new int[N] ;}for (int i = 0; i < M; i++) for (int j = 0; j < N; j++)S[i][j]=0;GrayErosion(S,M,N);CString str=pDoc->GetTitle();pDoc->SetTitle(str+"腐蚀运算");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);for(int i=0;i<M;i++)delete []S[i];delete []S;}void CImageProcessView::GrayDilation(int** S, int M, int N){CImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;unsigned char*lpDst;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){return ;}lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);////膨胀运算for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpDst = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpSrc =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;int gray=*lpSrc;for (int m = 0; m < M; m++){for (int n = 0; n < N; n++){   if(S[m][n]<0) continue;if(i-M/2 + m>=0 && i-M/2 +m<lHeight && j+n - N/2>=0 && j+n - N/2<lWidth){int tmp=*(lpSrc + lLineBytes*(M/2 - m)  +(n - N/2))+S[m][n];if(tmp>gray) gray=tmp;//max}}}if(gray>255) gray=255;*lpDst=(BYTE)gray;}}// 释放内存delete []lpNewDIBBits;}void CImageProcessView::GrayErosion(int** S, int M, int N){CImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;unsigned char*lpDst;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){return ;}lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);//腐蚀运算,定义域内输入数据减对应模板数据,并求最小值,该最小值便是该点输出for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpDst = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpSrc =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;int gray=*lpSrc;for (int m = 0; m < M; m++){for (int n = 0; n < N; n++){   if(S[m][n]<0) continue;if(i-M/2 + m>=0 && i-M/2 +m<lHeight && j+n - N/2>=0 && j+n - N/2<lWidth){int tmp=*(lpSrc + lLineBytes*(M/2 - m)  +(n - N/2))-S[m][n];if(tmp<gray) gray=tmp;//min}}}*lpDst=(BYTE)gray;}}// 释放内存delete []lpNewDIBBits;}void CImageProcessView::OnUpdateGrayErosion(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnGrayOpen(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();const int M=3;const int N=3;// 3×3的结构元素int **S;S =  new int * [M];for (int i = 0; i < M; i++) {S[i] = new int[N] ;}for (int i = 0; i < M; i++) for (int j = 0; j < N; j++)S[i][j]=0;GrayErosion(S,M,N);GrayDilation(S,M,N);CString str=pDoc->GetTitle();pDoc->SetTitle(str+"开运算");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);for(int i=0;i<M;i++)delete []S[i];delete []S;}void CImageProcessView::OnUpdateGrayOpen(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnGrayClose(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();const int M=3;const int N=3;// 3×3的结构元素int **S;S =  new int * [M];for (int i = 0; i < M; i++) {S[i] = new int[N] ;}for (int i = 0; i < M; i++) for (int j = 0; j < N; j++)S[i][j]=0;GrayDilation(S,M,N);GrayErosion(S,M,N);CString str=pDoc->GetTitle();pDoc->SetTitle(str+"闭运算");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);for(int i=0;i<M;i++)delete []S[i];delete []S;}void CImageProcessView::OnUpdateGrayClose(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnGrayGradient(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;unsigned char*lpDst;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){return ;}unsigned char*lpNewDIBBits1;lpNewDIBBits1=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits1 == NULL){return ;}const int M=3;const int N=3;// 3×3的结构元素int **S;S =  new int * [M];for (int i = 0; i < M; i++) {S[i] = new int[N] ;}for (int i = 0; i < M; i++) for (int j = 0; j < N; j++)S[i][j]=0;lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits1,lpSrc, lLineBytes * lHeight);GrayDilation(S,M,N);lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);//loadlpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy(lpSrc, lpNewDIBBits1, lLineBytes * lHeight);GrayErosion(S,M,N);//形态学梯度为膨胀的结果减腐蚀的结果for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;*lpDst=max(*lpDst-*lpSrc,0);}}CString str=pDoc->GetTitle();DisplayNewImg(lpNewDIBBits, lLineBytes ,lHeight,str+"形态学梯度");lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy(lpSrc, lpNewDIBBits1, lLineBytes * lHeight);// 释放内存delete []lpNewDIBBits;delete []lpNewDIBBits1;for(int i=0;i<M;i++)delete []S[i];delete []S;}void CImageProcessView::OnUpdateGrayGradient(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnGrayTophat(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;unsigned char*lpDst;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){return ;}const int M=3;const int N=3;// 3×3的结构元素int **S;S =  new int * [M];for (int i = 0; i < M; i++) {S[i] = new int[N] ;}for (int i = 0; i < M; i++) for (int j = 0; j < N; j++)S[i][j]=0;lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);GrayErosion(S,M,N);GrayDilation(S,M,N);//原图减开运算的结果for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;*lpSrc=max(*lpDst-*lpSrc,0);}}CString str=pDoc->GetTitle();DisplayNewImg(pDoc->m_pDib->m_lpImage, lLineBytes ,lHeight,str+"Top-hat变换");lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy(lpSrc, lpNewDIBBits, lLineBytes * lHeight);// 释放内存delete []lpNewDIBBits;for(int i=0;i<M;i++)delete []S[i];delete []S;}void CImageProcessView::OnUpdateGrayTophat(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}//获取梯度大小,低2位包含方向信息 0| 、1\、 2--、 3///存放于原图,可以调用void CImageProcessView::OnEdgeSobel(){CImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;unsigned char*lpDst;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){// 分配内存失败return ;}BeginWaitCursor();lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);int pixel[8];for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpDst  = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpSrc  =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;if(i>0 && i<lHeight-1 && j>0 && j<lWidth-1){pixel[0] = (int)*(lpSrc+lLineBytes-1);pixel[1] = (int)*(lpSrc+lLineBytes);pixel[2] = (int)*(lpSrc+lLineBytes+1);pixel[3] = (int)*(lpSrc-1);pixel[4] = (int)*(lpSrc+1);pixel[5] = (int)*(lpSrc - lLineBytes-1);pixel[6] = (int)*(lpSrc - lLineBytes);pixel[7] = (int)*(lpSrc - lLineBytes+1);//  1   2   1//  0   0   0// -1  -2  -1int tmp1=pixel[0]+2*pixel[1]+pixel[2]-pixel[5]-2*pixel[6]-pixel[7];//  -1   0   1//  -2   0   2//  -1   0   1int tmp2=pixel[2]+2*pixel[4]+pixel[7]-pixel[0]-2*pixel[3]-pixel[5];int result =(int)(sqrt(double(tmp1*tmp1+tmp2*tmp2))+0.5);//>>255 if(result>255) result=255;*lpDst = (unsigned char)result;//add edge infomation*lpDst&=0xfc;if(tmp2==0) tmp2=1;double tha=atan((double(tmp1))/tmp2);//if(result>10)//TRACE("\n %3.2f",tha);if(abs(tha)<Pi/8)//   |  0*lpDst=*lpDst;elseif(tha>Pi/8 && tha<Pi*3/8)//  \   1*lpDst=*lpDst+1;elseif(tha<-Pi/8 && tha>-Pi*3/8)//  /  3*lpDst=*lpDst+3;else                   //  -    2*lpDst=*lpDst+2;}else *lpDst=0;}}CString str=pDoc->GetTitle();pDoc->SetTitle(str+"--Sobe");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);// 恢复光标EndWaitCursor();// 释放内存delete []lpNewDIBBits;}void CImageProcessView::OnUpdateEdgeSobel(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}//显示-127---127(0--128)//高值反映边缘偏亮处、低值为边缘偏暗处,不显示边缘处(过零点)//跳跃变换如二值图像无过零点void CImageProcessView::OnEdgeLaplace(){CImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;unsigned char*lpDst;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){// 分配内存失败return ;}BeginWaitCursor();lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);int pixel[8];for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;if(i>0 && i<lHeight-1 && j>0 && j<lWidth-1){pixel[0] = (int)*(lpSrc+lLineBytes-1);pixel[1] = (int)*(lpSrc+lLineBytes);pixel[2] = (int)*(lpSrc+lLineBytes+1);pixel[3] = (int)*(lpSrc-1);pixel[4] = (int)*(lpSrc+1);pixel[5] = (int)*(lpSrc - lLineBytes-1);pixel[6] = (int)*(lpSrc - lLineBytes);pixel[7] = (int)*(lpSrc - lLineBytes+1);//   -1   -1  -1//   -1   8   -1 //   -1   -1  -1int Tmp=0;for(int k=0;k<8;k++)Tmp+=pixel[k];Tmp=8*((int)*lpSrc)-Tmp;Tmp+=128;//Tmp=abs(Tmp);if(Tmp>255) Tmp=255;if(Tmp<0) Tmp=0;*lpDst=(BYTE)Tmp;}else *lpDst=128;}}CString str=pDoc->GetTitle();DisplayNewImg(lpNewDIBBits, lLineBytes ,lHeight,"--Laplace");// 恢复光标EndWaitCursor();// 释放内存delete []lpNewDIBBits;}void CImageProcessView::OnUpdateEdgeLaplace(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}// LOGvoid CImageProcessView::OnEdgeLog(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;unsigned char*lpDst;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){// 分配内存失败return ;}BeginWaitCursor();lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);const int M=11;const int N=11;float **H;H =  new float * [M];for (int i = 0; i < M; i++) {H[i] = new float[N] ;}/*H[2][2]=16;H[2][1]=H[1][2]=H[2][3]=H[3][2]=-2;H[0][2]=H[2][0]=H[4][2]=H[2][4]=-1;H[1][1]=H[3][1]=H[1][3]=H[3][3]=-1;*/float sigma=.8f;float fsum=0.0f;for (int i = 0; i < M; i++) for (int j = 0; j < N; j++){float ftmp=((i-M/2)*(i-M/2)+(j-N/2)*(j-N/2))/(sigma*sigma);H[i][j]=(ftmp-2)/(sigma*sigma)*exp(-ftmp/2);fsum+=H[i][j];}for (int i = 0; i < M; i++) {  // TRACE("\n");for (int j = 0; j < N; j++){H[i][j]/=fsum;//TRACE("%3.2f\t",H[i][j]);}}MaskCount(H,M,N,true);CString str=pDoc->GetTitle();DisplayNewImg(pDoc->m_pDib->m_lpImage, lLineBytes ,lHeight,str+"--LOG");lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpSrc,lpNewDIBBits, lLineBytes * lHeight);DisplayNewImg(pDoc->m_pDib->m_lpImage, lLineBytes ,lHeight,str);//判断过零点for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;if(i>0 && i<lHeight-1 && j>0 && j<lWidth-1){int v=*lpDst+*(lpDst-1)+*(lpDst+lLineBytes)+*(lpDst-1+lLineBytes)-4*128;int min=v;int max=v;v=*lpDst+*(lpDst+1)+*(lpDst+lLineBytes)+*(lpDst+1+lLineBytes)-4*128;if(v>max)max=v;else if(v<min) min=v;v=*lpDst+*(lpDst-1)+*(lpDst-lLineBytes)+*(lpDst-1-lLineBytes)-4*128;if(v>max)max=v;else if(v<min) min=v;v=*lpDst+*(lpDst+1)+*(lpDst-lLineBytes)+*(lpDst+1-lLineBytes)-4*128;if(v>max)max=v;else if(v<min) min=v;if(max>=0 && min<=0)*lpSrc=0x80;else*lpSrc=0;}else *lpSrc=0;}}pDoc->SetTitle(str+"--LOG过零点");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);// 恢复光标EndWaitCursor();// 释放内存delete []lpNewDIBBits;for(int i=0;i<M;i++)delete []H[i];delete []H;}void CImageProcessView::OnUpdateEdgeLog(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::MaskCount(float** H,int M,int N,bool bEdge){CImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;unsigned char*lpDst;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){// 分配内存失败return ;}lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = lpNewDIBBits +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpDst =pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;if(i>=N/2 && i<lHeight-N/2 && j>=M/2 && j<lWidth-M/2){float Tmp=0.0f;for(int m=0;m<M;m++)for(int n=0;n<N;n++)Tmp+=*(lpSrc+lLineBytes*(N/2-n)+m-M/2)*H[m][n] ; if(bEdge) Tmp+=128;if(Tmp>255) Tmp=255;if(Tmp<0) Tmp=0;*lpDst=(unsigned char)Tmp;}else *lpDst=0;}}// 释放内存delete []lpNewDIBBits;}//获取直线参数(最大值),删除该值附近值,再取最大值为下一条直线//显示直线为图像点为边缘且满足方向的约束,若无满足点查看邻域(1,-1)是否满足,可去掉一些断点,//对于角度变化求可能的距离,故速度较快,不考虑方向对角度的限制,提高速度有限//针对一般图像OnEdgeLog();//二值Sobel边缘-细化后运行//图像较大时,由于原点(0,0) 误差较大,改为(cx/2,cy/2)void CImageProcessView::OnHoughLines(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();//1 save imageunsigned char*lpSrc;unsigned char*lpDst;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){// 分配内存失败return ;}for (int i =0; i <lHeight; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) -1;lpDst = lpNewDIBBits +  lLineBytes* (lHeight-1-i) -1;for (int j =0; j <lWidth; j ++){lpSrc++;lpDst++;*lpDst=*lpSrc;if(*lpDst>=220) *lpDst=220;//  for display line}}//2 Get edgeif(!m_bTwoValue)OnEdgeLog();elseOnEdgeSobel();//3 Hough transform//极半径检测分辨率和角度检测分辨率int radiusResolution=2;int angleResolution=1;//线与原点的距离最大int houghWidth=(int)(sqrt((double)(lWidth*lWidth+lHeight*lHeight)));//+/-houghWidth /= radiusResolution;//线的角度在[-90,90]之间,所以申请的累加数组高度为181/angleResolutionint houghHeight=181/angleResolution;//申请累加数组缓冲区int *houghBuf=new int[houghWidth*houghHeight];//init  //清理变换空间累加数组for(int i=0;i<houghHeight;i++){for(int j=0;j<houghWidth;j++){*(houghBuf+i*houghWidth+j)=0;}}const double Deg_Rad=3.1415926/180;//遍历图像数据for (int i =max(pDoc->StartPoint.y,1); i <=pDoc->EndPoint.y; i ++){//start: 1// 指向源图像倒数第j行,第i个象素的指针lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + max(pDoc->StartPoint.x,1)-1;// 针对每行图像每列进行操作for (int j =max(pDoc->StartPoint.x,1); j <=pDoc->EndPoint.x; j ++){// 指向源DIB第i行,第j个象素的指针lpSrc++;//如果是edge,则在变换域的对应各点上加1if(*lpSrc>=TWOVALUE_H)//if(i+j==500 && j>=200 && j<=300 ){//出现一个目标点//a代表角度的循环变量,在变换空间累加数组的垂直方向上for(int a=0;a<houghHeight;a++){//按照给定变换角度的分辨率,求取角度double tempA=Deg_Rad*(a-houghHeight/2)*angleResolution;//double tempA=Deg_Rad*(a)*angleResolution;//可以建立表,查表;提高速度//根据当前遍历的角度及x,y值求取对应极半径double tempR=(i*cos(tempA)+j*sin(tempA))/radiusResolution;//r=xcosa+ysina//double tempR=((i-houghHeight/2)*cos(tempA)+(houghWidth/2-j)*sin(tempA))/radiusResolution;//r=xcosa+ysina//与冈萨雷斯书一致,与习惯不同int r;if(tempR>0)r=(int)(tempR+0.5);elser=(int)(tempR-0.5);if(r>=-houghWidth/2 && r<houghWidth/2)//累加数组累加*(houghBuf+a*houghWidth+r+houghWidth/2)+=1;//[r][a]}}}}//4.save for display Hough Resultint line=houghWidth/4*4;unsigned char  *pHoughImg=new unsigned char[line*houghHeight];memset(pHoughImg,0,line*houghHeight);for(int r=0;r<line;r++){for(int a=0;a<houghHeight;a++){if(*(houghBuf+a*houghWidth+r)>255)*(pHoughImg+(houghHeight-a-1)*line+r)=255;else*(pHoughImg+(houghHeight-a-1)*line+r)=(BYTE)(*(houghBuf+a*houghWidth+r));}}//display centerfor(int i=-5;i<=5;i++)*(pHoughImg+(houghHeight/2)*line+houghWidth/2+i)=255;for(int i=-5;i<=5;i++)*(pHoughImg+(houghHeight/2+i)*line+houghWidth/2)=255;DisplayNewImg(pHoughImg, line ,houghHeight,"HoughImg:a:(-90,90) r:(-rMax/2,rMax/2)");//5 累加数组的极大值const int N_MaxVal=60;vector< LineInfo> L_Info;for(int a=5;a<houghHeight;a++){//-90 r == 90 -r for(int r=0;r<houghWidth;r++){if(*(houghBuf+a*houghWidth+r)>N_MaxVal){bool btrue=true;//判断极值for(int m=-2;m<=2;m++){  for(int n=-2;n<=2;n++)//{if(m==0 && n==0)continue;if(a+n>=0 && a+n<houghHeight && r+m>=0 && r+m<houghWidth) {if(*(houghBuf+(a+n)*houghWidth+r+m)>*(houghBuf+a*houghWidth+r)){btrue=false;break;}elseif(*(houghBuf+(a+n)*houghWidth+r+m)==*(houghBuf+a*houghWidth+r))*(houghBuf+(a+n)*houghWidth+r+m)=*(houghBuf+(a+n)*houghWidth+r+m)-1;}}if(!btrue)break;}if(btrue){LineInfo line;line.pt=CPoint((a-houghHeight/2)*angleResolution,(r-houghWidth/2)*radiusResolution);//line.pt=CPoint((a)*angleResolution,(r-houghWidth/2)*radiusResolution);line.num=*(houghBuf+a*houghWidth+r);L_Info.push_back(line);}}}}//sortTRACE("\n Edge Infomation:\n");if(L_Info.size()){for(int i=0;i<(int)L_Info.size()-1;i++){   for(int j=i+1;j<(int)L_Info.size();j++)if(L_Info[i].num<L_Info[j].num){LineInfo line;line=L_Info[i];L_Info[i]=L_Info[j];L_Info[j]=line;}}for(int i=0;i<(int)L_Info.size() && i<100;i++){CString str;str.Format("%d: (R: %d  theta: %d  MaxNum: %d)\n",i+1,L_Info[i].pt.y,L_Info[i].pt.x,L_Info[i].num);TRACE("%s\n",str);}const int displayN=20;int no=0;for(int i=0;i<(int)L_Info.size() && no<displayN;i++){no++;double angle=L_Info[i].pt.x;double radius=L_Info[i].pt.y;//angle的单位是度,此处转换为弧度进行计算double alfa=angle*Deg_Rad;if(angle<-45 || angle>45){for(int x= pDoc->StartPoint.y+1;x<pDoc->EndPoint.y-2;x++){//|int y=(int)(radius/sin(alfa)-x/tan(alfa)+0.5);if(y>pDoc->StartPoint.x && y<pDoc->EndPoint.x){lpSrc=pDoc->m_pDib->m_lpImage+lLineBytes* (lHeight-1-x) +y; if(*lpSrc>=TWOVALUE_H || *(lpSrc+1)>=TWOVALUE_H || *(lpSrc-1)>=TWOVALUE_H)*(lpNewDIBBits+lLineBytes* (lHeight-1-x) +y)=220+(BYTE)no;//} }}else{for( int y= pDoc->StartPoint.x+1;y<pDoc->EndPoint.x-2;y++){int x=(int)(radius/cos(alfa)-y*tan(alfa)+0.5);if(x>pDoc->StartPoint.y && x<pDoc->EndPoint.y){lpSrc=pDoc->m_pDib->m_lpImage+lLineBytes* (lHeight-1-x) +y; if(*lpSrc>=TWOVALUE_H || *(lpSrc+lLineBytes)>=TWOVALUE_H || *(lpSrc-lLineBytes)>=TWOVALUE_H)*(lpNewDIBBits+lLineBytes* (lHeight-1-x) +y)=220+(BYTE)no;}}}}}lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpSrc,lpNewDIBBits, lLineBytes * lHeight);lpSrc=(unsigned char*)pDoc->m_pDib->m_lpvColorTable;for (int i=221;i<=255;i++)//{*(lpSrc+i*4+1)=((i-220)*20)%256;*(lpSrc+i*4)=(BYTE)max(255-(i-220)*20,0);*(lpSrc+i*4+2)=255;//(i-220)*20%255;}CString str=pDoc->GetTitle();pDoc->SetTitle(str+"--Hough Lines");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);// 释放内存delete []lpNewDIBBits;delete []houghBuf;delete []pHoughImg;// 恢复光标EndWaitCursor();}void CImageProcessView::OnUpdateHoughLines(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}//适应于多峰图像void CImageProcessView::OnSegmentationRegiongrowing(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();//copy imgunsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL)return ;memcpy( lpNewDIBBits,pDoc->m_pDib->m_lpImage, lLineBytes * lHeight);unsigned char* lpSrc;stack <CPoint> ptStack;//1.获取种子点图像,取亮点(255)//set 0for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = lpNewDIBBits  +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;if(*lpSrc>254) {ptStack.push(CPoint(j,i)); //255 种子*lpSrc=TWOVALUE_H;     }else*lpSrc=0;}}//2.显示种子图像DisplayNewImg(lpNewDIBBits,lLineBytes,lHeight,"种子");//display orignal imageunsigned char* lpDst;const int DIFF=65;//3.邻域生长//栈出列,3x3邻域点未处理(0),若与种子点灰度差小则标记(TWOVALUE_H)、进栈;否则设访问过(0x1)while(!ptStack.empty()){CPoint Point;Point=ptStack.top();ptStack.pop();//set areafor(int m=1;m>-2;m--)for(int n=1;n>-2;n--) {if(m!=0 || n!=0){int x=Point.x+m;int y=Point.y+n;if(y>=pDoc->StartPoint.y && y<=pDoc->EndPoint.y && x>=pDoc->StartPoint.x && x<=pDoc->EndPoint.x){lpDst =lpNewDIBBits  +  lLineBytes*(lHeight-1-y) + x;if(!(*lpDst)){//no visitlpSrc = pDoc->m_pDib->m_lpImage+  lLineBytes*(lHeight-1-y) + x;if(*lpSrc>255-DIFF){////limit in  ptStack.push(CPoint(x,y));*lpDst=TWOVALUE_H;   }}(*lpDst)|= 0x1;//visted}}}}//4.显示结果CString str=pDoc->GetTitle();DisplayNewImg(lpNewDIBBits,lLineBytes,lHeight,str+"区域生长");//display orignal imagedelete [] lpNewDIBBits;// 恢复光标EndWaitCursor();}void CImageProcessView::OnUpdateSegmentationRegiongrowing(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnSegmentationWatershed(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();unsigned char*pMarker;pMarker=new unsigned char [lLineBytes*lHeight];if (pMarker == NULL){return ;}unsigned char* pOrgIMg;pOrgIMg=new unsigned char [lLineBytes*lHeight];if (pOrgIMg == NULL){return ;}//save memcpy( pOrgIMg,pDoc->m_pDib->m_lpImage, lLineBytes * lHeight);//获取目标亮度阈值(取大一些,保证每个目标都有值即可,无需一个目标一值)int Hist[256]={0};GetHistgram(Hist,false);int GrayTh=0;int tol=0;int size=(pDoc->EndPoint.y-pDoc->StartPoint.y+1)*(pDoc->EndPoint.x-pDoc->StartPoint.x+1);for(GrayTh=0;GrayTh<256;GrayTh++){tol+=Hist[GrayTh];if(tol>size*8/10) break;}//1)get edgeOnEdgeSobel();//FilterGaussFilter(5,5,1.414);unsigned char* lpSrc;unsigned char* lpDst;//设置边界梯度为最大,防止物体在边界上(梯度=0)与背景混合for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){if(i==pDoc->StartPoint.y || i==pDoc->EndPoint.y || j==pDoc->StartPoint.x || j==pDoc->EndPoint.x){lpDst  = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + j;*lpDst=255;//edge}}}DisplayNewImg(pDoc->m_pDib->m_lpImage, lLineBytes ,lHeight,"梯度Image");//初始化标记图置0,0代表未作标记的点(等待生长的点)memset(pMarker, 0, lLineBytes*lHeight);//2) set all lable is 0xff //目标为亮,背景为暗,取目标内部区域为Marker(0xff),保证每个目标都有Marker点//目标的Marker点:梯度小且亮度大int GradientTh=40;TRACE("\nGradientTh=%d,GrayTh=%d\n",GradientTh,GrayTh);const int initLabel=0xff;for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + j;lpDst = pOrgIMg +  lLineBytes* (lHeight-1-i) + j;if((*lpSrc<GradientTh) && (*lpDst >GrayTh))//目标内部{int min=*lpSrc; for(int m=-1;m<2;m++)for(int n=-1;n<2;n++)if((*(lpSrc+m*lLineBytes+n))<min)min=*(lpSrc+m*lLineBytes+n);if(min<(*lpSrc-2) || min<5)*(pMarker+  lLineBytes*(lHeight-1-i) + j)=initLabel;}}}//设置边缘处判断为背景的点为:1for (int i = pDoc->StartPoint.y+1; i <pDoc->EndPoint.y; i ++){for (int j =pDoc->StartPoint.x+1; j <pDoc->EndPoint.x; j ++){if(i==pDoc->StartPoint.y+1 || i==pDoc->EndPoint.y-1 || j==pDoc->StartPoint.x+1 || j==pDoc->EndPoint.x-1){lpDst  = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + j;lpSrc  =pOrgIMg + lLineBytes * (lHeight - 1 - i)+ j;if(*lpDst<GradientTh/2 && *lpSrc<GrayTh)*(pMarker+  lLineBytes*(lHeight-1-i) + j)=1;//back}}}//3 利用连通性标定//2、3...objectCount物体,消除了过小的目标(可能的噪声点) int objectCount=1;bool bProcOver=false;while(!bProcOver){bProcOver=true;int No=0;for (int i = pDoc->StartPoint.y+1; i <pDoc->EndPoint.y; i ++){for (int j =pDoc->StartPoint.x+1; j <pDoc->EndPoint.x; j ++){ lpSrc =pMarker + lLineBytes *(lHeight-1-i)+ j;if(*lpSrc==initLabel){   objectCount++;*lpSrc=(BYTE)objectCount;//set first ptNo++;bProcOver=false;break;}}if(!bProcOver)break;}if(bProcOver) break;bool bchg=true;while(bchg){bchg=false;for (int i = pDoc->StartPoint.y+1; i <pDoc->EndPoint.y; i ++){for (int j =pDoc->StartPoint.x+1; j <pDoc->EndPoint.x; j ++){ lpSrc =pMarker + lLineBytes * (lHeight-1-i)+ j;if(*lpSrc==objectCount){for(int m=-1;m<2;m++)for(int n=-1;n<2;n++){if((*(lpSrc+m*lLineBytes+n))==initLabel){*(lpSrc+m*lLineBytes+n)=(BYTE)objectCount;No++;bchg=true;}}}}}}if(No<10){//面积过小,标注取消//delete all seedfor (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){ lpSrc =pMarker + lLineBytes *(lHeight-1-i)+ j;if(*lpSrc==objectCount) *lpSrc=0;}}objectCount--;if(objectCount<0) objectCount=0;}}DisplayNewImg(pMarker, lLineBytes ,lHeight,"Marker Image");Watershed(pMarker,objectCount);DisplayNewImg(pOrgIMg, lLineBytes ,lHeight,"Origin Image");memcpy( pDoc->m_pDib->m_lpImage,pMarker, lLineBytes * lHeight);pDoc->SetTitle("Watershed");//如果粘连、或者一个目标多区域描述,可以进一步处理//将其二值化(门限>0),利用腐蚀、标注、条件膨胀可解决该问题,见物体分离DisplayObjLabel(objectCount); EndWaitCursor();delete []pMarker;delete []pOrgIMg;}//利用各个目标点与背景点(objectCount>0)对其邻域进行处理(相当于膨胀),//其邻域梯度小(不大于当前值)就并入,否则待以后处理(梯度递增、相当于水位上升)//利用队列确定梯度小的邻域先处理,每个目标同步处理,梯度小的未处理点(objectCount==0)并入最近的目标//pMarkImg中所有点处理完为结果,1--表示背景,物体标识为2--objectCount+1//可以不处理完,阈值上升到(例如128)一定时停止,这时其中还有位处理点(梯度较大),判断为背景int CImageProcessView::Watershed(unsigned char* pMarkImg,int objectCount){CImageProcessDoc* pDoc = GetDocument();unsigned char * lpSrc;unsigned char * lpDst;if(!objectCount){MessageBox("无区域种子!","Message");return 0;}//int direct[8][2]={{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}};//水域生长//每个种子同步生长,在交融处停止;标志区全部被标志for(int grad=2;grad<128;grad++){//256; 可以调整,大了浪费时间但没有问题for(int obj=1;obj<=objectCount;obj++){bool bchg=true;while(bchg){bchg=false;for (int i = pDoc->StartPoint.y+1; i <pDoc->EndPoint.y; i ++){lpDst =pMarkImg  + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x;lpSrc =pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x;for (int j =pDoc->StartPoint.x+1; j <pDoc->EndPoint.x; j ++){ lpDst++;lpSrc++;if((*lpDst)==obj){   for(int m=-1;m<2;m++)for(int n=-1;n<2;n++)if(*(lpDst+m*lLineBytes+n)==0)if((*(lpSrc+m*lLineBytes+n))<=grad){ (*(lpDst+m*lLineBytes+n))=(BYTE)obj;bchg=true;}}}}}}}//obj-- ,0--back, //未处理点置为背景for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc =pMarkImg + lLineBytes * (lHeight-1-i)+ j;if(*lpSrc)*lpSrc=*lpSrc-1;}}return 0;}void CImageProcessView::DisplayObjLabel(int objectCount){//display colorCImageProcessDoc* pDoc = GetDocument();int dstep=250/objectCount;unsigned char* lpSrc=(unsigned char*)pDoc->m_pDib->m_lpvColorTable;for (int i=1;i<=objectCount;i++)//0 --back{*(lpSrc+i*4+1)=(BYTE)(i*dstep);*(lpSrc+i*4)=(BYTE)(255-i*dstep);*(lpSrc+i*4+2)=(BYTE)((i*20)%256);}//get characterlong int *pArea;pArea=new long int [objectCount+1];for(int i=0;i<=objectCount;i++)pArea[i]=0;for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){ if(*lpSrc>objectCount) continue;//前面可以不做完,有255pArea[*lpSrc]++;lpSrc++;}}long int min=1000;long int max=0;long int total=0;CString str;str="\n\tNo\t\tArea";for(int i=1;i<objectCount;i++)//1 --back{if(pArea[i]>max)max=pArea[i];if(pArea[i]<min)min=pArea[i];total+=pArea[i];CString str1;str1.Format("\n\t%3d:\t\t%d",i,pArea[i]);str+=str1;}//int aver=total/(objectCount-1);InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);MessageBox(str);delete []pArea;}void CImageProcessView::OnUpdateSegmentationWatershed(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnApplicationThinbycondition(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;unsigned char*lpDst;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){// 分配内存失败return ;}// 更改光标形状BeginWaitCursor();lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);// 3×3相邻区域像素值unsigned char S[3][3];bool bOver=false;while (!bOver){bOver = true;for(int kk=0;kk<2;kk++){//do step1/step2for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpDst++;lpSrc++;// 如果源图像中当前点为Backgroung,则跳过if (*lpSrc==TWOVALUE_L)continue;if(i<1 || i>=lHeight-1 && j<1 && j>=lWidth-1)continue;// 获得当前点相邻的3×3区域内像素值,白色用1代表,黑色用0代表for (int m = 0; m < 3; m++){for (int n = 0; n < 3; n++){if (*(lpSrc +  (1-m)* lLineBytes  + n-1 ) >= TWOVALUE_H)S[m][n] = 1;elseS[m][n] = 0;}}// 判断条件一是否成立:int Num =  S[0][0] + S[0][1] + S[0][2] + S[1][0] + S[1][2] + S[2][0]+ S[2][1] + S[2][2];if (Num < 2 || Num >6){continue;}// 判断条件二是否成立:Num = 0;if (S[0][1] == 0 && S[0][2] == 1) Num++;if (S[0][2] == 0 && S[1][2] == 1)Num++;if (S[1][2] == 0 && S[2][2] == 1)Num++;if (S[2][2] == 0 && S[2][1] == 1)Num++;if (S[2][1] == 0 && S[2][0] == 1)Num++;if (S[2][0] == 0 && S[1][0] == 1)Num++;if (S[1][0] == 0 && S[0][0] == 1)Num++;if (S[0][0] == 0 && S[0][1] == 1)Num++;if (Num != 1){continue;}if(kk==0){// 判断条件三是否成立;if (S[0][1] * S[1][2] * S[2][1] != 0)continue;// 判断条件四是否成立:if (S[1][2] * S[2][1] * S[1][0] != 0)continue;}else{// 判断条件三是否成立;if (S[0][1] * S[1][2] * S[1][0] != 0)continue;// 判断条件四是否成立:if (S[0][1] * S[2][1] * S[1][0] != 0)continue;}// 如果条件均满足则标注该点*lpDst = 0;bOver= false;}}//删除所有标注点if(!bOver){lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy(lpSrc, lpNewDIBBits, lLineBytes * lHeight);}}}CString str=pDoc->GetTitle();pDoc->SetTitle(str+"条件-细化");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);EndWaitCursor();// 释放内存delete []lpNewDIBBits;}void CImageProcessView::OnUpdateApplicationThinbycondition(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code herepCmdUI->Enable(m_bTwoValue);}//获取模板,可调用图像或在图中选择区域//计算相关系数并显示(-1,1)为(0,255)//可以方便的利用系数门限确定是否匹配,未做void CImageProcessView::OnObjectrecognitionCorrelationmatch(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();unsigned char*lpSrc;unsigned char*lpDst;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){// 分配内存失败return ;}lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memset( lpNewDIBBits,0, lLineBytes * lHeight);int tol=0;for (int m = 0; m <m_ModelHeight; m++)for (int n =0; n <m_ModelWidth; n++)tol+=m_pModelData[m*m_ModelWidth+n];int size=m_ModelHeight*m_ModelWidth;int ModelMean=tol/size;int ModelSigm2=0;for (int m = 0; m <m_ModelHeight; m++)for (int n =0; n <m_ModelWidth; n++)ModelSigm2+=((m_pModelData[m*m_ModelWidth+n]-ModelMean)*(m_pModelData[m*m_ModelWidth+n]-ModelMean));for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;if(i-m_ModelHeight/2<0 || i+m_ModelHeight/2>lHeight-1 || j-m_ModelWidth/2<0 || j+m_ModelWidth/2>lWidth-1)continue;tol=0;for (int m = -m_ModelHeight/2; m <=m_ModelHeight/2; m++)for (int n = -m_ModelWidth/2; n <=m_ModelWidth/2; n++)tol+=*(lpSrc-m*lLineBytes+n);int ImgMean=tol/size;int ImgSigm2=0;int ImgModel=0;for (int m = -m_ModelHeight/2; m <=m_ModelHeight/2; m++){for (int n = -m_ModelWidth/2; n <=m_ModelWidth/2; n++){ImgSigm2+=((*(lpSrc-m*lLineBytes+n)-ImgMean)*(*(lpSrc-m*lLineBytes+n)-ImgMean));ImgModel+=((*(lpSrc-m*lLineBytes+n)-ImgMean)*(m_pModelData[(m+m_ModelWidth/2)*m_ModelWidth+n+m_ModelWidth/2]-ModelMean));}}double r;r=((double)ImgModel)/sqrt((double)ImgSigm2*ModelSigm2);*lpDst=(BYTE)min((int)(128+r*128),255);}}//displayDisplayNewImg(lpNewDIBBits,lLineBytes,lHeight,"相关系数(-1,1)-(0,255)");//display orignal image// 恢复光标EndWaitCursor();delete [] lpNewDIBBits;}void CImageProcessView::OnUpdateObjectrecognitionCorrelationmatch(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)if(m_pModelData)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnMorphologicalDistancetransform(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();unsigned char*lpSrc;int*lpDst;int* pDist;pDist=new int [lLineBytes*lHeight];if (pDist == NULL){return ;}Distance(pDist);//displayint MaxDist=0;for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpDst =pDist + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;if(*lpDst) {//*lpDst/=3;if(*lpDst>MaxDist) MaxDist=*lpDst;if(*lpDst>255) *lpSrc=255;else *lpSrc=(BYTE)*lpDst;}}}lpSrc=(unsigned char*)pDoc->m_pDib->m_lpvColorTable;for (int i=1;i<=min(MaxDist,255);i++){*(lpSrc+i*4+1)=(i/2%10)*25;*(lpSrc+i*4)=(10-i/2%10)*25;*(lpSrc+i*4+2)=(i/2%6)*50;}CString str=pDoc->GetTitle();pDoc->SetTitle(str+"距离");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);EndWaitCursor();// 释放内存delete [] pDist;}void CImageProcessView::OnUpdateMorphologicalDistancetransform(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code herepCmdUI->Enable(m_bTwoValue);}//设置背景距离为0 物体为大值//顺序扫描,利用邻域值修正(+3,+4 近似欧几里得距离)取最小值改变当前距离值//再次反向扫描,修改距离//其值为3倍像数点值void CImageProcessView::Distance(int * pDist){CImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;int*lpDst;//init 0,maxconst int max=10000;//for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpDst =pDist + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;if(*lpSrc) *lpDst=max;else *lpDst=0;}}const int d1=3;//Euclideanconst int d2=4;//do left--right top--downfor (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpDst =pDist + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpDst++;if(*lpDst){int Min=*lpDst;//d2 d1 d2//d1 0if(i>0)           Min=min(Min,*(lpDst+lLineBytes)+d1);if(j>0)           Min=min(Min,*(lpDst-1)+d1);if(i>0 && j>0)    Min=min(Min,*(lpDst+lLineBytes-1)+d2);if(i>0 && j<lWidth-1)Min=min(Min,*(lpDst+lLineBytes+1)+d2);//set label*(lpDst)=Min;}}}//do right--left down--topfor (int i =pDoc->EndPoint.y; i >=pDoc->StartPoint.y; i --){for (int j =pDoc->EndPoint.x; j>=pDoc->StartPoint.x; j --){ lpDst =pDist + lLineBytes * (lHeight - 1 - i)+ j;if(*lpDst){int Min=*lpDst;//    0 d1//d2 d1 d2if(i<lHeight-1)           Min=min(Min,*(lpDst-lLineBytes)+d1);if(j<lWidth-1)           Min=min(Min,*(lpDst+1)+d1);if(i<lHeight-1 && j>0)    Min=min(Min,*(lpDst-lLineBytes-1)+d2);if(i<lHeight-1 && j<lWidth-1)Min=min(Min,*(lpDst-lLineBytes+1)+d2);//set label*(lpDst)=Min;}}}}void CImageProcessView::OnApplicationSeparateobject(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();//int Obj=TWOVALUE_H;int Back=TWOVALUE_L;const int M=31;const int N=31;const int r=15;int **S;S =  new int * [M];for (int i = 0; i < M; i++) {S[i] = new int[N] ;}for (int i = 0; i < M; i++){ for (int j = 0; j < N; j++)if((i-M/2)*(i-M/2)+(j-N/2)*(j-N/2)<r*r)S[i][j]=1;else S[i][j]=0;}unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){// 分配内存失败return ;}memcpy( lpNewDIBBits,pDoc->m_pDib->m_lpImage, lLineBytes * lHeight);//1)腐蚀Erosion(S,M,N,Back);DisplayNewImg( pDoc->m_pDib->m_lpImage,lLineBytes,lHeight,"种子图像");//2) 标记int ObjNum=Connectedcomponents();//3)条件膨胀int obj=-1;unsigned char* lpSrc;unsigned char* lpDst;unsigned char* lpDst1;unsigned char*lpNewDIBBits1;lpNewDIBBits1=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits1 == NULL)return ;memcpy( lpNewDIBBits1,pDoc->m_pDib->m_lpImage, lLineBytes * lHeight);for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = lpNewDIBBits +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpDst =pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;lpDst1 =lpNewDIBBits1 + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;lpDst1++;if ((*(lpSrc) !=Back) && (*(lpDst) ==Back)){//原图像有值bool bObj=false;for (int m = 0; m < M; m++){for (int n = 0; n < N; n++){if (S[m][n] == 0)continue;if(i+m-M/2>=0 && i+m-M/2<lHeight && j+n -N/2>=0 && j+n-N/2<lWidth)//图像内if (*(lpDst1 - lLineBytes*(m-M/2)  +(n-N/2) ) !=Back)//有非背景点{   bObj=true;obj=*(lpDst1 + lLineBytes*(M/2 - m)  +(n - N/2));//取当前标记值m=M;n=N;//out}}}if(bObj) *lpDst=(BYTE)obj;//设置该目标点为判断的标记值,若多个标记相连,取首个,不同于水域分割,同时生长,也可多次小范围膨胀}}}//4 显示结果DisplayObjLabel(ObjNum+1);InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);DisplayNewImg( lpNewDIBBits,lLineBytes,lHeight,"原图像");// 恢复光标EndWaitCursor();delete [] lpNewDIBBits;delete [] lpNewDIBBits1;for(int i=0;i<M;i++)delete []S[i];delete []S;}void CImageProcessView::OnUpdateApplicationSeparateobject(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code herepCmdUI->Enable(m_bTwoValue);}void CImageProcessView::OnWatershedprocessGetseed(){// TODO: Add your command handler code hereif(m_pModelData)//have image{CImageProcessDoc* pDoc = GetDocument();unsigned char *lpSrc;unsigned char *lpDst;unsigned char *lpDst1;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL)return ;memcpy( lpNewDIBBits,m_pModelData, lLineBytes * lHeight);memset( m_pModelData,0, lLineBytes * lHeight);const int GradientTh=30;const int GrayTh=100;int max=0;for (int i = pDoc->StartPoint.y+1; i <pDoc->EndPoint.y; i ++){for (int j =pDoc->StartPoint.x+1; j <pDoc->EndPoint.x; j ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + j;lpDst = m_pModelData +  lLineBytes* (lHeight-1-i) + j;lpDst1 = lpNewDIBBits +  lLineBytes*i + j;//area, not bmpif(*lpDst1>max) max=*lpSrc;if((*lpSrc<GradientTh) && (*lpDst1 <GrayTh)){//目标内部int min=255;for(int m=-1;m<2;m++)for(int n=-1;n<2;n++)if(min>*(lpSrc+m*lLineBytes+n))min=*(lpSrc+m*lLineBytes+n);if(min==*lpSrc)*lpDst=TWOVALUE_H;}}}for (int i = pDoc->StartPoint.y+1; i <pDoc->EndPoint.y; i ++){for (int j =pDoc->StartPoint.x+1; j <pDoc->EndPoint.x; j ++){lpDst = m_pModelData +  lLineBytes* (lHeight-1-i) + j;lpDst1 = lpNewDIBBits +  lLineBytes*i + j;//area, not bmpif(*lpDst1==max)*lpDst=TWOVALUE_H;}}DisplayNewImg(m_pModelData,lLineBytes,lHeight,"Marked Point");//delete [] lpNewDIBBits;}else{//select point by handm_bWatershedProcGetSeed=true;m_pModelData=new unsigned char [lWidth*lHeight];memset(m_pModelData,0,lWidth*lHeight);}}void CImageProcessView::OnUpdateWatershedprocessGetseed(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnWatershedprocessLabelmarked(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();if(m_bWatershedProcGetSeed){DisplayNewImg( pDoc->m_pDib->m_lpImage,lLineBytes,lHeight,"原图像");memcpy( pDoc->m_pDib->m_lpImage,m_pModelData , lLineBytes * lHeight);unsigned char* lpSrc;unsigned char* lpDst;for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = m_pModelData +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpDst = pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;if ((*(lpSrc) == TWOVALUE_H)){*(lpDst-1)=TWOVALUE_H;*(lpDst+1)=TWOVALUE_H;*(lpDst+lLineBytes)=TWOVALUE_H;*(lpDst-lLineBytes)=TWOVALUE_H;*(lpDst+lLineBytes-1)=TWOVALUE_H;*(lpDst+lLineBytes+1)=TWOVALUE_H;*(lpDst-lLineBytes-1)=TWOVALUE_H;*(lpDst-lLineBytes+1)=TWOVALUE_H;}}}}int ObjNum=Connectedcomponents();memcpy( m_pModelData ,pDoc->m_pDib->m_lpImage, lLineBytes * lHeight);if(ObjNum)DisplayObjLabel(ObjNum+1);}void CImageProcessView::OnUpdateWatershedprocessLabelmarked(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code herepCmdUI->Enable(m_pModelData!=NULL);}// Edge imgvoid CImageProcessView::OnWatershedprocessGetareas(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();unsigned char* lpSrc;BeginWaitCursor();int objectCount=0;for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = m_pModelData +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;if ((*lpSrc)>objectCount)objectCount=*(lpSrc);}}//set boarder 255for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;if (i == pDoc->StartPoint.y || i==pDoc->EndPoint.y || j ==pDoc->StartPoint.x || j ==pDoc->EndPoint.x)*(lpSrc)=255;}}Watershed(m_pModelData,objectCount);memcpy( pDoc->m_pDib->m_lpImage,m_pModelData, lLineBytes * lHeight);pDoc->SetTitle("Watershed");DisplayObjLabel(objectCount); // 恢复光标EndWaitCursor();}void CImageProcessView::OnUpdateWatershedprocessGetareas(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code herepCmdUI->Enable(m_pModelData!=NULL);}void CImageProcessView::OnSegmentationOstu(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();//直方图数组int lHistogram[256]={0};GetHistgram(lHistogram,true);int iThreshold;//用于计算区域灰度平均值的中间变量double m1,m2,w1,w2;double maxD=0.0;int size=(pDoc->EndPoint.x-pDoc->StartPoint.x+1)*(pDoc->EndPoint.y-pDoc->StartPoint.y+1);for(iThreshold = 1; iThreshold< 255;iThreshold ++){m1 =0.0;m2=0.0;w1 =0.0;w2=0.0;//求两个区域的灰度平均值m and number wfor (int i =0;i <=iThreshold;i++){m1 += lHistogram[i]*i;//w1 += lHistogram[i];//total num}for (int i = iThreshold+1;i < 256;i++){m2 += lHistogram[i]*i;}m1/=w1;m2/=(size-w1);w1/=size;w2=1-w1;double dev_B=w1*w2*(m2-m1)*(m2-m1);if(dev_B>maxD){maxD=dev_B;THRESHOLD=iThreshold;}}Fixedthreshold();//display HistCString str;str.Format("Treshold(%d)",THRESHOLD);DisplayDlg dlg;dlg.pData=&lHistogram[0];dlg.m_Sizex=256;dlg.m_Title=str;dlg.m_Level=1;//draw numberdlg.m_LinePos=THRESHOLD;dlg.DoModal();// 恢复光标EndWaitCursor();}void CImageProcessView::OnUpdateSegmentationOstu(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnSegmentationEntropy(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();//直方图数组int lHistogram[256]={0};GetHistgram(lHistogram,true);int size=(pDoc->EndPoint.x-pDoc->StartPoint.x+1)*(pDoc->EndPoint.y-pDoc->StartPoint.y+1);int iThreshold;double maxH=0.0;for(iThreshold = 1; iThreshold< 255;iThreshold ++){double Pk =0.0;for (int i =0;i <=iThreshold;i++){Pk+= lHistogram[i];}Pk/=size;if(Pk<0.01 || Pk>0.99) continue;double H1=0.0;for (int i =0;i <=iThreshold;i++){double dtmp=((double)lHistogram[i])/size;if(dtmp>0.0001)H1+= dtmp*log(dtmp);}double H2=0.0;for (int i = iThreshold+1;i < 256;i++){double dtmp=((double)lHistogram[i])/size;if(dtmp>0.0001)H2+= dtmp*log(dtmp);}double H=log(Pk)+log(1-Pk)-H1/Pk-H2/(1-Pk);if(H>maxH){maxH=H;THRESHOLD=iThreshold;}}Fixedthreshold();//display HistCString str;str.Format("Treshold(%d)",THRESHOLD);DisplayDlg dlg;dlg.pData=&lHistogram[0];dlg.m_Sizex=256;dlg.m_Title=str;dlg.m_Level=1;//draw numberdlg.m_LinePos=THRESHOLD;dlg.DoModal();// 恢复光标EndWaitCursor();}void CImageProcessView::OnUpdateSegmentationEntropy(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}//假设存在2个正态分布,估计其均值、方差//估计其背景、目标的比例//依据最小误判概率,解2次方差void CImageProcessView::OnSegmentationMaxlikelihood(){// TODO: Add your command handler code here//CImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();//直方图数组int lHistogram[256]={0};GetHistgram(lHistogram,true);//get meanBack,meanObjint meanBack,meanObj;int ABack,AObj;//get max ABack=0;meanBack=-1;meanObj=-1;for (int i = 0; i < 256;i++){  if(ABack<lHistogram[i]) {ABack=(int)lHistogram[i];//maxmeanBack=i;}}int minH=0;while(lHistogram[minH]<ABack/20)minH++;int maxH=255;while(lHistogram[maxH]<ABack/20)maxH--;//get second maxAObj=0;int pos=meanBack-(maxH-minH)/3;int min=lHistogram[meanBack];if(pos<0) pos=0;if(meanBack>10){for (int i =pos ; i>=0 ;i--){if(min>lHistogram[i])min=lHistogram[i];else{pos=i;break;}if(min<10) {pos=i;break;}}for (int i = pos; i >=0 ;i--){if(AObj<lHistogram[i]) {AObj=(int)lHistogram[i];//maxmeanObj=i;}}}min=lHistogram[meanBack];pos=meanBack+(maxH-minH)/3;if(pos>255) pos=255;if(meanBack<250){for (int i = pos; i<256 ;i++){if(min>lHistogram[i])min=lHistogram[i];else{pos=i;break;}if(min<10) {pos=i;break;}}for (int i = pos; i <256 ;i++){if(AObj<lHistogram[i]) {AObj=(int)lHistogram[i];//maxmeanObj=i;}}}if(meanObj<meanBack){//swapint tmp=meanBack;meanBack=meanObj;meanObj=tmp;int  dtmp=ABack;ABack=AObj;AObj=dtmp;}TRACE("\nmeanBack=%d,(%d),meanObj=%d,(%d) posStep=%d\n\n",meanBack,ABack,meanObj,AObj,(maxH-minH)/3);//get segmdouble segmBack;pos=meanBack;bool bfind=false;if(meanBack>10){while(pos>0 && !bfind){pos--;double dtmp=((double)lHistogram[pos])/ABack;if(dtmp<exp(-0.5))bfind=true;}}else{while(pos<255 && !bfind){pos++;double dtmp=((double)lHistogram[pos])/ABack;if(dtmp<exp(-0.5))bfind=true;}}segmBack=abs(pos-meanBack);if(segmBack<3.0)segmBack=3.0;//不连续直方图else if(segmBack>meanObj-meanBack)segmBack=(meanObj-meanBack)/3;double segmObj;pos=meanObj;bfind=false;if(meanObj>255-10){while(pos>0 && !bfind){pos--;double dtmp=((double)lHistogram[pos])/AObj;if(dtmp<exp(-0.5))bfind=true;}}else{while(pos<255 && !bfind){pos++;double dtmp=((double)lHistogram[pos])/AObj;if(dtmp<exp(-0.5))bfind=true;}}segmObj=abs(pos-meanObj);if(segmObj<3.0)segmObj=3.0;//不连续直方图else if(segmObj>meanObj-meanBack)segmObj=(meanObj-meanBack)/3;TRACE("\nmeanBack=%d,segmBack=%3.1f,meanObj=%d,segmObj=%3.1f",meanBack,segmBack,meanObj,segmObj);//get Th--比例double Th=AObj*segmObj/(AObj*segmObj+ABack*segmBack);//get iThresholddouble A,B,C;A=segmObj*segmObj-segmBack*segmBack;B=2.0*(-meanBack*segmObj*segmObj+meanObj*segmBack*segmBack);C=meanBack*meanBack*segmObj*segmObj-meanObj*meanObj*segmBack*segmBack-2.0*segmObj*segmObj*segmBack*segmBack*log(segmObj/segmBack*(1.0-Th)/Th);if(A>0.01 || A<-0.01){ //A!=0double t1=(-B+sqrt(B*B-4*A*C))/(2.0*A);double t2=(-B-sqrt(B*B-4*A*C))/(2.0*A);if(t1>meanBack && t1<meanObj) THRESHOLD=(int)(t1+0.5);if(t2>meanBack && t2<meanObj) THRESHOLD=(int)(t2+0.5);}else if(B>0.01 || B<-0.01)THRESHOLD=(int)max((-C/B+0.5),0.0);else THRESHOLD=0;//errFixedthreshold();//display HistCString str;str.Format("Treshold(%d)",THRESHOLD);DisplayDlg dlg;dlg.pData=&lHistogram[0];dlg.m_Sizex=256;dlg.m_Title=str;dlg.m_Level=1;//draw numberdlg.m_LinePos=THRESHOLD;dlg.DoModal();// 恢复光标EndWaitCursor();}void CImageProcessView::OnUpdateSegmentationMaxlikelihood(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}//目标为黑,适合扫描文字提取,可克服明亮程度的不同//利用邻域的最大最小值获取阈值void CImageProcessView::OnSegmentationLocalthresholding(){CImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){return ;}unsigned char*lpSrc;unsigned char*lpDst;lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);const int M=5;const int N=5;int minrange=255/5;for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;if(i>=M/2 && i<lHeight-M/2 && j>=N/2 && j<lWidth-N/2){int min=255;int max=0;for(int m=-M/2;m<=M/2;m++)for(int n=-N/2;n<=N/2;n++){if(*(lpSrc+m*lLineBytes+n)>max)max=*(lpSrc+m*lLineBytes+n);if(*(lpSrc+m*lLineBytes+n)<min)min=*(lpSrc+m*lLineBytes+n);int range=max-min;int T;if(range>minrange)T=(min+max)/2;elseT=max-min/2;//all whiteif(*lpSrc>T)*(lpDst)=255;else*(lpDst)=0;}}else*(lpDst)=255;//back}}DisplayNewImg(lpNewDIBBits,lLineBytes,lHeight,"自适应局部阈值");//// 释放内存delete []lpNewDIBBits;EndWaitCursor();}void CImageProcessView::OnUpdateSegmentationLocalthresholding(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnApplicationParallelthin(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;unsigned char*lpDst;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){// 分配内存失败return ;}// 更改光标形状BeginWaitCursor();lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);BOOL bOver=false;while(!bOver){bOver=true;//North://x  0  x//x (1) x//x  1  xfor (int i = pDoc->StartPoint.y+1; i <pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x;lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x;for (int j =pDoc->StartPoint.x+1; j <pDoc->EndPoint.x; j ++){lpDst++;lpSrc++;bool A0,A1,A2,A3,A4,A5,A6,A7,A8;A0 = *lpSrc>0;A1 = *(lpSrc+1)>0;A2 = *(lpSrc+lLineBytes+1)>0;A3 = *(lpSrc+lLineBytes)>0;A4 = *(lpSrc+lLineBytes-1)>0;A5 = *(lpSrc-1)>0;A6 = *(lpSrc - lLineBytes-1)>0;A7 = *(lpSrc - lLineBytes)>0;A8 = *(lpSrc - lLineBytes+1)>0;if(A0 && !A3 && A7){int sigm=A1+A2+A3+A4+A5+A6+A7+A8;int chi=(A1!=A3)+(A3!=A5)+(A5!=A7)+(A7!=A1)+2*((A1 && A2 && !A3)+(!A3 && A4 && !A5)+(!A5 && A6 && !A7)+(!A7 && A8 && !A1));if((chi==2) && (sigm!=1)){*lpDst = TWOVALUE_L;bOver=false;}}}}lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy(lpSrc, lpNewDIBBits, lLineBytes * lHeight);//South://x  1  x//x (1) x//x  0  xfor (int i = pDoc->StartPoint.y+1; i <pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x;lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x;for (int j =pDoc->StartPoint.x+1; j <pDoc->EndPoint.x; j ++){lpDst++;lpSrc++;bool A0,A1,A2,A3,A4,A5,A6,A7,A8;A0 = *lpSrc>0;A1 = *(lpSrc+1)>0;A2 = *(lpSrc+lLineBytes+1)>0;A3 = *(lpSrc+lLineBytes)>0;A4 = *(lpSrc+lLineBytes-1)>0;A5 = *(lpSrc-1)>0;A6 = *(lpSrc - lLineBytes-1)>0;A7 = *(lpSrc - lLineBytes)>0;A8 = *(lpSrc - lLineBytes+1)>0;if(A0 && !A7 && A3){int sigm=A1+A2+A3+A4+A5+A6+A7+A8;int chi=(A1!=A3)+(A3!=A5)+(A5!=A7)+(A7!=A1)+2*((A1 && A2 && !A3)+(!A3 && A4 && !A5)+(!A5 && A6 && !A7)+(!A7 && A8 && !A1));if((chi==2) && (sigm!=1)){*lpDst = TWOVALUE_L;bOver=false;}}}}lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy(lpSrc, lpNewDIBBits, lLineBytes * lHeight);//East://x  x  x//0 (1) 1//x  x  xfor (int i = pDoc->StartPoint.y+1; i <pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x;lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x;for (int j =pDoc->StartPoint.x+1; j <pDoc->EndPoint.x; j ++){lpDst++;lpSrc++;bool A0,A1,A2,A3,A4,A5,A6,A7,A8;A0 = *lpSrc>0;A1 = *(lpSrc+1)>0;A2 = *(lpSrc+lLineBytes+1)>0;A3 = *(lpSrc+lLineBytes)>0;A4 = *(lpSrc+lLineBytes-1)>0;A5 = *(lpSrc-1)>0;A6 = *(lpSrc - lLineBytes-1)>0;A7 = *(lpSrc - lLineBytes)>0;A8 = *(lpSrc - lLineBytes+1)>0;if(A0 && !A5 && A1){int sigm=A1+A2+A3+A4+A5+A6+A7+A8;int chi=(A1!=A3)+(A3!=A5)+(A5!=A7)+(A7!=A1)+2*((A1 && A2 && !A3)+(!A3 && A4 && !A5)+(!A5 && A6 && !A7)+(!A7 && A8 && !A1));if((chi==2) && (sigm!=1)){*lpDst = TWOVALUE_L;bOver=false;}}}}lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy(lpSrc, lpNewDIBBits, lLineBytes * lHeight);//West://x  x  x//1 (1) 0//x  x  xfor (int i = pDoc->StartPoint.y+1; i <pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x;lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x;for (int j =pDoc->StartPoint.x+1; j <pDoc->EndPoint.x; j ++){lpDst++;lpSrc++;bool A0,A1,A2,A3,A4,A5,A6,A7,A8;A0 = *lpSrc>0;A1 = *(lpSrc+1)>0;A2 = *(lpSrc+lLineBytes+1)>0;A3 = *(lpSrc+lLineBytes)>0;A4 = *(lpSrc+lLineBytes-1)>0;A5 = *(lpSrc-1)>0;A6 = *(lpSrc - lLineBytes-1)>0;A7 = *(lpSrc - lLineBytes)>0;A8 = *(lpSrc - lLineBytes+1)>0;if(A0 && !A1 && A5){int sigm=A1+A2+A3+A4+A5+A6+A7+A8;int chi=(A1!=A3)+(A3!=A5)+(A5!=A7)+(A7!=A1)+2*((A1 && A2 && !A3)+(!A3 && A4 && !A5)+(!A5 && A6 && !A7)+(!A7 && A8 && !A1));if((chi==2) && (sigm!=1)){*lpDst = TWOVALUE_L;bOver=false;}}}}lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy(lpSrc, lpNewDIBBits, lLineBytes * lHeight);}CString str=pDoc->GetTitle();pDoc->SetTitle(str+"细化");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);EndWaitCursor();// 释放内存delete []lpNewDIBBits;}void CImageProcessView::OnUpdateApplicationParallelthin(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code herepCmdUI->Enable(m_bTwoValue);}//1. select sub_image(2x2) ,it can improve accuray//    not process ; ==select area by hand //2  select the origin at the center of area//3  let rho>10//4  Sobel//5  count x0,y0 set list and count times//6 sort by num //7 union by pt (near as 1)//8 display positions (liness)//delete last position (around )--not process//9 use center and point(x0,y0) can get line function // not process!//10 get near line (function) point ,then improve accuray by 最小二乘法拟合void CImageProcessView::OnHoughFontofnormal(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;BeginWaitCursor();//err! must be 全局变量/*struct Info{CPoint pt;int num;};*/CList<LineInfo,LineInfo&> myList;LineInfo info;int pixel[8];CPoint center=CPoint((pDoc->EndPoint.x-pDoc->StartPoint.x+1)/2+pDoc->StartPoint.x,(pDoc->EndPoint.y-pDoc->StartPoint.y+1)/2+pDoc->StartPoint.y);const int TH=280;//need be changed::gantrycranefor (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc  = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;if(i>0 && i<lHeight-1 && j>0 && j<lWidth-1){pixel[0] = (int)*(lpSrc+lLineBytes-1);pixel[1] = (int)*(lpSrc+lLineBytes);pixel[2] = (int)*(lpSrc+lLineBytes+1);pixel[3] = (int)*(lpSrc-1);pixel[4] = (int)*(lpSrc+1);pixel[5] = (int)*(lpSrc - lLineBytes-1);pixel[6] = (int)*(lpSrc - lLineBytes);pixel[7] = (int)*(lpSrc - lLineBytes+1);//  1   2   1//  0   0   0// -1  -2  -1int gy=pixel[0]+2*pixel[1]+pixel[2]-pixel[5]-2*pixel[6]-pixel[7];//  -1   0   1//  -2   0   2//  -1   0   1int gx=pixel[2]+2*pixel[4]+pixel[7]-pixel[0]-2*pixel[3]-pixel[5];int result =(int)(sqrt(double(gx*gx+gy*gy))); //edgeif(result>TH){double v=((double)((j-center.x)*gx+(center.y-i)*gy))/(gx*gx+gy*gy);int x0=(int)(v*gx);int y0=(int)(v*gy);bool bfind=false;POSITION pos=myList.GetHeadPosition();while(pos!=NULL){POSITION tmp_pos=pos;info=myList.GetNext(pos);if(info.pt==CPoint(x0,y0)){bfind=true;pos=tmp_pos;break;}}if(!bfind){info.pt=CPoint(x0,y0);info.num=1;myList.AddTail(info);}else{info.num++;myList.SetAt(pos,info);//++}}}}}//watch data//sortfor(POSITION pos1=myList.GetHeadPosition();pos1!=NULL;myList.GetNext(pos1))for(POSITION pos2=myList.GetHeadPosition();pos2!=NULL;myList.GetNext(pos2)){LineInfo info1=myList.GetAt(pos1);LineInfo info2=myList.GetAt(pos2);if(info1.num>info2.num){LineInfo tmp=info1;myList.SetAt(pos1,info2);//++myList.SetAt(pos2,tmp);//++}}POSITION  pos = myList.GetHeadPosition();TRACE("\nBefore Union:\nData(%d):\n",myList.GetCount());while(pos!=NULL){info=myList.GetNext(pos);TRACE("\t(%3d,%3d)=%3d",info.pt.x,info.pt.y,info.num);if(info.num<30) break;}TRACE("\n\n");//unionfor(POSITION pos1=myList.GetHeadPosition();pos1!=NULL;myList.GetNext(pos1))for(POSITION pos2=myList.GetHeadPosition();pos2!=NULL;myList.GetNext(pos2)){LineInfo info1=myList.GetAt(pos1);LineInfo info2=myList.GetAt(pos2);if(info1.pt!= info2.pt){if(abs(info1.pt.x-info2.pt.x)<3 && abs(info1.pt.y-info2.pt.y)<3){ //near ptinfo1.num+=info2.num;myList.SetAt(pos1,info1);//POSITION tmp=pos2;myList.GetPrev(pos2);myList.RemoveAt(tmp);//}}}pos = myList.GetHeadPosition();TRACE("\nAfter Union:\nData(%d):\n",myList.GetCount());while(pos!=NULL){info=myList.GetNext(pos);TRACE("\t(%3d,%3d)=%3d",info.pt.x,info.pt.y,info.num);if(info.num<50) break;}TRACE("\n\n");//find ptpos = myList.GetHeadPosition();CPoint pt;while(pos!=NULL){info=myList.GetNext(pos);//not be sorted nowif(info.num>50){//line length>50pt=info.pt;pt.x+=center.x;pt.y=(center.y-pt.y);//display x0,y0lpSrc  = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-pt.y) + pt.x;*(lpSrc-2)=255;*(lpSrc-1)=255;*(lpSrc)=255;*(lpSrc+1)=255;*(lpSrc+2)=255;*(lpSrc-2*lLineBytes)=255;*(lpSrc-lLineBytes)=255;*(lpSrc+lLineBytes)=255;*(lpSrc+2*lLineBytes)=255;}}//display CenterlpSrc  = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-center.y) + center.x;*(lpSrc-1)=255;*(lpSrc)=255;*(lpSrc+1)=255;*(lpSrc-lLineBytes-1)=255;*(lpSrc-lLineBytes)=255;*(lpSrc-lLineBytes+1)=255;*(lpSrc+lLineBytes-1)=255;*(lpSrc+lLineBytes)=255;*(lpSrc+lLineBytes+1)=255;LPRGBQUAD pDibQuad = (LPRGBQUAD) pDoc->m_pDib->m_lpvColorTable+255;pDibQuad->rgbRed = 255;pDibQuad->rgbGreen =0;pDibQuad->rgbBlue = 0;CString str=pDoc->GetTitle();pDoc->SetTitle(str+"The Foot of Nomal Method");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);EndWaitCursor();}void CImageProcessView::OnUpdateHoughFontofnormal(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}//1.选择一个圆处理//可以进行二值化,标定再处理,获取多个圆---未完成//2提取边缘Sobel//3获取每行起始、终止边缘的中值//4获取每列起始、终止边缘的中值//5 取峰值获得圆心//6 对于边缘点计算半径均值//7 作图形显示圆心、圆void CImageProcessView::OnCircledetectionChordbisectionalg(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){// 分配内存失败return ;}// 更改光标形状BeginWaitCursor();lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);//sobleOnEdgeSobel();const int TH=250;//coins if no use OnEdgeSobel();:400int *ptx;ptx=new int [lWidth];memset(ptx,0,lWidth*sizeof(int));//获取行中心点for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc  = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;bool bfind=false;int pt1=0;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x && !bfind; j ++){lpSrc++;if(*lpSrc>TH){pt1=j;bfind=true;}}if(bfind){lpSrc  = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->EndPoint.x+1;bfind=false;int pt2=0;for (int j =pDoc->EndPoint.x; j >=pDoc->StartPoint.x && !bfind; j --){lpSrc--;if(*lpSrc>TH){pt2=j;bfind=true;}}ptx[(pt2+pt1)/2]++;if((pt2+pt1%2)) ptx[(pt2+pt1)/2+1]++;//后面取最大值,将其赋值,保证峰值点}}int *pty;pty=new int [lHeight];memset(pty,0,lHeight*sizeof(int));//获取列中心点for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){bool bfind=false;int pt1=0;for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y && !bfind; i ++){lpSrc  = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) +j;if(*lpSrc>TH){pt1=i;bfind=true;}}if(bfind){bfind=false;int pt2=0;for (int i =pDoc->EndPoint.y; i >=pDoc->StartPoint.y && !bfind; i --){lpSrc  = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) +j;if(*lpSrc>TH){pt2=i;bfind=true;}}pty[(pt2+pt1)/2]++;if((pt2+pt1%2)) pty[(pt2+pt1)/2+1]++;//后面取最大值,将其赋值,保证峰值点}}//中心点:最大值CPoint center(CPoint(0,0));int max1=0;for(int i=0;i<lWidth;i++)if(ptx[i]>max1){max1=ptx[i];center.x=i;}int max2=0;for(int i=0;i<lHeight;i++)if(pty[i]>max2){max2=pty[i];center.y=i;}delete []ptx;delete []pty;TRACE("\n\nCenter(%d,%d)  max(%d,%d)\n\n",center.x,center.y,max1,max2);//get radiusint num=0;double addRadius=0;for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc  = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x ; j ++){lpSrc++;if(*lpSrc>TH){double r=sqrt(double((j-center.x)*(j-center.x)+(i-center.y)*(i-center.y)));num++;addRadius+=r;}}}double Radius=0;if(num)Radius=addRadius/num;TRACE("\n\nRadiu(%3.1f),edge num=%d\n",Radius,num);lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy(lpSrc, lpNewDIBBits, lLineBytes * lHeight);//original imageCString str=pDoc->GetTitle();pDoc->SetTitle(str+"Circle Detection");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);CString msg;msg.Format("圆心坐标(%d,%d)半径(%3.1f)\n",center.x,center.y,Radius);MessageBox(msg,"Message");//在显示图形前,等待屏幕刷新完成//displayCDC *pdc=GetDC();CPenRedpen;Redpen.CreatePen(PS_DOT, 1, RGB(255,0,0));pdc->SelectObject(Redpen);int radius=(int)(Radius+1.5);//普遍小,补偿?Arc(pdc->m_hDC,center.x-radius,center.y-radius,center.x+radius,center.y+radius,center.x+radius,center.y,center.x+radius,center.y);Rectangle(pdc->m_hDC,center.x-1,center.y-1,center.x+1,center.y+1);DeleteObject(Redpen);EndWaitCursor();// 释放内存delete []lpNewDIBBits;}void CImageProcessView::OnUpdateCircledetectionChordbisectionalg(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}//1.选择一个圆处理//物体为亮,否则圆心计算公式需要调整//可以处理半个圆、//多个圆----未完成//2 Sobel//3 估计半径// 半径递增,取中心点,取最大数下为估计半径。误差+/-1 pixel//半径不必整数,可初调后精调,边缘的大小可对中心数加权,提高精度—未完成//4 中心点精确估计0.1pixel(书上介绍?)//边缘的大小对中心数加权,提高精度//梯度计算重复多次,可利用存储gx、gy降低计算量//5 显示圆、圆心void CImageProcessView::OnCircledetectionAcurr(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;BeginWaitCursor();//估计半径int pixel[8];const int Rmin=20;const int Rmax=35;CList<LineInfo,LineInfo&> myList;LineInfo info;const int TH=400;//coins :need be changedint Max=0;//numint rMax=0;//半径CPoint center;for(int R=Rmin;R<=Rmax;R++){myList.RemoveAll();//get List---info(x0,y0,num)  circle center \point numfor (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc  = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;if(i>0 && i<lHeight-1 && j>0 && j<lWidth-1){pixel[0] = (int)*(lpSrc+lLineBytes-1);pixel[1] = (int)*(lpSrc+lLineBytes);pixel[2] = (int)*(lpSrc+lLineBytes+1);pixel[3] = (int)*(lpSrc-1);pixel[4] = (int)*(lpSrc+1);pixel[5] = (int)*(lpSrc - lLineBytes-1);pixel[6] = (int)*(lpSrc - lLineBytes);pixel[7] = (int)*(lpSrc - lLineBytes+1);//  1   2   1//  0   0   0// -1  -2  -1int gy=pixel[0]+2*pixel[1]+pixel[2]-pixel[5]-2*pixel[6]-pixel[7];//  -1   0   1//  -2   0   2//  -1   0   1int gx=pixel[2]+2*pixel[4]+pixel[7]-pixel[0]-2*pixel[3]-pixel[5];double g =sqrt(double(gx*gx+gy*gy)); //edgeif(g>TH){double v=R/g;int x0=j+(int)(v*gx+0.5);//于书不同!int y0=i-(int)(v*gy+0.5);bool bfind=false;POSITION pos=myList.GetHeadPosition();while(pos!=NULL){POSITION tmp_pos=pos;info=myList.GetNext(pos);if(info.pt==CPoint(x0,y0)){bfind=true;pos=tmp_pos;break;}}if(!bfind){info.pt=CPoint(x0,y0);info.num=1;myList.AddTail(info);}else{info.num++;myList.SetAt(pos,info);//++}}}}}//sortfor(POSITION pos1=myList.GetHeadPosition();pos1!=NULL;myList.GetNext(pos1))for(POSITION pos2=myList.GetHeadPosition();pos2!=NULL;myList.GetNext(pos2)){LineInfo info1=myList.GetAt(pos1);LineInfo info2=myList.GetAt(pos2);if(info1.num>info2.num){LineInfo tmp=info1;myList.SetAt(pos1,info2);//++myList.SetAt(pos2,tmp);//++}}//unionfor(POSITION pos1=myList.GetHeadPosition();pos1!=NULL;myList.GetNext(pos1))for(POSITION pos2=myList.GetHeadPosition();pos2!=NULL;myList.GetNext(pos2)){LineInfo info1=myList.GetAt(pos1);LineInfo info2=myList.GetAt(pos2);if(info1.pt!= info2.pt){if(abs(info1.pt.x-info2.pt.x)<3 && abs(info1.pt.y-info2.pt.y)<3){ //near ptinfo1.num+=info2.num;myList.SetAt(pos1,info1);//POSITION tmp=pos2;myList.GetPrev(pos2);myList.RemoveAt(tmp);//}}}////POSITION pos = myList.GetHeadPosition();//TRACE("\nAfter Union:\nR=%dData(%d):\n",R,myList.GetCount());//while(pos!=NULL){//info=myList.GetNext(pos);//TRACE("\t(%3d,%3d)=%3d",info.pt.x,info.pt.y,info.num);//if(info.num<30) break;//}//TRACE("\n\n");info=myList.GetHead();if(Max<info.num){Max=info.num;rMax=R;center=info.pt;}}TRACE("\n圆心坐标(%3d,%3d)\t 半径(%3d) 数目(%d)\n",center.x,center.y,rMax,Max);//中心点精确估计int R=rMax;double num=0;double totX=0;double totY=0;for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc  = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;if(i>0 && i<lHeight-1 && j>0 && j<lWidth-1){pixel[0] = (int)*(lpSrc+lLineBytes-1);pixel[1] = (int)*(lpSrc+lLineBytes);pixel[2] = (int)*(lpSrc+lLineBytes+1);pixel[3] = (int)*(lpSrc-1);pixel[4] = (int)*(lpSrc+1);pixel[5] = (int)*(lpSrc - lLineBytes-1);pixel[6] = (int)*(lpSrc - lLineBytes);pixel[7] = (int)*(lpSrc - lLineBytes+1);//  1   2   1//  0   0   0// -1  -2  -1int gy=pixel[0]+2*pixel[1]+pixel[2]-pixel[5]-2*pixel[6]-pixel[7];//  -1   0   1//  -2   0   2//  -1   0   1int gx=pixel[2]+2*pixel[4]+pixel[7]-pixel[0]-2*pixel[3]-pixel[5];double g =sqrt(double(gx*gx+gy*gy)); //edgeif(g>TH){double v=R/g;double x0=j+v*gx;double y0=i-v*gy;double s=sqrt((x0-j)*(x0-j)+(y0-i)*(y0-i));if(abs(s-R)<5){//num++;double w=g/TH;num+=w;//边缘峰值加权totX+=(j-(R/s)*(j-x0))*w;totY+=(i-(R/s)*(i-y0))*w;}}}}}if(num>1.0){TRACE("\n中心点精确估计后\n圆心坐标(%3.1f,%3.1f)\t 半径(%3d) 数目(%3.1f)\n",totX/num,totY/num,rMax,num);}//display//MessageBox(msg,"Message");//在显示图形前,等待屏幕刷新完成//displayCDC *pdc=GetDC();CPenRedpen;Redpen.CreatePen(PS_DOT, 1, RGB(255,0,0));pdc->SelectObject(Redpen);int radius=R;center.x=(int)(totX/num+0.5);center.y=(int)(totY/num+0.5);Arc(pdc->m_hDC,center.x-radius,center.y-radius,center.x+radius,center.y+radius,center.x+radius,center.y,center.x+radius,center.y);Rectangle(pdc->m_hDC,center.x-1,center.y-1,center.x+1,center.y+1);DeleteObject(Redpen);EndWaitCursor();}void CImageProcessView::OnUpdateCircledetectionAcurr(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnHistgramGrayBar(){// TODO: Add your command handler code here//CImageProcessDoc* pDoc = GetDocument();int Hist[256]={0};GetHistgram(Hist,false);pDlg=new DisplayDlg();//pDlg->Create(IDD_DISPLAY_DIALOG,this);//pDlg->pData=&Hist[0];//动态时,数据传不过去pDlg->pData=new int [256];memcpy(pDlg->pData,Hist,256*sizeof(int));pDlg->m_Sizex=256;pDlg->m_LinePos=100;pDlg->m_Title=_T("灰度直方图");pDlg->m_Level=1;pDlg->bBar=true;pDlg->ShowWindow(SW_SHOW);}void CImageProcessView::OnUpdateHistgramGrayBar(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnHistgramRgbbar(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();int m_nHistRGB[256*3]={0};unsigned char *lpSrc;// 计算各个灰度值的计数,即得到直方图for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++)for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes*(lHeight-1-i) + j*3;//down -up// 计数加1m_nHistRGB[*(lpSrc+2)]++;//Rm_nHistRGB[256+*(lpSrc+1)]++;//Gm_nHistRGB[256*2+*(lpSrc)]++;//B}pDlg=new DisplayDlg();//pDlg->Create(IDD_DISPLAY_DIALOG,this);pDlg->pData=new int [256*3];memcpy(pDlg->pData, m_nHistRGB,256*3*sizeof(int));pDlg->m_Sizex=256;pDlg->m_Title="彩色RGB直方图";pDlg->m_Level=3;//draw numberpDlg->m_LinePos=0;pDlg->bBar=true;pDlg->ShowWindow(SW_SHOW);}void CImageProcessView::OnUpdateHistgramRgbbar(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==24)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnHistgramHsibar(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();int m_nHistHSI[256*3]={0};unsigned char *lpSrc;// 计算各个灰度值的计数,即得到直方图for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++)for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes*(lHeight-1-i) + j*3;//down -upRGB Rgb;HSI Hsi;Rgb.b=*lpSrc;Rgb.g=*(lpSrc+1);Rgb.r=*(lpSrc+2);RgbtoHsi(&Rgb, &Hsi);unsigned int H,S,I;H=(unsigned int) (Hsi.Hue/360.0*255.0);S=(unsigned int) (Hsi.Saturation*255.0);I=(unsigned int) (Hsi.Intensity*255.0);// 计数加1m_nHistHSI[H]++;//Hm_nHistHSI[256+S]++;//Sm_nHistHSI[256*2+I]++;//I}pDlg=new DisplayDlg();//pDlg->Create(IDD_DISPLAY_DIALOG,this);pDlg->pData=new int [256*3];memcpy(pDlg->pData, m_nHistHSI,256*3*sizeof(int));pDlg->m_Sizex=256;pDlg->m_Title="彩色HSI直方图";pDlg->m_Level=3;//draw numberpDlg->m_LinePos=0;pDlg->bBar=true;pDlg->ShowWindow(SW_SHOW);}void CImageProcessView::OnUpdateHistgramHsibar(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==24)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnObjectrecognitionPlesseycornerdetector(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();// 更改光标形状BeginWaitCursor();//1 filterGaussFilter(7,7,1.0);//-3*1.0--3*1.0//2 differencedouble*Dx;double*Dy;Dx=new double [lLineBytes*lHeight];Dy=new double [lLineBytes*lHeight];_ASSERT(Dx != NULL);//false_ASSERT(Dy != NULL);//falsefor (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){unsigned char *lpSrc  = pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;double* pDx  = Dx +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;double* pDy  = Dy +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;pDx++;pDy++;if(*lpSrc==255)*lpSrc=254;//for display outif(i>1 && i<lHeight-2 && j>1 && j<lWidth-2){*pDx=*(lpSrc-1)-*(lpSrc+1);*pDy=*(lpSrc+lLineBytes)-*(lpSrc-lLineBytes);}else{*pDx=*pDy=0;}}}//3 Dx2=Dx*Dx Dy2 Dxydouble*Dxy;Dxy=new double [lLineBytes*lHeight];_ASSERT(Dxy != NULL);//falsefor (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){double* pDx  = Dx +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;double* pDy  = Dy +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;double* pDxy  = Dxy +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){pDxy++;pDx++;pDy++;*pDxy=(*pDx)*(*pDy);*pDx=(*pDx)*(*pDx);*pDy=(*pDy)*(*pDy);}}//4 filterGaussFilter(Dx,25,25,4.0);GaussFilter(Dy,25,25,4.0);GaussFilter(Dxy,25,25,4.0);////for test//for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){//unsigned char *lpSrc  = pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;//double* pDx  = Dx +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;//double* pDy  = Dy +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;//double* pDxy  = Dxy +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;//for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){//lpSrc++;pDx++;pDy++;pDxy++;//    *lpSrc=min(255,max(0,(*pDxy)/5+128));//            //}//}//// kappa = 0.04 ... 0.06, at most 0.25 .const double kappa = 0.04;const double CxyTh = 250000;double maxCxy=0; for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){unsigned char *lpSrc  = pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;double* pDx  = Dx +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;double* pDy  = Dy +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;double* pDxy  = Dxy +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;pDx++;pDy++;pDxy++;double A=*pDx;double B=*pDy;double C=*pDxy;double Cxy=(A*B-C*C)-kappa*(A+B)*(A+B);if(Cxy>maxCxy)maxCxy=Cxy;if(Cxy>CxyTh)*lpSrc=255;}}TRACE("\nmaxCxy=%6.1f\n",maxCxy);//displayunsigned char* lpSrc=(unsigned char*)pDoc->m_pDib->m_lpvColorTable;*(lpSrc+255*4+1)=0;*(lpSrc+255*4)=0;*(lpSrc+255*4+2)=255;//// 释放内存delete []Dx;delete []Dy;delete []Dxy;CString str=pDoc->GetTitle();pDoc->SetTitle(str+"角点检测");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);EndWaitCursor();}void CImageProcessView::OnUpdateObjectrecognitionPlesseycornerdetector(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnEdgeCanny(){// TODO: 在此添加命令处理程序代码CImageProcessDoc* pDoc = GetDocument();unsigned char*lpImg;// 指向转置图像对应象素的指针unsigned char*lpMag;unsigned char*lpEdge;// 指向转置图像的指针unsigned char*lpNewDIBBits;unsigned char*lpNewDIBBits1;// 暂时分配内存,以保存新图像lpNewDIBBits=new unsigned char [lLineBytes*lHeight];// 判断是否内存分配失败if (lpNewDIBBits == NULL){// 分配内存失败return ;}// 暂时分配内存,以保存新图像lpNewDIBBits1=new unsigned char [lLineBytes*lHeight];// 判断是否内存分配失败if (lpNewDIBBits1 == NULL){// 分配内存失败return ;}BeginWaitCursor();// 针对图像每行进行操作lpImg=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpImg, lLineBytes * lHeight);//1 Gaussian Filterconst int M=7;GaussFilter(M,M,1.5);//edge number down//2 Sobel to get Mag// 针对图像每行进行操作for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpImg =(unsigned char *)pDoc->m_pDib->m_lpImage+  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpMag =lpNewDIBBits1 + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;// 针对每行图像每列进行操作for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){// 指向源DIB第i行,第j个象素的指针lpImg++;//lpMag++;//if(i<1 || i>=lHeight-1 || j<1 || j >=lWidth-1){*lpMag=0;continue;}int valx,valy;valy=*(lpImg+lLineBytes-1)+*(lpImg+lLineBytes)*2+*(lpImg+lLineBytes+1)-*(lpImg-lLineBytes-1)-*(lpImg-lLineBytes)*2-*(lpImg-lLineBytes+1);valx=*(lpImg+lLineBytes-1)+*(lpImg-1)*2+*(lpImg-lLineBytes-1)-*(lpImg+lLineBytes+1)-*(lpImg+1)*2-*(lpImg-lLineBytes+1);int val=(int)(0.5+sqrt(double(valx*valx+valy*valy)));*lpMag=(unsigned char)min(val,255);}}//3 应用non-maximum 抑制const int DOOR=8;// 针对图像每行进行操作for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpMag =lpNewDIBBits1  +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpImg =(unsigned char *)pDoc->m_pDib->m_lpImage  + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;lpEdge =lpNewDIBBits+ lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;// 针对每行图像每列进行操作for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){// 指向源DIB第i行,第j个象素的指针lpImg++;//lpMag++;//lpEdge++;//int g,g1,g2,g3,g4;if(i<1 || i>lHeight-2 || j<1 || j >lWidth-2)*lpEdge = 0 ;else{g=*(lpMag);if(g>DOOR){int gx,gy;gy=*(lpImg-lLineBytes);gy-=*(lpImg+lLineBytes);gx=*(lpImg+1);gx-=*(lpImg-1);double weight;// 如果方向导数y分量比x分量大,说明导数的方向更加“趋向”于y分量。if (abs(gy) > abs(gx)) {// 计算插值的比例weight = fabs((float) gx)/fabs((float) gy); g2 = *(lpMag+lLineBytes) ; g4 = *(lpMag-lLineBytes);// 如果x,y两个方向的方向导数的符号相同// C是当前象素,与g1-g4的位置关系为:// g1 g2 // C         // g4 g3 if (gx*gy > 0) { g1 = *(lpMag+lLineBytes-1) ;g3 =  *(lpMag-lLineBytes+1) ;} // 如果x,y两个方向的方向导数的符号相反// C是当前象素,与g1-g4的位置关系为://    g2 g1// C         // g3 g4  else { g1 =  *(lpMag+lLineBytes+1) ;g3 = *(lpMag-lLineBytes-1) ;} }// 如果方向导数x分量比y分量大,说明导数的方向更加“趋向”于x分量// 这个判断语句包含了x分量和y分量相等的情况else{// 计算插值的比例weight = fabs((float) gy)/fabs((float) gx); g2 =  *(lpMag+1) ; g4 = *(lpMag-1) ;// 如果x,y两个方向的方向导数的符号相同// C是当前象素,与g1-g4的位置关系为://g3   //g4 C g2       //       g1if (gx*gy > 0) {g1 =  *(lpMag-lLineBytes+1) ;g3 =  *(lpMag+lLineBytes-1) ;} // 如果x,y两个方向的方向导数的符号相反// C是当前象素,与g1-g4的位置关系为://     g1//g4 C g2       //  g3     else { g1 = *(lpMag+lLineBytes+1) ;g3 =  *(lpMag-lLineBytes-1) ;}}// 下面利用g1-g4对梯度进行插值{double dTmp1 = weight*g1 + (1-weight)*g2 ;double dTmp2 = weight*g3 + (1-weight)*g4 ;// 当前象素的梯度是局部的最大值// 该点可能是个边界点if(g>=dTmp1 && g>=dTmp2){*lpEdge =TWOVALUE_H ;}else *lpEdge = 0 ;}}else *lpEdge = 0 ;}}}DisplayNewImg(lpNewDIBBits,lLineBytes,lHeight,"non-maximum Edge");//4应用Hysteresis,找到所有的边界//  估计需要的低阈值,高阈值int ThdHigh,ThdLow;int nHist[256];//const double dRatioHigh =0.61;//总边缘数的比例const double dRatioLow =0.3;//// 该数组的大小和梯度值的范围有关,如果采用本程序的算法,那么梯度的范围不会超过pow(2,10)// 初始化for(int k=0; k<256; k++) {nHist[k] = 0; }// 统计直方图,然后利用直方图计算阈值for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpMag =lpNewDIBBits1  +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpEdge =lpNewDIBBits+ lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;// 针对每行图像每列进行操作for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){// 指向源DIB第i行,第j个象素的指针lpEdge++;//lpMag++;//// 只是统计那些可能是边界点,并且还没有处理过的象素if(*lpEdge==TWOVALUE_H){nHist[*lpMag]++;}}}int nEdgeNb = nHist[0]  ;int nMaxMag = 0         ;// 统计经过“非最大值抑止(non-maximum suppression)”后有多少象素for(int k=1; k<256; k++){if(nHist[k] != 0){// 最大梯度值nMaxMag = k;}// 梯度为0的点是不可能为边界点的// 经过non-maximum suppression后有多少象素nEdgeNb += nHist[k];}// 梯度比高阈值*pnThdHigh小的象素点总数目int nHighCount = (int)(dRatioHigh * nEdgeNb +0.5);int nLowCount = (int)(dRatioLow * nEdgeNb +0.5);int k = 1;nEdgeNb = nHist[1];// 计算低阈值while( (k<(nMaxMag-1)) && (nEdgeNb < nLowCount) ){k++;nEdgeNb += nHist[k];}// 设置低阈值ThdLow = k ;// 计算高阈值while( (k<(nMaxMag-1)) && (nEdgeNb < nHighCount) ){k++;nEdgeNb += nHist[k];}// 设置高阈值ThdHigh = k ;TRACE("\nThdLow =%d,ThdHigh=%d\n",ThdLow ,ThdHigh);// 这个循环用来寻找大于nThdHigh的点,这些点被用来当作边界点,然后用// TraceEdge函数来跟踪该点对应的边界(大于ThdLow)for (int i = pDoc->StartPoint.y+1; i <pDoc->EndPoint.y; i ++){lpMag =lpNewDIBBits1  +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x;lpEdge =lpNewDIBBits+ lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x;// 针对每行图像每列进行操作for (int j =pDoc->StartPoint.x+1; j <pDoc->EndPoint.x; j ++){// 指向源DIB第i行,第j个象素的指针lpEdge++;//lpMag++;//// 只是统计那些可能是边界点,并且还没有处理过的象素if(*lpEdge==TWOVALUE_H){if(*lpMag >= ThdHigh){// 设置该点为边界点*lpEdge = 255;TraceEdge(i, j, ThdLow, lpNewDIBBits, lpNewDIBBits1);}}}}//经过试验,无需反向再做一遍,// 那些还没有被设置为边界点的象素已经不可能成为边界点int Num=0;for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpEdge =lpNewDIBBits+ lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpEdge++;//if(*lpEdge!= 255){// 设置为非边界点*lpEdge = 0 ;}elseNum++;}}TRACE("\n Total Edge Num=%d\n",Num);lpImg=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpImg, lpNewDIBBits,lLineBytes * lHeight);CString str=pDoc->GetTitle();pDoc->SetTitle(str+"Canny 边缘检测");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);// 恢复光标EndWaitCursor();// 释放内存delete []lpNewDIBBits;delete []lpNewDIBBits1;}void CImageProcessView::OnUpdateEdgeCanny(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::TraceEdge(int y, int x,int LowThd, unsigned char* pUnchEdge, unsigned char* pnMag){// 对8邻域象素进行查询int xNb[8] = {1, 1, 0,-1,-1,-1, 0, 1} ;int yNb[8] = {0, 1, 1, 1,0 ,-1,-1,-1} ;int yy ;int xx ;int k  ;int nWidth=lLineBytes;for(k=0; k<8; k++){yy =y + yNb[k] ;xx = x + xNb[k] ;// 如果该象素为可能的边界点,又没有处理过// 并且梯度大于阈值if(*(pUnchEdge+(lHeight-1-yy)*lLineBytes+xx) == 128  && *(pnMag+(lHeight-1-yy)*nWidth+xx)>=LowThd){// 把该点设置成为边界点*(pUnchEdge+(lHeight-1-yy)*lLineBytes+xx) = 255 ;// 以该点为中心进行跟踪TraceEdge(yy, xx, LowThd, pUnchEdge, pnMag);}}}void CImageProcessView::OnSegmentationOptimal(){CImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();//直方图数组int lHistogram[256]={0};GetHistgram(lHistogram,true);int iThreshold=*pDoc->m_pDib->m_lpImage;int iOldThreshold=-1;int size=(pDoc->EndPoint.x-pDoc->StartPoint.x+1)*(pDoc->EndPoint.y-pDoc->StartPoint.y+1);for (int i =0;i <=255;i++)if(lHistogram[i]>size/10){iThreshold=i;break;}//用于计算区域灰度平均值的中间变量int m1,m2,w1,w2;while(iThreshold !=iOldThreshold ){iOldThreshold=iThreshold;m1 =0;m2=0;w1 =0;w2=0;//求两个区域的灰度平均值m and number wfor (int i =0;i <=iOldThreshold;i++){m1 += lHistogram[i]*i;//w1 += lHistogram[i];//total num}for (int i = iOldThreshold+1;i < 256;i++){m2 += lHistogram[i]*i;}m1/=w1;m2/=(size-w1);iThreshold=(m1+m2)/2;}THRESHOLD=iThreshold;Fixedthreshold();//display HistCString str;str.Format("Treshold(%d)",THRESHOLD);DisplayDlg dlg;dlg.pData=&lHistogram[0];dlg.m_Sizex=256;dlg.m_Title=str;dlg.m_Level=1;//draw numberdlg.m_LinePos=THRESHOLD;dlg.DoModal();// 恢复光标EndWaitCursor();}void CImageProcessView::OnUpdateSegmentationOptimal(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnEdgeNon(){CImageProcessDoc* pDoc = GetDocument();// 指向转置图像对应象素的指针unsigned char*lpSrc;unsigned char*lpDst;// 指向转置图像的指针unsigned char*lpNewDIBBits;// 暂时分配内存,以保存新图像lpNewDIBBits=new unsigned char [lLineBytes*lHeight];// 指向转置图像的指针// 判断是否内存分配失败if (lpNewDIBBits == NULL){// 分配内存失败return ;}OnEdgeSobel();lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;if(i>0 && i<lHeight-1 && j>0 && j<lWidth-1){if((*lpSrc & 0x3) == 2) //------{if(*lpSrc<*(lpSrc+lLineBytes) || *lpSrc<*(lpSrc-lLineBytes))*lpDst=0;}else if((*lpSrc & 0x3) == 0)//  |{if(*lpSrc<*(lpSrc+1) || *lpSrc<*(lpSrc-1))*lpDst=0;}else  if((*lpSrc & 0x3) == 1)//  |{if(*lpSrc<*(lpSrc+lLineBytes+1) || *lpSrc<*(lpSrc-lLineBytes-1))*lpDst=0;}else {if(*lpSrc<*(lpSrc-lLineBytes+1) || *lpSrc<*(lpSrc+lLineBytes-1))*lpDst=0;}}else *lpDst=0;}}lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy(lpSrc, lpNewDIBBits, lLineBytes * lHeight);CString str=pDoc->GetTitle();str+="--Non_Maximum Suppression";pDoc->SetTitle(str);InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);// 释放内存delete []lpNewDIBBits;}void CImageProcessView::OnUpdateEdgeNon(CCmdUI *pCmdUI){CImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}//process after edgeedvoid CImageProcessView::OnEdgeHysteresis(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;const int HighTh=80;const int LowTh=10;bool bOver=false;while(!bOver){bOver=true;for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;if(*lpSrc>LowTh && *lpSrc<HighTh){for(int m=-1;m<2;m++)for(int n=-1;n<2;n++){if(m+i>0 && m+i<lHeight && n+j>0 && n+j<lWidth){if(*(lpSrc-m*lLineBytes+n)>=HighTh && ((*(lpSrc-m*lLineBytes+n) & 0x3) == (*(lpSrc) & 0x3))){*lpSrc=HighTh;bOver=false;}}}}}}}for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;if(*lpSrc<HighTh)*lpSrc=0;}}CString str=pDoc->GetTitle();str+="--Hysteresis to filter";pDoc->SetTitle(str);InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);}void CImageProcessView::OnUpdateEdgeHysteresis(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnHoughCircle(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();CPoint StartPoint=pDoc->StartPoint;CPoint EndPoint=pDoc->EndPoint;BeginWaitCursor();const int aMax=512;//center x(0-aMax)const int bMax=512;//center y(0-bMax)const int rMin=25;//radium //const int rMax=80;//radiumint dx=max(EndPoint.y-StartPoint.y,EndPoint.y-StartPoint.y)/min(aMax,bMax)+1;int (*pArray)[bMax][rMax-rMin]=new int [aMax][bMax][rMax-rMin];//init  for(int k=0;k<aMax;k++)for(int m=0;m<bMax;m++)for(int r=0;r<rMax-rMin;r++)pArray[k][m][r]=0;const double pi=3.14159;unsigned char* lpSrc;//get pArrayfor (int i = StartPoint.y; i <=EndPoint.y; i ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + StartPoint.x-1;for (int j =StartPoint.x; j <=EndPoint.x; j ++){lpSrc++;if(*lpSrc){for(int theta=0;theta<360;theta+=2)for(int r=rMin;r<rMax;r++){int a=j-StartPoint.x-int(cos((float)theta*pi/180)*r+0.5);int b=i-StartPoint.y-int(sin((float)theta*pi/180)*r+0.5);if(a>=0 && a/dx<aMax && b>=0 && b/dx<bMax){    pArray[a/dx][b/dx][r-rMin]++;}}}}}int N_value=200;int N_MaxVal=100;vector <bool> Err;//重合点数少判为errint  kk=0;//timeswhile(N_value>N_MaxVal && kk<30){kk++;//查找计数器数组中的最大值int Max=0;int A=-1,B=-1,R=-1;for(int r=0;r<rMax-rMin;r++){for(int a=0;a<aMax;a++)for(int b=0;b<bMax;b++){if(pArray[a][b][r]>Max){Max=pArray[a][b][r];A=a;B=b;R=r+rMin;}}}A=A*dx;//chgB=B*dx;CString str;str.Format("\n%d: (a: %d  b: %d r: %d ) Max:%d\n",kk,A+StartPoint.x,B+StartPoint.y,R,Max);TRACE(str);//将最大值点附近清零for(int r=-R/2;r<R/2;r++){   for(int a=A-R/2;a<=A+R/2;a++)for(int b=B-R/2;b<=B+R/2;b++){   if(a>=0 && a<aMax*dx)if(b>=0 && b<bMax*dx)if(r+R>=rMin && r+R<rMax){pArray[a/dx][b/dx][r+R-rMin]=0;}}}N_value=Max;N_MaxVal=20+R/2;if(dx>1) N_MaxVal+=(dx-1)*R;//if dx>1 have more pointA+=StartPoint.x;B+=+StartPoint.y;if(N_value>N_MaxVal){int num=0;int allnum=0;//Draw a circle(A,B,R) to get poin or point--circle int x=0;int y=R;int p=1-R;while(x<y){x++;if(p<0) p+=2*x+1;else{y--;p+=2*(x-y)+1;}for(int i=-1;i<2;i+=2)//-1,1for(int j=-1;j<2;j+=2)//-1,1{if(A+i*x>=StartPoint.x && A+i*x<=EndPoint.x && B+j*y>=StartPoint.y && B+j*y<=EndPoint.y){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-B-j*y) +A+i*x;if(*lpSrc==TWOVALUE_H) num++;*lpSrc=(unsigned char)(min(200+kk,255));allnum++;}if(A+i*y>=StartPoint.x && A+i*y<=EndPoint.x && B+j*x>=StartPoint.y && B+j*x<=EndPoint.y){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-B-j*x) +A+i*y;if(*lpSrc==TWOVALUE_H) num++;*lpSrc=(unsigned char)(min(200+kk,255));allnum++;}}}if(num>allnum/5 && num>N_value/3)Err.push_back(true);elseErr.push_back(false);}}// 复制图像//lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;//memcpy( lpSrc,lpNewDIBBits, lLineBytes * lHeight);LPRGBQUAD pDibQuad = (LPRGBQUAD) pDoc->m_pDib->m_lpvColorTable+200;for(int i=0;i<min(kk,255);i++){// 更新DIB调色板红色分量pDibQuad->rgbRed = 255;// 更新DIB调色板绿色分量pDibQuad->rgbGreen =i*10%256;// 更新DIB调色板蓝色分量pDibQuad->rgbBlue = 0;pDibQuad ++;}//display err find in blueif(Err.size()>0){for(int i=0;i<(int)Err.size();i++){if(!Err[i]){pDibQuad = (LPRGBQUAD) pDoc->m_pDib->m_lpvColorTable+200+i+1;pDibQuad->rgbRed =0;pDibQuad->rgbGreen =0;pDibQuad->rgbBlue = 255;}}}InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);// 恢复光标EndWaitCursor();delete []pArray;}void CImageProcessView::OnUpdateHoughCircle(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnSegmentationDynamic(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();CPoint StartPoint=pDoc->StartPoint;CPoint EndPoint=pDoc->EndPoint;BeginWaitCursor();unsigned char*lpSrc;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){return ;}lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);const int M=25;const int N=25;const int Gdiff=10;//if select small area display dataint Data[256*3]={0};bool bDisplay=false;//draw line?if((EndPoint.x-StartPoint.x)<256) bDisplay=true;int minMean=255;int maxMean=0;int maxDiff=0;unsigned char* lpDst;for (int i = StartPoint.y; i <=EndPoint.y; i ++){for (int j = StartPoint.x; j <= EndPoint.x; j ++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + j;lpDst=lpNewDIBBits +  lLineBytes* (lHeight-1-i) + j;*lpSrc=TWOVALUE_H;int mean=*lpDst;if(i>=N/2 && i<lHeight-N/2 && j>=M/2 && j<lWidth-M/2){int add=0;int num=0;for(int m=-M/2;m<=M/2;m++)for(int n=-N/2;n<=N/2;n++){   if(*(lpDst+lLineBytes* n + m)>(*lpDst+5)){add+=*(lpDst+lLineBytes* n + m);num++;}}if(num>N*M/3)mean=add/num;if(mean-(*lpDst)>Gdiff){*lpSrc=TWOVALUE_L;if(mean-(*lpDst)>maxDiff) maxDiff=mean-(*lpDst);if(mean>maxMean) maxMean=mean;if(mean<minMean) minMean=mean;}}if(bDisplay){if(i==(EndPoint.y/2+StartPoint.y/2)){Data[min(j- StartPoint.x,199)]=mean-*lpDst;//max(mean-*lpDst,0);Data[256+min(j- StartPoint.x,199)]=*lpDst;Data[512+min(j- StartPoint.x,199)]=mean;}}}}if(bDisplay){CString str;str.Format("minMean=%d maxMean=%d  maxDiff=%d",minMean,maxMean,maxDiff);DisplayDlg dlg;dlg.pData=&Data[0];dlg.m_Sizex=256;dlg.m_Title=str;dlg.m_Level=3;//draw numberdlg.m_LinePos=0;dlg.DoModal();}InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);DisplayNewImg(lpNewDIBBits, lLineBytes ,lHeight,"Origin Image");EndWaitCursor();delete [] lpNewDIBBits;}void CImageProcessView::OnUpdateSegmentationDynamic(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnSpatialdomainZoombilinearinterpolation(){// TODO: Add your command handler code hereBeginWaitCursor();ZoomDblLinear(1.8,1.8);//zoom outZoomDblLinear(.8,.8);//zoom inEndWaitCursor();}void CImageProcessView::OnUpdateSpatialdomainZoombilinearinterpolation(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::ZoomDblLinear(double fx, double fy){CImageProcessDoc* pDoc = GetDocument();CPoint StartPoint=pDoc->StartPoint;CPoint EndPoint=pDoc->EndPoint;unsigned char*lpSrc;// 指向转置图像对应象素的指针unsigned char*lpDst;//if scaled down get smooth first; else : aliasing effectsif(fx<1.0 || fy<1.0)GaussFilter(5,5,0);int w,h,l;h=(int)(fy*(EndPoint.y-StartPoint.y+1));w=(int)(fx*(EndPoint.x-StartPoint.x+1));l=(w+3)/4*4;unsigned char *lpNewDIBBits=new unsigned char [h * l];// 判断是否内存分配失败if (lpNewDIBBits == NULL){// 分配内存失败return ;}//out imagefor(int i = 0; i < h; i++){// 列for(int j = 0; j <w ; j++){// 指向DIB第i行,第j个象素的指针lpDst = (unsigned char*)lpNewDIBBits + l * (h - 1 - i) + j;double x=j/fx;double y=i/fy;int x1=(int)x;int y1=(int)y;if(x1+StartPoint.x>=0 && x1+StartPoint.x<lWidth-1 && y1+StartPoint.y>=0 && y1+StartPoint.y<lHeight-1){//inlpSrc = (unsigned char*)pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - y1-StartPoint.y) + x1+StartPoint.x;int v=(unsigned char)((y1+1-y)*((x1+1-x)*(*lpSrc)+(x-x1)*(*(lpSrc+1)))+(y-y1)*((x1+1-x)*(*(lpSrc-lLineBytes))+(x-x1)*(*(lpSrc-lLineBytes+1))));//a=x-x1 b=y-y1 if(v<0) v=0;else if(v>255) v=255;*lpDst=(BYTE)v;}else*lpDst=*(pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - (int)(y+0.5)-StartPoint.y) + (int)(x+0.5)+StartPoint.x);//近邻插值}}CString str;str.Format("Scaling by (%3.2f %3.2f)",fx,fy);DisplayNewImg(lpNewDIBBits, l ,h,str);InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);// 释放内存delete []lpNewDIBBits;return ;}void CImageProcessView::OnUpdateApplicationContourtrace(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code herepCmdUI->Enable(m_bTwoValue);}//obj:black//1)能获取多个边界及参数//2)获取周长//3)存储边界点//4)计算面积//5)显示边界图形//可以在标记后再进行跟踪,无需考虑处理的区域了,每个标号仅有一个起始点void CImageProcessView::OnApplicationContourtrace(){//// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();unsigned char*lpSrc;//1 置处理边沿为背景for (int j = pDoc->StartPoint.y;j <= pDoc->EndPoint.y ;j++){for(int i = pDoc->StartPoint.x;i <= pDoc->EndPoint.x ;i++){if(i == pDoc->StartPoint.x || i == pDoc->EndPoint.x ||  j == pDoc->StartPoint.y || j == pDoc->EndPoint.y){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-j) + i;*lpSrc=TWOVALUE_H;}}}BOOL bFindStartPoint;CPoint StartPoint;int SearchNo=0;const int MaxAreaNum=20;CRect Area[MaxAreaNum];while(SearchNo<MaxAreaNum){//初始化处理区域大小(为后面比较最大最小值)Area[SearchNo].left=lWidth;Area[SearchNo].top=lHeight;Area[SearchNo].right=0;Area[SearchNo].bottom=0;//获取起始点 StartPointbFindStartPoint = false;for (int j = pDoc->StartPoint.y;j <= pDoc->EndPoint.y && !bFindStartPoint;j++){for(int i = pDoc->StartPoint.x;i <= pDoc->EndPoint.x && !bFindStartPoint;i++){lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-j) + i;if(*lpSrc == 0)//obj{bFindStartPoint = true;StartPoint.y = j;StartPoint.x = i;//确定该点不在已经处理的区域内int k_tmp=0;while(k_tmp<SearchNo){if(StartPoint.x<=Area[k_tmp].right && StartPoint.x>=Area[k_tmp].left&& StartPoint.y<=Area[k_tmp].bottom && StartPoint.y>=Area[k_tmp].top)bFindStartPoint = false;k_tmp++;}}}}if(!bFindStartPoint) break;//无新未处理的区域,退出循环//八个方向和起始扫描方向int Direction[8][2]={{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1}};////由于起始点是在左上方,故起始扫描沿左下方向int BeginDirect = 5;////跟踪边界CPoint CurrentPoint;//从初始点开始扫描CurrentPoint.y = StartPoint.y;CurrentPoint.x = StartPoint.x;//起始点//memorey areaif(CurrentPoint.x<Area[SearchNo].left)Area[SearchNo].left=CurrentPoint.x;if(CurrentPoint.x>Area[SearchNo].right)Area[SearchNo].right=CurrentPoint.x;if(CurrentPoint.y<Area[SearchNo].top)Area[SearchNo].top=CurrentPoint.y;if(CurrentPoint.y>Area[SearchNo].bottom)Area[SearchNo].bottom=CurrentPoint.y;vector<CPoint> edgePt;edgePt.push_back(CurrentPoint);double perimeter=0.0;while(1){//沿扫描方向查看一个像素lpSrc = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1- CurrentPoint.y - Direction[BeginDirect][1])+ (CurrentPoint.x + Direction[BeginDirect][0]);if(*lpSrc == 0)//obj{CurrentPoint.y = CurrentPoint.y + Direction[BeginDirect][1];CurrentPoint.x = CurrentPoint.x + Direction[BeginDirect][0];//获取周长if(BeginDirect%2) perimeter+=1.414;else      perimeter+=1;//存储边界点edgePt.push_back(CurrentPoint);if(CurrentPoint.y == StartPoint.y && CurrentPoint.x == StartPoint.x)break;//out while (闭合)//memorey areaif(CurrentPoint.x<Area[SearchNo].left)Area[SearchNo].left=CurrentPoint.x;if(CurrentPoint.x>Area[SearchNo].right)Area[SearchNo].right=CurrentPoint.x;if(CurrentPoint.y<Area[SearchNo].top)Area[SearchNo].top=CurrentPoint.y;if(CurrentPoint.y>Area[SearchNo].bottom)Area[SearchNo].bottom=CurrentPoint.y;//扫描的方向顺时针旋转两格BeginDirect--;if(BeginDirect == -1)BeginDirect = 7;BeginDirect--;if(BeginDirect == -1)BeginDirect = 7;}else{//扫描方向逆时针旋转一格BeginDirect++;if(BeginDirect == 8)BeginDirect = 0;}}SearchNo++;//计算面积int S=0;for(int i=0;i<(int)edgePt.size()-1;i++)S+=(edgePt[i].x*edgePt[i+1].y-edgePt[i+1].x*edgePt[i].y) ;S/=2;if(S<0) S=-S;TRACE("\nNo=%d,面积=%d,周长=%3.1f,圆形度=%3.1f\n",SearchNo,S,perimeter,perimeter*perimeter/S);//CDC *pdc = GetDC();//显示边界图形for(int i=0;i<(int)edgePt.size();i++)pdc->SetPixel(edgePt[i],RGB(255,0,0)) ;//ReleaseDC(pdc);}CString str;str.Format("\nContour Number is %d\n",SearchNo);TRACE(str);//MessageBox(str,"Message ",MB_OK);EndWaitCursor();}void CImageProcessView::OnEdgeTrace(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();CPoint StartPoint=pDoc->StartPoint;CPoint EndPoint=pDoc->EndPoint;unsigned char*lpSrc;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){return ;}lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);//1 get start Point=maxGrad pointCPoint stPt;unsigned char* lpDst;double maxGrad=0;double last_angle=0;for (int i = StartPoint.y; i <=EndPoint.y; i ++){for (int j = StartPoint.x; j <= EndPoint.x; j ++){lpDst=lpNewDIBBits +  lLineBytes* (lHeight-1-i) + j;*lpDst=min(*lpDst,254);if(i>=1 && i<lHeight-1 && j>=1 && j<lWidth-1){CPoint pt=CPoint(j,i);double grad=0.0;double angle=0.0;Gradient(pt,&grad,&angle);if(grad>maxGrad){maxGrad=grad;last_angle=angle;stPt=pt;}}}}if(maxGrad<10){delete[]lpNewDIBBits;return;}//根据边缘方向调整 0: |o (6)int Direction[8][2]={{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}};//const double DiffTh=maxGrad/2;CPoint pt=stPt;int no=0;while(1){lpDst=lpNewDIBBits +  lLineBytes* (lHeight-1-pt.y) + pt.x;*lpDst=255;CPoint nextpt;//下一点位置获取int dir=int((last_angle+22.5)/45);if((last_angle+22.5)>=360)dir=0;//边缘double grad1=0.0;double angle1=0.0;CPoint nextpt1=CPoint(pt.x+Direction[dir][0],pt.y+Direction[dir][1]);Gradient(nextpt1,&grad1,&angle1);double grad2=0.0;double angle2=0.0;dir++;if(dir>8) dir=0;CPoint nextpt2=CPoint(pt.x+Direction[dir][0],pt.y+Direction[dir][1]);Gradient(nextpt2,&grad2,&angle2);double grad=0.0;double angle=0.0;if(grad2>grad1){grad=grad2;angle=angle2;nextpt=nextpt2;}else{grad=grad1;angle=angle1;nextpt=nextpt1;}double diff=abs(last_angle-angle);if(diff>315) diff=0;if(grad>DiffTh && diff<45){last_angle=angle;pt=nextpt;}else{//修正角度//可能不需要,//find max grad near ptdouble maxGrad=0;double tmpangle=last_angle;for(int m=-1;m<2;m++)for(int n=-1;n<2;n++){CPoint tmpPt=pt;tmpPt.x+=m;tmpPt.y+=n;lpDst=lpNewDIBBits +  lLineBytes* (lHeight-1-tmpPt.y) + tmpPt.x;if(*lpDst<255){double grad=0.0;double angle=0.0;Gradient(tmpPt,&grad,&angle);if(abs(angle-last_angle)<15)//5 err!grad*=1.2;if(grad>maxGrad ){maxGrad=grad;nextpt=tmpPt;tmpangle=angle;}}}pt=nextpt;last_angle=tmpangle;}no++;// out of whileif(no>10){if(abs(pt.x-stPt.x)<2 && abs(pt.y-stPt.y)<2){lpDst=lpNewDIBBits +  lLineBytes* (lHeight-1-pt.y) + pt.x;//set 255*lpDst=255;break;}}if(no>10000) break;//防止死循环}memcpy( pDoc->m_pDib->m_lpImage,lpNewDIBBits, lLineBytes * lHeight);//displaylpSrc=(unsigned char*)pDoc->m_pDib->m_lpvColorTable;*(lpSrc+255*4+1)=0;*(lpSrc+255*4)=0;*(lpSrc+255*4+2)=255;pDoc->SetTitle("Edge Trace Image");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);EndWaitCursor();delete [] lpNewDIBBits;}void CImageProcessView::OnUpdateEdgeTrace(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;//if(m_bTwoValue) bAvail=false;pCmdUI->Enable(bAvail);}void CImageProcessView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags){// TODO: Add your message handler code here and/or call default//微调(+、- 1)处理窗口大小CImageProcessDoc* pDoc = GetDocument();switch(nChar){case VK_LEFT:if(pDoc->StartPoint.x--<=0)pDoc->StartPoint.x=0;break;case VK_RIGHT:if(pDoc->EndPoint.x++>=lWidth-1)pDoc->EndPoint.x=lWidth-1;break;case VK_UP:if(pDoc->StartPoint.y--<=0)pDoc->StartPoint.y=0;break;case VK_DOWN:if(pDoc->EndPoint.y++>=lHeight-1)pDoc->EndPoint.y=lHeight-1;break;}InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);CScrollView::OnKeyDown(nChar, nRepCnt, nFlags);}void CImageProcessView::OnSmoothTrun(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();//copy imgunsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL)return ;memcpy( lpNewDIBBits,pDoc->m_pDib->m_lpImage, lLineBytes * lHeight);const int M=13;//oddconst int N=15;//oddTrunMedianFilter(M,N);CString str=pDoc->GetTitle();DisplayNewImg(pDoc->m_pDib->m_lpImage,lLineBytes,lHeight,str+"--++截断中值滤波");//display orignal image//get img backpDoc->SetTitle(str);memcpy( pDoc->m_pDib->m_lpImage,lpNewDIBBits, lLineBytes * lHeight);InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);delete [] lpNewDIBBits;// 恢复光标EndWaitCursor();}void CImageProcessView::OnUpdateSmoothTrun(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;if(m_bTwoValue) bAvail=false;pCmdUI->Enable(bAvail);}void CImageProcessView::TrunMedianFilter(int M,int N){CImageProcessDoc* pDoc = GetDocument();unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){return ;}unsigned char*lpSrc;unsigned char*lpDst;lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);//unsigned char *v=new unsigned char[M*N];//[N*M];//line N Column M not rect (int err) vector<unsigned char> v(M*N,0);const int Th=(M*N)/2;//Mid Posfor (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpDst = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpSrc =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;if(i>=M/2 && i<lHeight-M/2 && j>=N/2 && j<lWidth-N/2){//Get M*N data to v[]int vSize=0;int aver=0;for(int m=-M/2;m<=M/2;m++)for(int n=-N/2;n<=N/2;n++){v[vSize]=*(lpSrc+lLineBytes*m+n);aver+=v[vSize];vSize++;}aver/=vSize;//sort v[]for(int m=0;m<M*N-1;m++)for(int n=m+1;n<M*N;n++){if(v[m]>v[n]){//swapBYTE tmp=v[m];v[m]=v[n];v[n]=tmp;}}//截断int lower=v[0];int upper=v[vSize-1];if(aver>v[Th])upper=2*v[Th]-lower;elselower=2*v[Th]-upper;int pos1=0;int pos2=vSize-1;while(lower>v[pos1])pos1++;while(upper<v[pos2])pos2--;//取中值*(lpDst)=(unsigned char)v[(pos1+pos2)/2];}}}// 释放内存delete []lpNewDIBBits;//delete []v;}void CImageProcessView::OnSmoothAnisotropicdiffusion(){// TODO: Add your command handler code hereCImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();//copy imgunsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL)return ;memcpy( lpNewDIBBits,pDoc->m_pDib->m_lpImage, lLineBytes * lHeight);AnisotropicDiffusion();CString str=pDoc->GetTitle();DisplayNewImg(pDoc->m_pDib->m_lpImage,lLineBytes,lHeight,str+"--++各向异性扩散滤波");//display orignal image//get img backpDoc->SetTitle(str);memcpy( pDoc->m_pDib->m_lpImage,lpNewDIBBits, lLineBytes * lHeight);InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);delete [] lpNewDIBBits;// 恢复光标EndWaitCursor();}void CImageProcessView::AnisotropicDiffusion(){CImageProcessDoc* pDoc = GetDocument();unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];if (lpNewDIBBits == NULL){return ;}unsigned char*lpSrc;unsigned char*lpDst;const int k=5;const float lamda=0.25f;for(int t=0;t<20;t++)//迭代{lpSrc=(unsigned char *)pDoc->m_pDib->m_lpImage;memcpy( lpNewDIBBits,lpSrc, lLineBytes * lHeight);for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpDst = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpSrc =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;if(i>=1 && i<lHeight-1 && j>=1 && j<lWidth-1){//获取变化float dN=(float)(*(lpSrc+lLineBytes)-*(lpSrc));float dS=(float)(*(lpSrc-lLineBytes)-*(lpSrc));float dE=(float)(*(lpSrc-1)-*(lpSrc));float dW=(float)(*(lpSrc+1)-*(lpSrc));/*int v=*(lpSrc)+(int)(lamda*(dN/(1+dN*dN/k/k)+dS/(1+dS*dS/k/k)+dE/(1+dE*dE/k/k)+dW/(1+dW*dW/k/k)));*/int v=*(lpSrc)+(int)(lamda*(dN*exp(-dN*dN/k/k)+dS*exp(-dS*dS/k/k)+dE*exp(-dE*dE/k/k)+dW*exp(-dW*dW/k/k)));if(v>255) v=255;else if(v<0) v=0;*lpDst=(BYTE)v;}}}}// 释放内存delete []lpNewDIBBits;}void CImageProcessView::OnUpdateSmoothAnisotropicdiffusion(CCmdUI *pCmdUI){// TODO: Add your command update UI handler code hereCImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;if(m_bTwoValue) bAvail=false;pCmdUI->Enable(bAvail);}void CImageProcessView::OnGrayReconstruction(){// TODO: Add your command handler code hereBeginWaitCursor();CImageProcessDoc* pDoc = GetDocument();CDemoTimer exeTimer;exeTimer.Reset();//1 2x20 Se//se = strel('disk', 20)const int M=39;const int N=39;////动态定义三维数组://int *** p3 ;//[ hight][ row][ col]//p3 = new int**[hight ] ;int **S;S =  new int * [M];//S[M][N]for (int i = 0; i < M; i++) {S[i] = new int[N] ;}for (int i = 0; i < M; i++) for (int j = 0; j < N; j++){ if((i-M/2)*(i-M/2)+(j-N/2)*(j-N/2)<=20*20)S[i][j]=0;elseS[i][j]=-1;}//掩膜图像 原图:(lpNewDIBBits)unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];_ASSERT(lpNewDIBBits != NULL);//falsememcpy( lpNewDIBBits,pDoc->m_pDib->m_lpImage, lLineBytes * lHeight);//GrayErosion(S,M,N);//7s 578 msGrayFastOperate(false);TRACE("\nUsed Time is %.3f ms\n",exeTimer.GetTime(false)*1000);////标记图像 腐蚀 :pDoc->m_pDib->m_lpImageReConstruction(pDoc->m_pDib->m_lpImage,lpNewDIBBits);TRACE("\nUsed Time is %.3f ms\n",exeTimer.GetTime(false)*1000);memcpy( lpNewDIBBits,pDoc->m_pDib->m_lpImage, lLineBytes * lHeight);//掩膜图像:(lpNewDIBBits)////GrayDilation(S,M,N);GrayFastOperate(true);//标记图像 膨胀运算pDoc->m_pDib->m_lpImageunsigned char*lpSrc;unsigned char*lpDst;// 掩膜图像\标记图像 取反for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpDst = pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpSrc =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;*(lpSrc)=255-(*lpSrc);*(lpDst)=255-(*lpDst);}}//重构ReConstruction(pDoc->m_pDib->m_lpImage,lpNewDIBBits);// 重构图像 取反for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpDst = pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpDst++;*(lpDst)=255-(*lpDst);}}TRACE("\nUsed Time is %.3f ms\n",exeTimer.GetTime(false)*1000);CString str=pDoc->GetTitle();pDoc->SetTitle(str+"重构");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);for(int i=0;i<M;i++)delete []S[i];delete []S;// 释放内存delete []lpNewDIBBits;// 恢复光标EndWaitCursor();}void CImageProcessView::GrayFastOperate(bool bDilate){CImageProcessDoc* pDoc = GetDocument();unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];_ASSERT(lpNewDIBBits != NULL);//falsememcpy( lpNewDIBBits,pDoc->m_pDib->m_lpImage, lLineBytes * lHeight);//结构分解://seq = getsequence(se)unsigned char*lpSrc;unsigned char*lpDst;//1)int M=15;int N=15;//腐蚀运算,定义域内输入数据减对应模板数据,并求最小值,该最小值便是该点输出for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpDst = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpSrc =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;int gray=*lpSrc;//for (int m = 0; m < M; m++)int m=M/2;{for (int n = 0; n < N; n++){  // if(S[m][n]<0) continue;if(i-M/2 + m>=0 && i-M/2 +m<lHeight && j+n - N/2>=0 && j+n - N/2<lWidth){int tmp=*(lpSrc + lLineBytes*(M/2 - m)  +(n - N/2));//-S[m][n];if(bDilate){if(tmp>gray) gray=tmp;}//maxelse{if(tmp<gray) gray=tmp;}//min}}}*lpDst=(BYTE)gray;}}//2)M=11;N=11;//腐蚀运算,定义域内输入数据减对应模板数据,并求最小值,该最小值便是该点输出for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpDst = lpNewDIBBits +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpSrc =(unsigned char *)pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;int gray=*lpSrc;for (int m = 0; m < M; m++){//for (int n = 0; n < N; n++)int n=m;{  // if(S[m][n]<0) continue;if(i-M/2 + m>=0 && i-M/2 +m<lHeight && j+n - N/2>=0 && j+n - N/2<lWidth){int tmp=*(lpSrc + lLineBytes*(M/2 - m)  +(n - N/2));//-S[m][n];if(bDilate){if(tmp>gray) gray=tmp;}//maxelse{if(tmp<gray) gray=tmp;}//min}}}*lpDst=(BYTE)gray;}}//3M=15;N=15;//腐蚀运算,定义域内输入数据减对应模板数据,并求最小值,该最小值便是该点输出for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpDst = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpSrc =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;int gray=*lpSrc;for (int m = 0; m < M; m++){//for (int n = 0; n < N; n++)int n=m/2;{   //if(S[m][n]<0) continue;if(i-M/2 + m>=0 && i-M/2 +m<lHeight && j+n - N/2>=0 && j+n - N/2<lWidth){int tmp=*(lpSrc + lLineBytes*(M/2 - m)  +(n - N/2));//-S[m][n];if(bDilate){if(tmp>gray) gray=tmp;}//maxelse{if(tmp<gray) gray=tmp;}//min}}}*lpDst=(BYTE)gray;}}//4)M=11;N=11;//腐蚀运算,定义域内输入数据减对应模板数据,并求最小值,该最小值便是该点输出for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpDst = lpNewDIBBits +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpSrc =(unsigned char *)pDoc->m_pDib->m_lpImage + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;int gray=*lpSrc;for (int m = 0; m < M; m++){//for (int n = 0; n < N; n++)int n=N-1-m;{  // if(S[m][n]<0) continue;if(i-M/2 + m>=0 && i-M/2 +m<lHeight && j+n - N/2>=0 && j+n - N/2<lWidth){int tmp=*(lpSrc + lLineBytes*(M/2 - m)  +(n - N/2));//-S[m][n];if(bDilate){if(tmp>gray) gray=tmp;}//maxelse{if(tmp<gray) gray=tmp;}//min}}}*lpDst=(BYTE)gray;}}//5M=5;N=5;//腐蚀运算,定义域内输入数据减对应模板数据,并求最小值,该最小值便是该点输出for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpDst = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpSrc =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;int gray=*lpSrc;for (int m = 0; m < M; m++){//for (int n = 0; n < N; n++)int n=m/2;{   //if(S[m][n]<0) continue;if(i-M/2 + m>=0 && i-M/2 +m<lHeight && j+n - N/2>=0 && j+n - N/2<lWidth){int tmp=*(lpSrc + lLineBytes*(M/2 - m)  +(n - N/2));//-S[m][n];if(bDilate){if(tmp>gray) gray=tmp;}//maxelse{if(tmp<gray) gray=tmp;}//min}}}*lpDst=(BYTE)gray;}}//6M=5;N=5;//腐蚀运算,定义域内输入数据减对应模板数据,并求最小值,该最小值便是该点输出for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpDst = (unsigned char *)pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpSrc =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;int gray=*lpSrc;//for (int m = 0; m < M; m++)int m=M/2;{for (int n = 0; n < N; n++){  // if(S[m][n]<0) continue;if(i-M/2 + m>=0 && i-M/2 +m<lHeight && j+n - N/2>=0 && j+n - N/2<lWidth){int tmp=*(lpSrc + lLineBytes*(M/2 - m)  +(n - N/2));//-S[m][n];if(bDilate){if(tmp>gray) gray=tmp;}//maxelse{if(tmp<gray) gray=tmp;}//min}}}*lpDst=(BYTE)gray;}}// 释放内存delete []lpNewDIBBits;}void CImageProcessView::ReConstruction(unsigned char* lpLevel,unsigned char* lpMasked){//CImageProcessDoc* pDoc = GetDocument();unsigned char*lpSrc;unsigned char*lpDst;unsigned char*lpMask;unsigned char*lpNewDIBBits;lpNewDIBBits=new unsigned char [lLineBytes*lHeight];_ASSERT(lpNewDIBBits != NULL);//falseunsigned char*lpNewDIBBits1;lpNewDIBBits1=new unsigned char [lLineBytes*lHeight];_ASSERT(lpNewDIBBits1 != NULL);//falsememcpy(lpNewDIBBits, lpLevel, lLineBytes * lHeight);memcpy(lpNewDIBBits1, lpLevel, lLineBytes * lHeight);bool bChg=true;int num=0;while(bChg){num++;bChg=false;//memcpy( lpLevel,lpNewDIBBits, lLineBytes * lHeight);////水平膨胀运算for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){lpSrc = lpLevel +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x;lpDst =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x;for (int j =pDoc->StartPoint.x+1; j <=pDoc->EndPoint.x-1; j ++){lpSrc++;lpDst++;*lpDst=max(*lpSrc,max(*(lpSrc+1),*(lpSrc-1)));;}}////垂直膨胀运算for (int i = pDoc->StartPoint.y+1; i <=pDoc->EndPoint.y-1; i ++){lpDst = lpNewDIBBits1 +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;lpSrc =lpNewDIBBits + lLineBytes * (lHeight - 1 - i)+ pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;lpDst++;*lpDst=max(*lpSrc,max(*(lpSrc+lLineBytes),*(lpSrc-lLineBytes)));}}//比较运算for (int i = pDoc->StartPoint.y+1; i <=pDoc->EndPoint.y-1; i ++){lpSrc = lpLevel +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x;lpMask= lpMasked+  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x;lpDst =lpNewDIBBits1 +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x;for (int j =pDoc->StartPoint.x+1; j <=pDoc->EndPoint.x-1; j ++){lpDst++;lpMask++;lpSrc++;if(*lpDst>*lpMask)*lpDst=*lpMask;if((*lpDst)!=(*lpSrc)){bChg=true;*lpSrc=*lpDst;}}}}TRACE("\nnum=%d\n",num);memcpy( pDoc->m_pDib->m_lpImage,lpLevel, lLineBytes * lHeight);// 释放内存delete []lpNewDIBBits;delete []lpNewDIBBits1;}void CImageProcessView::OnEdgeRelaxation(){// TODO: 在此添加命令处理程序代码CImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();CPoint* pEdgeInfo;//i | j      // i - jpEdgeInfo=new CPoint [lLineBytes*lHeight];_ASSERT(pEdgeInfo != NULL);//falseCPoint* pEdgeInfo1;//i | j      // i // - // jpEdgeInfo1=new CPoint [lLineBytes*lHeight];_ASSERT(pEdgeInfo1 != NULL);//false//1 init  c(e)=0---100int eMax=200;for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){unsigned char* lpSrc = pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;CPoint * pEdge =pEdgeInfo +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;pEdge++;if(i==pDoc->EndPoint.y || j==pDoc->EndPoint.x)*pEdge=CPoint(0,0);else{(*pEdge)=CPoint(abs(*lpSrc-*(lpSrc+1)),abs(*lpSrc-*(lpSrc-lLineBytes)));if((*pEdge).x>eMax)eMax=(*pEdge).x;if((*pEdge).y>eMax)eMax=(*pEdge).y;}}}//for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){CPoint * pEdge =pEdgeInfo +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){pEdge++;(*pEdge).x=min(90,(*pEdge).x*200/eMax);(*pEdge).y=min(90,(*pEdge).y*200/eMax);if((*pEdge).x<10)// && (*pEdge).x>5)//q=10 not type err!(*pEdge).x=0;if((*pEdge).y<10)// && (*pEdge).y>5)(*pEdge).y=0;}}//2迭代numconst int num=100;int no=0;const int q=10;const int delt=20;int type[4];bool bOver=false;while(no<num && !bOver){no++;bOver=true;memcpy(pEdgeInfo1,pEdgeInfo,lLineBytes*lHeight*sizeof(CPoint));for (int i = pDoc->StartPoint.y+1; i <=pDoc->EndPoint.y-1; i ++){CPoint * pEdge1 =pEdgeInfo1 +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x;CPoint * pEdge =pEdgeInfo +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x;for (int j =pDoc->StartPoint.x+1; j <=pDoc->EndPoint.x-1; j ++){pEdge1++;pEdge++;int a=(*(pEdge1-1)).x;int b=(*(pEdge1-1)).y;int c=(*(pEdge1-lLineBytes-1)).x;//sortif(a<b) Swap(&a,&b);if(a<c)Swap(&a,&c);if(b<c)Swap(&b,&c);int m=max(q,a);int Snode=0;type[0]=(m-a)*(m-b)*(m-c);type[1]=a*(m-b)*(m-c);type[2]=a*b*(m-c);type[3]=a*b*c;int maxT=type[0];for(int k=1;k<4;k++){if(maxT<type[k]){Snode=k;maxT=type[k];}}int d=(*(pEdge1)).x;int g=(*(pEdge1+1)).y;int f=(*(pEdge1-lLineBytes)).x;//sortif(d<g) Swap(&d,&g);if(d<f)Swap(&d,&f);if(g<f)Swap(&g,&f);m=max(q,d);type[0]=(m-d)*(m-g)*(m-f);type[1]=d*(m-g)*(m-f);type[2]=d*g*(m-f);type[3]=d*g*f;int Enode=0;maxT=type[0];for(int k=1;k<4;k++){if(maxT<type[k]){Enode=k;maxT=type[k];}}if((Snode==0 && Enode!=1) || (Snode!=1 && Enode==0))//-{(*pEdge).y=max((*pEdge).y-delt,0);bOver=false;}if((Snode==1 && Enode==1))//+{(*pEdge).y=min((*pEdge).y+delt,100);bOver=false;}elseif((Snode==1 && Enode!=0) || (Snode!=0 && Enode==1))//+{(*pEdge).y=min((*pEdge).y+delt/2,100);bOver=false;}a=(*(pEdge1+lLineBytes)).x;b=(*(pEdge1+lLineBytes)).y;c=(*(pEdge1+lLineBytes+1)).y;//sortif(a<b) Swap(&a,&b);if(a<c)Swap(&a,&c);if(b<c)Swap(&b,&c);m=max(q,a);type[0]=(m-a)*(m-b)*(m-c);type[1]=a*(m-b)*(m-c);type[2]=a*b*(m-c);type[3]=a*b*c;Snode=0;maxT=type[0];for(int k=1;k<4;k++){if(maxT<type[k]){Snode=k;maxT=type[k];}}d=(*(pEdge1)).y;g=(*(pEdge1+1)).y;f=(*(pEdge1-lLineBytes)).x;//sortif(d<g) Swap(&d,&g);if(d<f)Swap(&d,&f);if(g<f)Swap(&g,&f);m=max(q,d);type[0]=(m-d)*(m-g)*(m-f);type[1]=d*(m-g)*(m-f);type[2]=d*g*(m-f);type[3]=d*g*f;Enode=0;maxT=type[0];for(int k=1;k<4;k++){if(maxT<type[k]){Enode=k;maxT=type[k];}}if((Snode==0 && Enode!=1) || (Snode!=1 && Enode==0))//-{(*pEdge).x=max((*pEdge).x-delt,0);bOver=false;}if((Snode==1 && Enode==1))//+{(*pEdge).x=min((*pEdge).x+delt,100);bOver=false;}elseif((Snode==1 && Enode!=0) || (Snode!=0 && Enode==1))//+{(*pEdge).x=min((*pEdge).x+delt/2,100);bOver=false;}}}}TRACE("\n\n run: %d\n\n",no);//3输出结果for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y-1; i ++){unsigned char* lpSrc = pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;CPoint * pEdge =pEdgeInfo +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x-1; j ++){lpSrc++;pEdge++;*lpSrc=0;//max((*pEdge).x,(*pEdge).y);if((*pEdge).x>80){*lpSrc=255;}}}DisplayNewImg(pDoc->m_pDib->m_lpImage,lLineBytes,lHeight,"垂直边缘松弛");for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y-1; i ++){unsigned char* lpSrc = pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;CPoint * pEdge =pEdgeInfo +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x-1; j ++){lpSrc++;pEdge++;*lpSrc=0;//max((*pEdge).x,(*pEdge).y);if((*pEdge).y>80){*lpSrc=255;}}}DisplayNewImg(pDoc->m_pDib->m_lpImage,lLineBytes,lHeight,"水平边缘松弛");for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y-1; i ++){unsigned char* lpSrc = pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;CPoint * pEdge =pEdgeInfo +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x-1; j ++){lpSrc++;pEdge++;*lpSrc=0;//max((*pEdge).x,(*pEdge).y);if((*pEdge).x>80 && (*pEdge).y<80){*lpSrc=255;}if((*pEdge).x<80 && (*pEdge).y>80){*lpSrc=255;}}}pDoc->SetTitle("边缘松弛");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);// 恢复光标EndWaitCursor();delete[]pEdgeInfo;delete[]pEdgeInfo1;}void CImageProcessView::OnUpdateEdgeRelaxation(CCmdUI *pCmdUI){// TODO: 在此添加命令更新用户界面处理程序代码CImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::Swap(int* a, int* b){int tmp=*a;*a=*b;*b=tmp;}void CImageProcessView::OnSegmentationBoundarytrace(){// TODO: 在此添加命令处理程序代码CImageProcessDoc* pDoc = GetDocument();BeginWaitCursor();int* pCost;//i | j      // i - jpCost=new int [lLineBytes*lHeight];_ASSERT(pCost != NULL);//falsememset(pCost,0,lLineBytes*lHeight*sizeof(int));//get costfor (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){unsigned char* lpSrc = pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pDoc->StartPoint.x-1;int* pC =pCost +  lLineBytes*i + pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;pC++;*lpSrc=min(*lpSrc,254);//for diaplyif(i == pDoc->StartPoint.y){*pC=*lpSrc;}else{if(j == pDoc->StartPoint.x)*pC=*lpSrc+min(*(pC-lLineBytes),*(pC-lLineBytes+1));elseif(j == pDoc->EndPoint.x)*pC=*lpSrc+min(*(pC-lLineBytes),*(pC-lLineBytes-1));else*pC=*lpSrc+min(*(pC-lLineBytes),min(*(pC-lLineBytes-1),*(pC-lLineBytes+1)));}}}//get min pathvector<int> path;int pos=pDoc->StartPoint.x+1;int min=*(pCost +  lLineBytes*pDoc->EndPoint.y + pDoc->StartPoint.x+1);for (int j =pDoc->StartPoint.x+1; j <=pDoc->EndPoint.x-1; j ++){int* pC =pCost +  lLineBytes*pDoc->EndPoint.y + j;if(*pC<min){min=*pC;pos=j;}//TRACE("\t%d",*pC);}path.push_back(pos);for (int i =pDoc->EndPoint.y-1 ; i >=pDoc->StartPoint.y; i --){int* pC =pCost +  lLineBytes*i + pos;if(*(pC-1)<min(*(pC),*(pC+1)))pos--;if(*(pC+1)<min(*(pC),*(pC-1)))pos++;path.push_back(pos);}//displayunsigned char* lpSrc;for (int i =pDoc->EndPoint.y ; i >=pDoc->StartPoint.y; i --){int pos=path[pDoc->EndPoint.y-i];lpSrc = pDoc->m_pDib->m_lpImage +  lLineBytes* (lHeight-1-i) + pos;*lpSrc=255;}lpSrc=(unsigned char*)pDoc->m_pDib->m_lpvColorTable;*(lpSrc+255*4+1)=0;*(lpSrc+255*4)=0;*(lpSrc+255*4+2)=255;pDoc->SetTitle("边界跟踪(最小路径)");InvalidateRect(CRect(pDoc->StartPoint.x,pDoc->StartPoint.y,pDoc->EndPoint.x,pDoc->EndPoint.y),true);// 恢复光标EndWaitCursor();delete[]pCost;}void CImageProcessView::OnUpdateSegmentationBoundarytrace(CCmdUI *pCmdUI){// TODO: 在此添加命令更新用户界面处理程序代码CImageProcessDoc* pDoc = GetDocument();BOOL bAvail=false;if(pDoc->m_pDib->m_lpBMIH!=NULL)if(pDoc->m_pDib->m_lpBMIH->biBitCount==8)bAvail=true;pCmdUI->Enable(bAvail);}void CImageProcessView::OnFileOpenavi(){//// TODO: 在此添加命令处理程序代码TCHAR szFilters[]= _T("AVI Files (*.avi)|*.avi|");// Create an Open dialog; the default file name extension is ".my".CFileDialog fileDlg(TRUE, _T("avi"), _T("*.avi"),OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, szFilters);// Display the file dialog. When user clicks OK, fileDlg.DoModal() // returns IDOK.if(fileDlg.DoModal() == IDOK){if(fileDlg.GetFileExt()=="avi"){m_AviName=fileDlg.GetPathName();if(!LoadAvi())SetTimer(TIMER_AVI,60,NULL);}}}int CImageProcessView::LoadAvi(void){CImageProcessDoc* pDoc = GetDocument();//load aviAVIFileInit(); PAVIFILE avi;if(AVIFileOpen(&avi,m_AviName,OF_READ,NULL)!=AVIERR_OK)return 1;AVIFILEINFO avi_info;AVIFileInfo(avi, &avi_info, sizeof(AVIFILEINFO));if(avi_info.dwSuggestedBufferSize<avi_info.dwHeight*avi_info.dwWidth){MessageBox("Avi 视频压缩,需要先解压!退出");       return 1;}if(AVIFileGetStream(avi, &m_pAviStream, streamtypeVIDEO ,0 /*first stream*/)!=AVIERR_OK)return 1;int iFirstFrame;iFirstFrame=AVIStreamStart(m_pAviStream);if (iFirstFrame==-1){//Error getteing the frame inside the streamif (m_pAviStream!=NULL)AVIStreamRelease(m_pAviStream);AVIFileExit();return 1;}m_AviNumFrames=AVIStreamLength(m_pAviStream);//512if (m_AviNumFrames==-1){//Error getteing the number of frames inside the streamif (m_pAviStream!=NULL)AVIStreamRelease(m_pAviStream);AVIFileExit();return 1;}lHeight=avi_info.dwHeight;lWidth=avi_info.dwWidth;pDoc->StartPoint=CPoint(0,0);pDoc->EndPoint=CPoint(lWidth-1,lHeight-1);lLineBytes=(lWidth+3)/4*4;if(pDoc->m_pDib)delete pDoc->m_pDib;pDoc->m_pDib =new CDib(CSize(lLineBytes,lHeight) ,8);memset(pDoc->m_pDib->m_lpImage,0,lLineBytes*lHeight);unsigned char* lpSrc=(unsigned char*)pDoc->m_pDib->m_lpvColorTable;for(int i=0;i<256;i++){*lpSrc=(unsigned char)i;lpSrc++;*lpSrc=(unsigned char)i;lpSrc++;*lpSrc=(unsigned char)i;lpSrc++;*lpSrc=0;lpSrc++;}m_AviIndex=0;pDoc->SetTitle(m_AviName);return 0;}void CImageProcessView::OnTimer(UINT_PTR nIDEvent){// TODO: 在此添加消息处理程序代码和/或调用默认值if(nIDEvent==TIMER_AVI){if(!GetAviNext())KillTimer(TIMER_AVI);Invalidate();}CScrollView::OnTimer(nIDEvent);}int CImageProcessView::GetAviNext(void){CImageProcessDoc* pDoc = GetDocument();m_pAviFrame=AVIStreamGetFrameOpen(m_pAviStream, NULL );AVIStreamGetFrame(m_pAviFrame, m_AviIndex); //BITMAPINFOHEADER bitmapH; //  buffer containing the BITMAPINFOHEADERlong int len=40;AVIStreamReadFormat(m_pAviStream,m_AviIndex,&bitmapH,&len);int lineBytes=bitmapH.biWidth*2;//16bitint height=bitmapH.biHeight;if(bitmapH.biBitCount==24)lineBytes=bitmapH.biWidth*3;//24bitif(m_AviIndex==0){if(m_AviBuff)delete [] m_AviBuff;//may be 2 times openm_AviBuff=new unsigned char [lineBytes*height];}AVIStreamRead(m_pAviStream,m_AviIndex,1, m_AviBuff,lineBytes*height,NULL,NULL);AVIStreamGetFrameClose(m_pAviFrame);m_AviIndex++;CString str;str.Format("Play Avi...%d/%d)",m_AviIndex,m_AviNumFrames);((CMainFrame*)AfxGetMainWnd())->m_wndStatusBar.SetPaneText(0,str);//获取数据图像for (int i = pDoc->StartPoint.y; i <=pDoc->EndPoint.y; i ++){unsigned char* lpSrc = pDoc->m_pDib->m_lpImage +  lLineBytes* i + pDoc->StartPoint.x-1;for (int j =pDoc->StartPoint.x; j <=pDoc->EndPoint.x; j ++){lpSrc++;if(bitmapH.biBitCount==24){*lpSrc=*(m_AviBuff+i*lineBytes+j*3);}if(bitmapH.biBitCount==16){*lpSrc=*(m_AviBuff+i*lineBytes+j*2)&0xf8;//*lpSrc=*(m_AviBuff+i*lineBytes+j*2+1)&0xf8;}if(bitmapH.biBitCount==8){*lpSrc=*(m_AviBuff+i*lineBytes+j);}}}//close the stream after finishing the taskif(m_AviIndex>=m_AviNumFrames){if (m_pAviStream!=NULL)AVIStreamRelease(m_pAviStream);AVIFileExit();if(m_AviBuff)delete [] m_AviBuff;m_AviBuff=NULL;return 0;}elsereturn 1;}void CImageProcessView::OnFileBmp2avi(){// TODO: 在此添加命令处理程序代码//CString strBmpDir="d:\\imageprocess\\bmpset";//CString szAviName="d:\\imageprocess\\bmpset.avi";CString strBmpDir="d:\\imageprocess\\jpgset";CString szAviName="d:\\imageprocess\\jpgset.avi";CFileFind finder;strBmpDir += _T("\\*.*");AVIFileInit();AVISTREAMINFO strhdr;PAVIFILE pfile=NULL;PAVISTREAM ps=NULL; int nFrames =0; HRESULT hr; BOOL bFind = finder.FindFile(strBmpDir);CImage LoadImg;while(bFind){bFind = finder.FindNextFile();if(!finder.IsDots() && !finder.IsDirectory()){CString pathName = finder.GetFilePath();if(!LoadImg.IsNull())LoadImg.Destroy();LoadImg.Load(pathName);if(!LoadImg.IsNull()){ BYTE *tmp_buf = NULL;if(nFrames ==0 ){AVIFileOpen(&pfile,szAviName,OF_WRITE | OF_CREATE,NULL);memset(&strhdr, 0, sizeof(strhdr));strhdr.fccType = streamtypeVIDEO;// stream typestrhdr.fccHandler = 0;strhdr.dwScale = 1;strhdr.dwRate = 15; // 15 fpsstrhdr.dwSuggestedBufferSize = LoadImg.GetWidth()*LoadImg.GetHeight()*3;//bmpInfoHdr.biSizeImage ;SetRect(&strhdr.rcFrame, 0, 0, LoadImg.GetWidth(),LoadImg.GetHeight());// And create the stream;hr = AVIFileCreateStream(pfile,&ps,&strhdr); // hr = AVIStreamSetFormat(ps,nFrames,&bmpInfoHdr,sizeof(bmpInfoHdr));}tmp_buf = new BYTE[ LoadImg.GetWidth()*LoadImg.GetHeight() * 3];byte* pRealData;pRealData=(byte*)LoadImg.GetBits();int pit=LoadImg.GetPitch();//-line:-1056for (int y=0; y<LoadImg.GetHeight(); y++) for (int x=0; x<LoadImg.GetWidth(); x++){if(LoadImg.GetBPP()==24){*(tmp_buf -pit*(LoadImg.GetHeight()-1-y) +3*x)=*(pRealData + pit*y +3*x);;*(tmp_buf -pit*(LoadImg.GetHeight()-1-y) +3*x+1)=*(pRealData + pit*y +3*x+1);;*(tmp_buf -pit*(LoadImg.GetHeight()-1-y) +3*x+2)=*(pRealData + pit*y +3*x+2);;}if(LoadImg.GetBPP()==8){*(tmp_buf -3*pit*(LoadImg.GetHeight()-1-y) +3*x)=*(pRealData + pit*y +x);;*(tmp_buf -3*pit*(LoadImg.GetHeight()-1-y) +3*x+1)=*(pRealData + pit*y +x);;*(tmp_buf -3*pit*(LoadImg.GetHeight()-1-y) +3*x+2)=*(pRealData + pit*y +x);;}}CDib dib(CSize( LoadImg.GetWidth(),LoadImg.GetHeight()),24);//dib.m_lpBMIH->biXPelsPerMeter=4724;//dib.m_lpBMIH->biYPelsPerMeter=4724;for(int i=0;i<3;i++)//增加长度{hr = AVIStreamSetFormat(ps,nFrames,dib.m_lpBMIH,40); hr = AVIStreamWrite(ps, // stream pointernFrames , // time of this frame1, // number to write(LPBYTE) tmp_buf,LoadImg.GetWidth()*LoadImg.GetHeight()*3,//bmpInfoHdr.biSizeImage , // size of this frameAVIIF_KEYFRAME, // flags....NULL,NULL);nFrames ++; }delete []tmp_buf;}}}AVIStreamClose(ps);if(pfile != NULL)AVIFileRelease(pfile);AVIFileExit();}void CImageProcessView::OnRButtonDown(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值CImageProcessDoc* pDoc = GetDocument();//for testCDemoTimer exeTimer;exeTimer.Reset();/////////////////////////////////////////////////////////////////////TRACE("\nUsed Time is %.3f ms\n",exeTimer.GetTime(false)*1000);CScrollView::OnRButtonDown(nFlags, point);}

0 0
原创粉丝点击