opencv函数测试对话框

这个小工具是当年学习opencv249的时候写的,里面包含了很多各种各样的模块,学习用的,测试用的,调试用的,都有,源代码可能暂时不好公开,因为不知道里面是否包含了以前的项目代码,如果确实需要帮助可以联系我,我看能不能抽空提取出来。

 界面如下:

按钮源代码:

//author:autumoon
//联系QQ:4589968
//日期:2022-06-16


// OpenCVFunctionTestDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "OpenCVFunctionTest.h"
#include "OpenCVFunctionTestDlg.h"
#include "afxdialogex.h"
#include <math.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();

// 对话框数据
	enum { IDD = IDD_ABOUTBOX };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// COpenCVFunctionTestDlg 对话框




COpenCVFunctionTestDlg::COpenCVFunctionTestDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(COpenCVFunctionTestDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void COpenCVFunctionTestDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_PROGRESS_STATE, m_ProgressState);
}

BEGIN_MESSAGE_MAP(COpenCVFunctionTestDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON_Filter2D, &COpenCVFunctionTestDlg::OnBnClickedButtonFilter2d)
	ON_BN_CLICKED(IDC_BUTTON_TESTCLASS, &COpenCVFunctionTestDlg::OnBnClickedButtonTestclass)
	ON_BN_CLICKED(IDC_BUTTON_RESIZE, &COpenCVFunctionTestDlg::OnBnClickedButtonResize)
	ON_BN_CLICKED(IDC_BUTTON_ERODEDILATE, &COpenCVFunctionTestDlg::OnBnClickedButtonErodedilate)
	ON_BN_CLICKED(IDC_BUTTON_RENAMEFILES, &COpenCVFunctionTestDlg::OnBnClickedButtonRenamefiles)
	ON_BN_CLICKED(IDC_BUTTON_CALC_GLCM, &COpenCVFunctionTestDlg::OnBnClickedButtonCalcGlcm)
	ON_BN_CLICKED(IDC_BUTTON_MERGERECTS, &COpenCVFunctionTestDlg::OnBnClickedButtonMergerects)
	ON_BN_CLICKED(IDC_BUTTON_CANNY, &COpenCVFunctionTestDlg::OnBnClickedButtonCanny)
	ON_BN_CLICKED(IDC_BUTTON_BLUR, &COpenCVFunctionTestDlg::OnBnClickedButtonBlur)
	ON_BN_CLICKED(IDC_BUTTON_GABOR, &COpenCVFunctionTestDlg::OnBnClickedButtonGabor)
	ON_BN_CLICKED(IDC_BUTTON_GABORS, &COpenCVFunctionTestDlg::OnBnClickedButtonGabors)
	ON_BN_CLICKED(IDC_BUTTON_BIN, &COpenCVFunctionTestDlg::OnBnClickedButtonBin)
	ON_BN_CLICKED(IDC_BUTTON_GABOR2, &COpenCVFunctionTestDlg::OnBnClickedButtonGabor2)
	ON_BN_CLICKED(IDC_BUTTON_PCA, &COpenCVFunctionTestDlg::OnBnClickedButtonPca)
	ON_BN_CLICKED(IDC_BUTTON_AUTOCANNY, &COpenCVFunctionTestDlg::OnBnClickedButtonAutocanny)
	ON_BN_CLICKED(IDC_BUTTON_FLIP, &COpenCVFunctionTestDlg::OnBnClickedButtonFlip)
	ON_BN_CLICKED(IDC_BUTTON_WATERSHED, &COpenCVFunctionTestDlg::OnBnClickedButtonWatershed)
	ON_BN_CLICKED(IDC_BUTTON_KMEANS, &COpenCVFunctionTestDlg::OnBnClickedButtonKmeans)
	ON_BN_CLICKED(IDC_BUTTON_WATERSHED2, &COpenCVFunctionTestDlg::OnBnClickedButtonWatershed2)
	ON_BN_CLICKED(IDC_BUTTON_MEANSHIFT, &COpenCVFunctionTestDlg::OnBnClickedButtonMeanshift)
	ON_BN_CLICKED(IDC_BUTTON_HOUGH, &COpenCVFunctionTestDlg::OnBnClickedButtonHough)
	ON_BN_CLICKED(IDC_BUTTON_HOUGHC, &COpenCVFunctionTestDlg::OnBnClickedButtonHoughc)
	ON_BN_CLICKED(IDC_BUTTON_PICADD, &COpenCVFunctionTestDlg::OnBnClickedButtonPicadd)
	ON_BN_CLICKED(IDC_BUTTON_HIST, &COpenCVFunctionTestDlg::OnBnClickedButtonHist)
	ON_BN_CLICKED(IDC_BUTTON_HISTS, &COpenCVFunctionTestDlg::OnBnClickedButtonHists)
	ON_BN_CLICKED(IDC_BUTTON_BUILDDETECT, &COpenCVFunctionTestDlg::OnBnClickedButtonBuilddetect)
	ON_BN_CLICKED(IDC_BUTTON_SPIX, &COpenCVFunctionTestDlg::OnBnClickedButtonSpix)
	ON_BN_CLICKED(IDC_BUTTON_CONTOUR, &COpenCVFunctionTestDlg::OnBnClickedButtonContour)
	ON_BN_CLICKED(IDC_BUTTON_FIT, &COpenCVFunctionTestDlg::OnBnClickedButtonFit)
	ON_BN_CLICKED(IDC_BUTTON_FITLINE, &COpenCVFunctionTestDlg::OnBnClickedButtonFitline)
	ON_BN_CLICKED(IDC_BUTTON_FITCURVE, &COpenCVFunctionTestDlg::OnBnClickedButtonFitcurve)
	ON_BN_CLICKED(IDC_BUTTON_BILATERAL, &COpenCVFunctionTestDlg::OnBnClickedButtonBilateral)
	ON_BN_CLICKED(IDC_BUTTON_DIJKSTRA, &COpenCVFunctionTestDlg::OnBnClickedButtonDijkstra)
	ON_BN_CLICKED(IDC_BUTTON_SHORTESTPATH, &COpenCVFunctionTestDlg::OnBnClickedButtonShortestpath)
	ON_BN_CLICKED(IDC_BUTTON_CUTPIC, &COpenCVFunctionTestDlg::OnBnClickedButtonCutpic)
	ON_BN_CLICKED(IDC_BUTTON_OFFSETTFW, &COpenCVFunctionTestDlg::OnBnClickedButtonOffsettfw)
	ON_BN_CLICKED(IDC_BUTTON_ZOOMTFW, &COpenCVFunctionTestDlg::OnBnClickedButtonZoomtfw)
	ON_BN_CLICKED(IDC_BUTTON_WTOG, &COpenCVFunctionTestDlg::OnBnClickedButtonWtog)
	ON_BN_CLICKED(IDC_BUTTON_FILLPOLY, &COpenCVFunctionTestDlg::OnBnClickedButtonFillpoly)
	ON_BN_CLICKED(IDC_BUTTON_COPYMAT, &COpenCVFunctionTestDlg::OnBnClickedButtonCopymat)
	ON_BN_CLICKED(IDC_BUTTON_DISTINGUISH, &COpenCVFunctionTestDlg::OnBnClickedButtonDistinguish)
	ON_BN_CLICKED(IDC_BUTTON_SMOOTHBROKENLINE, &COpenCVFunctionTestDlg::OnBnClickedButtonSmoothbrokenline)
	ON_BN_CLICKED(IDC_BUTTON_RRLXPIXVALUE, &COpenCVFunctionTestDlg::OnBnClickedButtonRrlxpixvalue)
	ON_BN_CLICKED(IDC_BUTTON_MSER, &COpenCVFunctionTestDlg::OnBnClickedButtonMser)
	ON_BN_CLICKED(IDC_BUTTON_PERSPECT, &COpenCVFunctionTestDlg::OnBnClickedButtonPerspect)
	ON_BN_CLICKED(IDC_BUTTON_PIC_TRANS, &COpenCVFunctionTestDlg::OnBnClickedButtonPicTrans)
	ON_BN_CLICKED(IDC_BUTTON_FEATHER, &COpenCVFunctionTestDlg::OnBnClickedButtonFeather)
	ON_BN_CLICKED(IDC_BUTTON_SCROLL, &COpenCVFunctionTestDlg::OnBnClickedButtonScroll)
	ON_BN_CLICKED(IDC_BUTTON_GRADE, &COpenCVFunctionTestDlg::OnBnClickedButtonGrade)
	ON_BN_CLICKED(IDC_BUTTON_MERGEGRADE, &COpenCVFunctionTestDlg::OnBnClickedButtonMergegrade)
	ON_BN_CLICKED(IDC_BUTTON_TENEXPAND, &COpenCVFunctionTestDlg::OnBnClickedButtonTenexpand)
	ON_BN_CLICKED(IDC_BUTTON_FILLFEATHER, &COpenCVFunctionTestDlg::OnBnClickedButtonFillfeather)
	ON_BN_CLICKED(IDC_BUTTON_BGFILL, &COpenCVFunctionTestDlg::OnBnClickedButtonBgfill)
	ON_BN_CLICKED(IDC_BUTTON_ADDTIF, &COpenCVFunctionTestDlg::OnBnClickedButtonAddtif)
	ON_BN_CLICKED(IDC_BUTTON_MAT2TXT, &COpenCVFunctionTestDlg::OnBnClickedButtonMat2txt)
	ON_BN_CLICKED(IDC_BUTTON_FINDROAD, &COpenCVFunctionTestDlg::OnBnClickedButtonFindroad)
	ON_BN_CLICKED(IDC_BUTTON_POINTFEATHER, &COpenCVFunctionTestDlg::OnBnClickedButtonPointfeather)
	ON_BN_CLICKED(IDC_BUTTON_DRAWCONTOURS, &COpenCVFunctionTestDlg::OnBnClickedButtonDrawcontours)
	ON_BN_CLICKED(IDC_BUTTON_BIG_SHORTEST, &COpenCVFunctionTestDlg::OnBnClickedButtonBigShortest)
	ON_BN_CLICKED(IDC_BUTTON_PYRAMID, &COpenCVFunctionTestDlg::OnBnClickedButtonPyramid)
	ON_BN_CLICKED(IDC_BUTTON_CUBIC, &COpenCVFunctionTestDlg::OnBnClickedButtonCubic)
	ON_BN_CLICKED(IDC_BUTTON_OVERFLOW, &COpenCVFunctionTestDlg::OnBnClickedButtonOverflow)
	ON_BN_CLICKED(IDC_BUTTON_DRAWFILL, &COpenCVFunctionTestDlg::OnBnClickedButtonDrawfill)
	ON_BN_CLICKED(IDC_BUTTON_RECTBOUNDARY, &COpenCVFunctionTestDlg::OnBnClickedButtonRectboundary)
	ON_BN_CLICKED(IDC_BUTTON_SCALEMAT, &COpenCVFunctionTestDlg::OnBnClickedButtonScalemat)
	ON_BN_CLICKED(IDC_BUTTON_TIFSUB, &COpenCVFunctionTestDlg::OnBnClickedButtonTifsub)
	ON_BN_CLICKED(IDC_BUTTON_SURF, &COpenCVFunctionTestDlg::OnBnClickedButtonSurf)
	ON_BN_CLICKED(IDC_BUTTON_SURF2, &COpenCVFunctionTestDlg::OnBnClickedButtonSurf2)
	ON_BN_CLICKED(IDC_BUTTON_FLOODFILL, &COpenCVFunctionTestDlg::OnBnClickedButtonFloodfill)
	ON_BN_CLICKED(IDC_BUTTON_NEAREST, &COpenCVFunctionTestDlg::OnBnClickedButtonNearest)
END_MESSAGE_MAP()


// COpenCVFunctionTestDlg 消息处理程序

BOOL COpenCVFunctionTestDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 将“关于...”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码
	UINT array[5];
	for (int i = 0; i < 5; i++)
	{
		array[i] = 100 + i;
	}
	m_StatusBar.Create(this);
	m_StatusBar.SetIndicators(array, sizeof(array) / sizeof(UINT));
	CRect rect;
	GetClientRect(rect);
	for (int n = 0; n < 3; n++)
	{
		m_StatusBar.SetPaneInfo(n, array[n], 0, rect.Width() / 8);
	}
	m_StatusBar.SetPaneInfo(3, array[3], 0, rect.Width() * 3 / 8);
	m_StatusBar.SetPaneInfo(4, array[4], 0, rect.Width() / 8);
	//设置面版文字
	m_StatusBar.SetPaneText(0, _T("当前用户:"));
	m_StatusBar.SetPaneText(1, _T("autumoon"));
	m_StatusBar.SetPaneText(2, _T("总体进度:"));
	m_StatusBar.SetPaneText(4, _T(" Ready!"));
	RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0); //显示状态栏
	RECT m_rect;
	m_StatusBar.GetItemRect(3, &m_rect);
	m_ProgressState.SetParent(&m_StatusBar);
	m_ProgressState.MoveWindow(&m_rect);
	m_ProgressState.ShowWindow(SW_SHOW);
	m_ProgressState.SetRange(0, 100);
	m_ProgressState.SetPos(0);
	SetDlgItemText(IDC_EDIT_RESOLUTION, "0.6");

#ifdef _DEBUG
#endif // _DEBUG

	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

void COpenCVFunctionTestDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void COpenCVFunctionTestDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR COpenCVFunctionTestDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}



void COpenCVFunctionTestDlg::OnBnClickedButtonFilter2d()
{
	// TODO: 在此添加控件通知处理程序代码
	CString strPicPath = sdf.OpenSuffixFile(_T(".jpg"));

	if (strPicPath == CString())
	{
		return;
	}

	CCvImage ccv(strPicPath);
	//ccv.ShowImgAutoSize();

	cv::Mat MDst;
	cv::Mat mk = cv::Mat::ones(3,3,CV_32F);
	float k[9] = {1.0, -2.0, 1.0,   
		4.0, -2.0 , -1.0,  
		4.0, -2.0, 2.0};
	for (int i = 0; i < 3; ++i)
	{
		for (int j = 0; j < 3; ++j)
		{
			mk.at<float>(i,j) = k[i * 3 + j];
		}
	}
	cv::filter2D(ccv.m_Minput, MDst, CV_32F, mk);
	//ccv.ShowImgAutoSize(MDst, _T("opencv自带的卷积"));

	//测试SSE卷积
	cv::Mat Mdata=cv::Mat(MDst.rows,MDst.cols,CV_32F,cv::Scalar::all(0));
	ccv.m_Minput.convertTo(Mdata, CV_32F);
	//ccv.ShowImgAutoSize(Mdata, _T("浮点型"));

	CFilteringSSE fsse;
	fsse.ResizeTheMat(MDst.cols, MDst.rows, (float*)Mdata.data);
	fsse.MultiplySSE(k, (float*)Mdata.data, (((MDst.cols) + 3) / 4 * 4) * MDst.rows);
	ccv.ShowImgAutoSize(Mdata, _T("卷积SSE"));
}



void COpenCVFunctionTestDlg::OnBnClickedButtonTestclass()
{
	// TODO: 在此添加控件通知处理程序代码
	SendMessage(WM_CLOSE);
	//CTestClass tc;
	//tc.DoModal();
}


void COpenCVFunctionTestDlg::OnBnClickedButtonResize()
{
	// TODO: 在此添加控件通知处理程序代码
	CString strFilePath = sdf.OpenSuffixFile(".jpg");

	if (strFilePath == CString())
	{
		return;
	}

	CCvImage cvi(strFilePath);

	Mat Mnew;
	cv::resize(cvi.m_Minput, Mnew, cvSize(200, 150), 0, 0);

// 	IplImage IImg = Mnew;
// 	cvSmooth(&IImg, &IImg);

	cvi.ShowImgAutoSize(Mnew);

}

//全局变量声明
Mat g_srcImage, g_dstImage;
int g_nTrackbarNumer = 0;
int g_nStructElementSize = 3;

//-----------------------------【Process( )函数】------------------------------------
//	     描述:进行自定义的腐蚀和膨胀操作
//-----------------------------------------------------------------------------------------
void Process()
{
	//获取自定义核
	Mat element = getStructuringElement(MORPH_RECT, Size(2*g_nStructElementSize+1,2*g_nStructElementSize+1),
		Point( g_nStructElementSize, g_nStructElementSize ));

	//进行腐蚀或膨胀操作
	if(g_nTrackbarNumer== 0) 
	{   
		erode(g_srcImage,g_dstImage, element);
	}
	else if(g_nTrackbarNumer== 1)
	{
		//闭运算 先膨胀后腐蚀
		dilate(g_srcImage,g_dstImage, element);
		erode(g_dstImage,g_dstImage, element);
	}
	else
	{
		dilate(g_srcImage,g_dstImage, element);
	}

	//显示效果图
	imshow("Effect", g_dstImage);
	imwrite("Effect.tif", g_dstImage);
}

//-----------------------------【on_TrackbarNumChange( )函数】------------------------------------
//	     描述:腐蚀和膨胀之间切换开关的回调函数
//-----------------------------------------------------------------------------------------------------
void on_TrackbarNumChange(int, void *)
{
	//腐蚀和膨胀之间效果已经切换,回调函数体内需调用一次Process函数,使改变后的效果立即生效并显示出来
	Process();
}


//-----------------------------【on_ElementSizeChange( )函数】-------------------------------------
//	     描述:腐蚀和膨胀操作内核改变时的回调函数
//-----------------------------------------------------------------------------------------------------
void on_ElementSizeChange(int, void *)
{
	//内核尺寸已改变,回调函数体内需调用一次Process函数,使改变后的效果立即生效并显示出来
	Process();
}

void COpenCVFunctionTestDlg::OnBnClickedButtonErodedilate()
{
	// TODO: 在此添加控件通知处理程序代码
	CString strFilePath = sdf.OpenFile();

	//改变console字体颜色
	//system("color5E");
	g_srcImage = imread(sdf.CString2Char(strFilePath));

	if (!g_srcImage.data)
	{
		return;
	}

	namedWindow("Ori");
	imshow("Ori", g_srcImage);

	namedWindow("Effect");
	Process();
	Mat element = getStructuringElement(MORPH_RECT, Size(2*g_nStructElementSize + 1, 2 * g_nStructElementSize + 1),
		Point(g_nStructElementSize, g_nStructElementSize));
	createTrackbar("E/DE/D", "Effect", &g_nTrackbarNumer,2,on_TrackbarNumChange);
	createTrackbar("Element", "Effect", &g_nStructElementSize,21, on_ElementSizeChange);
}

void COpenCVFunctionTestDlg::OnBnClickedButtonRenamefiles()
{
	// TODO: 在此添加控件通知处理程序代码
	SendMessage(WM_CLOSE);
	CRenameFiles crf;
	crf.DoModal();
}


void COpenCVFunctionTestDlg::OnBnClickedButtonCalcGlcm()
{
	// TODO: Add your control notification handler code here
	CString strPicDir = sdf.BrowseDir("请选择图片文件夹");

	if (strPicDir.GetLength() > 0)
	{
		CStringArray arrFileInDir;
		sdf.ReadDirFiles(strPicDir, &arrFileInDir, ".jpg");
		sdf.ReadDirFiles(strPicDir, &arrFileInDir, ".png");

		for (int i = 0; i < arrFileInDir.GetCount(); ++i)
		{
			std::list<CString> lContent;
			Mat mSrc = imread(sdf.CString2Char(arrFileInDir[i]));
			Mat mGray;
			cv::cvtColor(mSrc, mGray, CV_RGB2GRAY);
			double featureVector[4];
			cvi.CalcGLCM(mGray, GLCM_ANGLE_VERTICAL, featureVector);
			lContent.push_back("熵:" + sdf.Float2Cstring(featureVector[0]) + '\n');
			lContent.push_back("能量:" + sdf.Float2Cstring(featureVector[1]) + '\n');
			lContent.push_back("对比度:" + sdf.Float2Cstring(featureVector[2]) + '\n');
			lContent.push_back("一致性:" + sdf.Float2Cstring(featureVector[3]) + '\n');

			sdf.SaveTXTFile(sdf.ReplaceSuffix(arrFileInDir[i], ".txt"), lContent);

			putText(mSrc,sdf.CString2Char("entropy:" + sdf.Float2Cstring(featureVector[0])),Point(0,30),FONT_HERSHEY_PLAIN, 1.0,Scalar(255,255,255),1);
			putText(mSrc,sdf.CString2Char("energy:" + sdf.Float2Cstring(featureVector[1])),Point(0,60),FONT_HERSHEY_PLAIN, 1.0,Scalar(255,255,255),1);
			putText(mSrc,sdf.CString2Char("contrast:" + sdf.Float2Cstring(featureVector[2])),Point(0,90),FONT_HERSHEY_PLAIN, 1.0,Scalar(255,255,255),1);
			putText(mSrc,sdf.CString2Char("homogenity:" + sdf.Float2Cstring(featureVector[3])),Point(0,120),FONT_HERSHEY_PLAIN, 1.0,Scalar(255,255,255),1);
			imwrite(sdf.CString2Char(sdf.ReplaceSuffix(arrFileInDir[i], ".bmp")), mSrc);
		}

		MessageBox("完成!", "提示", MB_ICONINFORMATION);
	}
}


void COpenCVFunctionTestDlg::OnBnClickedButtonMergerects()
{
	// TODO: Add your control notification handler code here
	cv::Mat mSrc = cv::Mat::zeros(cv::Size(800, 600), CV_8UC1);

	std::vector<std::vector<cv::Point>> vContours;

	vContours.push_back(GenerateRect(cv::Point(200, 0), 100, 100));
	for (int i = 0; i < vContours.size(); ++i)
	{
		cv::drawContours(mSrc, vContours, i, cv::Scalar(255), CV_FILLED);
	}


	//寻找轮廓
	Mat mCanny;
	std::vector<Vec4i> hierarchy;
	mSrc.copyTo(mCanny);
	std::vector <std::vector<Point>> vFindContours;
	findContours(mCanny, vFindContours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

	putText(mSrc,sdf.CString2Char("ConNum: " + sdf.Int2Cstring(vFindContours.size())),Point(0,30),FONT_HERSHEY_PLAIN, 1.0,Scalar(255,255,255),1);

	cv::imshow("Ori", mSrc);
	cv::waitKey();

}

std::vector<cv::Point> COpenCVFunctionTestDlg::GenerateRect( cv::Point pLeftUp, const int& nWidth, const int& nHeight )
{
	std::vector<cv::Point> vPts;
	vPts.push_back(cv::Point(pLeftUp.x, pLeftUp.y));
	vPts.push_back(cv::Point(pLeftUp.x + nWidth, pLeftUp.y));
	vPts.push_back(cv::Point(pLeftUp.x + nWidth, pLeftUp.y + nHeight));
	vPts.push_back(cv::Point(pLeftUp.x, pLeftUp.y + nHeight));

	return vPts;
}


int edgeThresh1 = 100;
int edgeThresh2 = 200;
// 声明 原始图片,灰度图片,和 canny边缘图片
Mat g_image, cedge;
Mat g_gray, edge;
bool bContour;

int ShowAllContours(const Mat& mSrc, const Mat& mCanny, std::vector<std::vector<cv::Point>>& contours)
{
	cv::Mat dst, canny_output;
	if (!mCanny.data)
	{
		return -1;
	}

	contours.clear();
	std::vector<Vec4i> hierarchy;

	if (mCanny.channels() == 3)
	{
		cvtColor(mCanny, canny_output, CV_RGB2GRAY);
	}
	else
	{
		mCanny.copyTo(canny_output);
	}
	
	findContours(canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
	//CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE

	RNG rng;
	Mat mCanvas = mSrc.clone();
	for (int i = 0; i < contours.size(); i++)
	{
		//随机颜色
		Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
		drawContours(mCanvas, contours, i, color, 2, 8, hierarchy, 0, Point());
	}

	//为了防止findContours函数的bug
	imshow("mCanvas", mCanvas);
	waitKey();

	return contours.size();
}

void onTrackbar(int, void*)
{

	//blur 灰度图片
	blur(g_gray, edge, Size(3,3));
	// Canny 边缘检测
	Canny(g_gray,edge, edgeThresh1, edgeThresh2, 3);

	//全部设为0
	cedge = Scalar::all(0);

	//拷贝边缘的象素点
	g_image.copyTo(cedge, edge);
	imshow("Edge map", cedge);

	if (bContour)
	{
		std::vector<std::vector<cv::Point>> contours;
		blur(cedge, cedge, Size(3, 3));
		ShowAllContours(g_image, cedge, contours);
	}
}

void COpenCVFunctionTestDlg::OnBnClickedButtonCanny()
{
	// TODO: Add your control notification handler code here
	//从文件中读入图像
	CString strFilePath = sdf.OpenFile();

	g_image = imread(sdf.CString2Char(strFilePath));
	//如果读入图像失败
	if(g_image.empty())
	{
		fprintf(stderr, "Can not load image\n");
		return;
	}
	// 生成灰度图片,因为只有灰度图片才能生成边缘图片
	cedge.create(g_image.size(), g_image.type());
	cvtColor(g_image,g_gray, CV_BGR2GRAY);
	//新建一个窗口
	namedWindow("Edge map", 1);
	// 生成一个进度条来控制边缘检测
	createTrackbar("Threshold1", "Edge map", &edgeThresh1, 800, onTrackbar);
	createTrackbar("Threshold2", "Edge map", &edgeThresh2, 800, onTrackbar);

	bContour = ((CButton*)GetDlgItem(IDC_CHECK_CONTOUR))->GetCheck();
	//初始化图像
	onTrackbar(0,0);
	//此函数等待按键,按键盘任意键就返回
	waitKey();

}

void BlurImage(int, void*)
{
	Mat mBlur = g_image.clone();
	blur(mBlur, mBlur, Size(edgeThresh1, edgeThresh1));
	imshow("Blur", mBlur);
}

void COpenCVFunctionTestDlg::OnBnClickedButtonBlur()
{
	// TODO: Add your control notification handler code here
	CString strFilePath = sdf.OpenFile();

	g_image = imread(sdf.CString2Char(strFilePath));
	edgeThresh1 = 3;
	cv::namedWindow("Blur");
	createTrackbar("Threshold1", "Blur", &edgeThresh1, 20, BlurImage);
	BlurImage(0, 0);
}


void COpenCVFunctionTestDlg::OnBnClickedButtonGabor()
{
	// TODO: Add your control notification handler code here
	//创建一个方向是PI/4而尺度是3的gabor

	double Sigma = 2*PI;

	double F = sqrt(2.0);

	CvGabor *gabor1 = new CvGabor; gabor1->Init(PI * 3 / 8, 3, Sigma, F);


	//获得实部并显示它

	IplImage *kernel = cvCreateImage( cvSize(gabor1->get_mask_width(), gabor1->get_mask_width()), IPL_DEPTH_8U, 1);

	kernel = gabor1->get_image(CV_GABOR_REAL);

	cvNamedWindow("Gabor Kernel", 1);

	cvShowImage("Gabor Kernel", kernel);

	cvWaitKey(10);

	//载入一个图像并显示
	CString strFilePath = sdf.OpenFile();

	IplImage *img = cvLoadImage(sdf.CString2Char(strFilePath), CV_LOAD_IMAGE_GRAYSCALE );

	cvNamedWindow("Original Image", 1);

	cvShowImage("Original Image", img);

	cvWaitKey(10);  


	//获取载入图像的gabor滤波响应的实部并且显示

	IplImage *reimg = cvCreateImage(cvSize(img->width,img->height), IPL_DEPTH_8U, 1);

	gabor1->conv_img(img, reimg, CV_GABOR_REAL);

	cvNamedWindow("Real Response", 1);

	cvShowImage("Real Response",reimg);

	cvWaitKey(10);

	cvDestroyWindow("Real Response");

	//获取载入图像的gabor滤波响应的虚部并且显示

	IplImage *reimg2 = cvCreateImage(cvSize(img->width,img->height), IPL_DEPTH_8U, 1);

	gabor1->conv_img(img, reimg2, CV_GABOR_IMAG);

	cvNamedWindow("Imaginary Response", 1);

	cvShowImage("Imaginary Response",reimg2);

	cvWaitKey(10);

	cvDestroyWindow("Imaginary Response");


	//获取载入图像的gabor滤波响应的模并且显示

	IplImage *reimg3 = cvCreateImage(cvSize(img->width,img->height), IPL_DEPTH_8U, 1);

	gabor1->conv_img(img, reimg3, CV_GABOR_MAG);

	cvNamedWindow("Magnitude Response", 1);

	cvShowImage("Magnitude Response",reimg3);

	cvWaitKey(0);

	cvDestroyWindow("Magnitude Response");
}


void COpenCVFunctionTestDlg::OnBnClickedButtonGabors()
{
	// TODO: Add your control notification handler code here

	double Sigma = 2*PI;

	double F = sqrt(2.0);

	CvGabor *gabor1[9];
	//载入一个图像并显示
	CString strFilePath = sdf.OpenFile();

	if (!strFilePath.GetLength())
	{
		return;
	}

	IplImage *img = cvLoadImage(sdf.CString2Char(strFilePath), CV_LOAD_IMAGE_GRAYSCALE );
	IplImage *reimg3 = cvCreateImage(cvSize(img->width,img->height), IPL_DEPTH_8U, 1);

	for (int i = 0; i < 9; ++i)
	{
		gabor1[i] = new CvGabor;
		gabor1[i]->Init(PI * i / 8, 3, Sigma, F);

		gabor1[i]->conv_img(img, reimg3, CV_GABOR_MAG);
		CString strSavePath = sdf.GetDirOfFile(strFilePath) + "\\" + sdf.GetNameOfFile(strFilePath, false) +
			sdf.Int2Cstring(i) + sdf.GetNameOfSuffix(strFilePath);
		cvSaveImage(sdf.CString2Char(strSavePath), reimg3);
		
	}
	cvReleaseImage(&reimg3);

	MessageBox("おわり!", "提示", MB_ICONINFORMATION);
}

cv::Mat mBinSrc;
int nBinThresh = 100;
void BinPic(int, void*)
{
	cv::Mat mBin = mBinSrc.clone();
	cv::threshold(mBin, mBin, nBinThresh, 255, THRESH_BINARY);
	imshow("Bin", mBin);
}

void COpenCVFunctionTestDlg::OnBnClickedButtonBin()
{
	// TODO: Add your control notification handler code here
	CString strPicPath = sdf.OpenFile();
	if (!strPicPath.GetLength())
	{
		return;
	}

	cv::namedWindow("Bin");

	mBinSrc = cv::imread(sdf.CString2Char(strPicPath), CV_LOAD_IMAGE_GRAYSCALE);
	cv::createTrackbar("阈值", "Bin", &nBinThresh, 255, BinPic);
	BinPic(0, 0);
	cv::waitKey();
}

cv::Mat mkKernel(int ks, double sig, double th, double lm, double ps)
{
	int hks = (ks-1)/2;
	double theta = th*CV_PI/180;
	double psi = ps*CV_PI/180;
	double del = 2.0/(ks-1);
	double lmbd = lm;
	double sigma = sig/ks;
	double x_theta;
	double y_theta;
	cv::Mat kernel(ks,ks, CV_32F);
	for (int y=-hks; y<=hks; y++)
	{
		for (int x=-hks; x<=hks; x++)
		{
			x_theta = x*del*cos(theta)+y*del*sin(theta);
			y_theta = -x*del*sin(theta)+y*del*cos(theta);
			kernel.at<float>(hks+y,hks+x) = (float)exp(-0.5*(pow(x_theta,2)+pow(y_theta,2))/pow(sigma,2))* cos(2*CV_PI*x_theta/lmbd + psi);
		}
	}
	return kernel;
}

int kernel_size=21;
int pos_sigma= 5;
int pos_lm = 50;
int pos_th = 0;
int pos_psi = 90;
cv::Mat src_f;
cv::Mat dest;

void Process(int , void *)
{
	double sig = pos_sigma;
	double lm = 0.5+pos_lm/100.0;
	double th = pos_th;
	double ps = pos_psi;
	cv::Mat kernel = mkKernel(kernel_size, sig, th, lm, ps);
	cv::filter2D(src_f, dest, CV_32F, kernel);
	cv::imshow("Process window", dest);
	cv::Mat Lkernel(kernel_size*20, kernel_size*20, CV_32F);
	cv::resize(kernel, Lkernel, Lkernel.size());
	Lkernel /= 2.;
	Lkernel += 0.5;
	cv::imshow("Kernel", Lkernel);
	cv::Mat mag;
	cv::pow(dest, 2.0, mag);
	cv::imshow("Mag", mag);
}

void COpenCVFunctionTestDlg::OnBnClickedButtonGabor2()
{
	// TODO: Add your control notification handler code here
	CString strFilePath = sdf.OpenFile();

	if (!strFilePath.GetLength())
	{
		return;
	}

	cv::Mat mImg = cv::imread(sdf.CString2Char(strFilePath),1);
	cv::imshow("Src", mImg);
	cv::Mat src;
	cv::cvtColor(mImg, src, CV_BGR2GRAY);
	src.convertTo(src_f, CV_32F, 1.0/255, 0);
	if (!kernel_size%2)
	{
		kernel_size+=1;
	}
	cv::namedWindow("Process window", 1);
	cv::createTrackbar("Sigma", "Process window", &pos_sigma, kernel_size, Process);
	cv::createTrackbar("Lambda", "Process window", &pos_lm, 100, Process);
	cv::createTrackbar("Theta", "Process window", &pos_th, 180, Process);
	cv::createTrackbar("Psi", "Process window", &pos_psi, 360, Process);
	Process(0,0);
	cv::waitKey(0);

	return;
}

#include "facedetect.h"
#include "gledcvClass.h"
void COpenCVFunctionTestDlg::OnBnClickedButtonPca()
{
	// TODO: Add your control notification handler code here
	//AllocConsole();//注意检查返回值
	//FaceDetect(NULL, NULL);


	for (int i = 1; i < 5; ++i)
	{
		char** argv = new char*[5];
		argv[1] = sdf.CString2Char(sdf.OpenFile()); //选择模板
		argv[2] = sdf.CString2Char(sdf.OpenFile()); //选择照片
		argv[3] = "30";
		argv[4] = "0.9";
		CGledcv gc(argv);
	}

	AfxMessageBox("おわり!");
}


void COpenCVFunctionTestDlg::OnBnClickedButtonAutocanny()
{
	// TODO: Add your control notification handler code here
	CString strFilePath = sdf.OpenFile();

	if (strFilePath.GetLength())
	{
		cv::Mat mSrc = imread(sdf.CString2Char(strFilePath), CV_LOAD_IMAGE_GRAYSCALE);
		cv::Mat mDst;

		//预处理很重要
		erode(mSrc, mDst, Mat(5, 5, CV_8U), Point(-1, -1), 3);
		dilate(mDst, mDst, Mat(5, 5, CV_8U), Point(-1, -1), 3);

		adaptiveThreshold(mDst, mDst, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, 3, 5);
		cvi.ShowImgAutoSize(mDst, "自动阈值", 1920, 1080, false);
		cv::waitKey();
	}
}


void COpenCVFunctionTestDlg::OnBnClickedButtonFlip()
{
	// TODO: Add your control notification handler code here
	CString strFilePath = sdf.OpenFile();

	if (strFilePath.GetLength())
	{
		cv::Mat mSrc = imread(sdf.CString2Char(strFilePath));
		cv::Mat mDst;

		cv::flip(mSrc, mDst, 0);
		cvi.ShowImgAutoSize(mSrc, "mSrc", 1920, 1080, false);
		cvi.ShowImgAutoSize(mDst, "mDst", 1920, 1080, false);
		cv::waitKey();
	}
}


void COpenCVFunctionTestDlg::OnBnClickedButtonWatershed()
{
	// TODO: Add your control notification handler code here
	CString strFilePath = sdf.OpenFile();

	if (strFilePath.GetLength())
	{
		WaterShed(sdf.CString2Char(strFilePath));
	}
}


void COpenCVFunctionTestDlg::OnBnClickedButtonWatershed2()
{
	// TODO: Add your control notification handler code here
	CString strFilePath = sdf.OpenFile();

	if (strFilePath.GetLength())
	{
		CString strFilePathBin = sdf.OpenFile();
		CString strFilePathTower = sdf.OpenFile();

		Segment(sdf.CString2Char(strFilePath), sdf.CString2Char(strFilePathBin), sdf.CString2Char(strFilePathTower));
	}
}

void COpenCVFunctionTestDlg::OnBnClickedButtonKmeans()
{
	// TODO: Add your control notification handler code here
	CString strFilePath = sdf.OpenFile();

	if (strFilePath.GetLength())
	{
		KMeans(sdf.CString2Char(strFilePath));
	}
}

void COpenCVFunctionTestDlg::OnBnClickedButtonMeanshift()
{
	// TODO: Add your control notification handler code here
	CString strFilePath = sdf.OpenFile();

	if (strFilePath.GetLength())
	{
		MeanShift(sdf.CString2Char(strFilePath));
	}
}

void COpenCVFunctionTestDlg::OnBnClickedButtonHough()
{
	// TODO: Add your control notification handler code here
	CString strFilePath = sdf.OpenFile();

	BOOL bCannyInput  = ((CButton*)(GetDlgItem(IDC_CHECK_CANNYINPUT)))->GetCheck();

	if (strFilePath.GetLength())
	{
		cv::Mat mSrc = imread(sdf.CString2Char(strFilePath));
		cv::Mat mHough;
 		cv::cvtColor(mSrc, mHough, CV_RGB2GRAY);

		if (!bCannyInput)
		{
			cv::erode(mHough, mHough, Mat(5, 5, CV_8U), Point(-1, -1));
			cv::dilate(mHough,  mHough, Mat(5, 5, CV_8U), Point(-1, -1));
			cv::blur(mHough, mHough, cv::Size(3, 3));
			cv::adaptiveThreshold(mHough, mHough, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, 3, 5);
		}

		cv::blur(mHough, mHough, cv::Size(2, 2));
		//cv::dilate(mHough,  mHough, Mat(5, 5, CV_8U), Point(-1, -1));
		//cv::erode(mHough, mHough, Mat(5, 5, CV_8U), Point(-1, -1));

		imshow("mHough", mHough);
		waitKey();

		std::vector<Vec4i> lines;
		HoughLinesP(mHough, lines, 1, CV_PI / 180, 40, 30, 3);
		RNG rng;
		for (int i = 0; i < lines.size(); ++i)
		{
			Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
			cv::line(mSrc, cv::Point(lines[i].val[0], lines[i].val[1]), cv::Point(lines[i].val[2], lines[i].val[3]), color, 2);
		}

		if (mSrc.cols > 1920 || mSrc.rows > 1080)
		{
			imwrite(sdf.CString2Char(sdf.ReplaceSuffix(strFilePath, "h.jpg")), mSrc);
			MessageBox("图片太大,结果已经保存为:\n" + sdf.ReplaceSuffix(strFilePath, "h.jpg"), "提示", MB_ICONINFORMATION);
		}
		else
		{
			imshow("霍夫变换", mSrc);
			waitKey();
		}
	}
}


#include "HoughTransP.h"
void COpenCVFunctionTestDlg::OnBnClickedButtonHoughc()
{
	// TODO: Add your control notification handler code here
	CString strFilePath = sdf.OpenFile();

	if (strFilePath.GetLength())
	{
		IplImage* pImage = cvLoadImage(strFilePath);
		IplImage* pGray = cvCreateImage(cvGetSize(pImage), IPL_DEPTH_8U, 1);
		IplImage* pCanvas = cvCloneImage(pImage);
// 		cvCvtColor(pImage, pGray, CV_RGB2GRAY);
// 		cvErode(pGray, pGray);
// 		cvDilate(pGray, pGray);
// 		cvSmooth(pGray, pGray);
// 		cvAdaptiveThreshold(pGray, pGray, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV);
// 		cvSmooth(pGray, pGray);

		cv::Mat mSrc = pImage;
		cv::Mat mHough;
		cv::cvtColor(mSrc, mHough, CV_RGB2GRAY);
		cv::erode(mHough, mHough, Mat(5, 5, CV_8U), Point(-1, -1));
		cv::dilate(mHough,  mHough, Mat(5, 5, CV_8U), Point(-1, -1));
		cv::blur(mHough, mHough, cv::Size(3, 3));
		cv::adaptiveThreshold(mHough, mHough, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, 3, 5);
		cv::blur(mHough, mHough, cv::Size(2, 2));

		IplImage GrayImg = mHough;
		cvShowImage("canny", &GrayImg);

		int nMaxLines = 100;
		int nLines;
		int* result = HoughTransP(&GrayImg, 40, 15, 2, nMaxLines, &nLines);

		cv::RNG rng;

		for (int i = 0; i < nLines; ++i)
		{
			Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
			cvLine(pCanvas, cvPoint(result[i * 4], result[i * 4 + 1]), cvPoint(result[i * 4 + 2], result[i * 4 + 3]), color, 2);
		}

		IplImage* pGray3c = cvCreateImage(cvGetSize(pGray), IPL_DEPTH_8U, 3);
		cvCvtColor(&GrayImg, pGray3c, CV_GRAY2BGR);
		for (int i = 0; i < nLines; ++i)
		{
			Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
			cvLine(pGray3c, cvPoint(result[i * 4], result[i * 4 + 1]), cvPoint(result[i * 4 + 2], result[i * 4 + 3]), color, 2);
		}
		cvShowImage("Hough", pCanvas);
		cvShowImage("CannyLine", pGray3c);
		cvWaitKey();

		cvReleaseImage(&pImage);
		cvReleaseImage(&pGray);
		cvReleaseImage(&pGray3c);
		cvReleaseImage(&pCanvas);
	}
}

void COpenCVFunctionTestDlg::OnBnClickedButtonPicadd()
{
	// TODO: Add your control notification handler code here
	CString strDirPath = sdf.BrowseDir();
	std::list<CString> lFilesInDir;
	sdf.ReadDirFiles(strDirPath, lFilesInDir, ".tif", false);
	
	for (std::list<CString>::iterator it = lFilesInDir.begin(); it!= lFilesInDir.end();)
	{
		if (it->Find("_h") != -1)
		{
			std::list<CString>::iterator it_tmp = it++;
			lFilesInDir.erase(it_tmp);
		}
		else
		{
			++it;
		}
	}

	for (std::list<CString>::iterator it = lFilesInDir.begin(); it!= lFilesInDir.end(); ++it)
	{
		CString strFile = *it;
		CString strTfw = sdf.ReplaceSuffix(*it, ".tfw");
		CString strMergeFile = sdf.ReplaceSuffix(*it, "_h.tif");
		CString strMergeTfw = sdf.ReplaceSuffix(*it, "_h.tfw");
		CString strSavePath = sdf.ReplaceSuffix(*it, "_a.tif");

		if (sdf.IfExistsFile(strFile) && sdf.IfExistsFile(strMergeFile))
		{
			cv::Mat mSrc = imread(sdf.CString2Char(strFile));
			cv::Mat mSrc_h = imread(sdf.CString2Char(strMergeFile));

			cv::Mat mSrcResize;
			cv::resize(mSrc, mSrcResize, mSrc_h.size());
			cv::Mat mSrc_a;
			cv::addWeighted(mSrc_h, 0.5, mSrcResize, 0.5, 0, mSrc_a);

			imwrite(sdf.CString2Char(strSavePath), mSrc_a);
		}
	}
	
	MessageBox("处理完成!", "提示!", MB_ICONINFORMATION);
}


void COpenCVFunctionTestDlg::OnBnClickedButtonHist()
{
	// TODO: Add your control notification handler code here
	CString strFilePath = sdf.OpenFile();

	if (strFilePath.GetLength())
	{
		cv::Mat mSrc = imread(sdf.CString2Char(strFilePath), 0);
		cv::Mat mDst;

		cv::equalizeHist(mSrc, mDst);

		imshow("src", mSrc);
		imshow("equalizeHist", mDst);
		cv::waitKey();
	}
}


void COpenCVFunctionTestDlg::OnBnClickedButtonHists()
{
	// TODO: Add your control notification handler code here
	CString strDir = sdf.BrowseDir();
	CString strHist = strDir + "\\Hist";
	if (!sdf.IfExistsDir(strHist))
	{
		CreateDirectory(strHist, NULL);
	}

	std::list<CString> lFiles;
	sdf.ReadDirFiles(strDir, lFiles, ".tif", false);

	for (std::list<CString>::iterator it = lFiles.begin(); it != lFiles.end(); ++it)
	{
		cv::Mat mSrc = imread(sdf.CString2Char(*it), 0);
		cv::Mat mDst;
		cv::equalizeHist(mSrc, mDst);
		CString strSave = strHist + "\\" + sdf.GetNameOfFile(*it);
		imwrite(sdf.CString2Char(strSave), mDst);
	}

	MessageBox("处理完成!", "提示!", MB_ICONINFORMATION);
}


void COpenCVFunctionTestDlg::OnBnClickedButtonBuilddetect()
{
	// TODO: Add your control notification handler code here
	CString strDirPath = sdf.BrowseDir();
	std::list<CString> lFilesInDir;
	sdf.ReadDirFiles(strDirPath, lFilesInDir, ".tif", false);
	for (std::list<CString>::iterator it = lFilesInDir.begin(); it != lFilesInDir.end(); ++it)
	{
		cv::Mat mSrc = imread(sdf.CString2Char(*it), CV_LOAD_IMAGE_COLOR);
		cv::Mat mGray, mDilate;
		cv::cvtColor(mSrc, mGray, CV_RGB2GRAY);
		cv::dilate(mGray, mDilate, cv::Mat());
		cv::Mat mContours;
		cv::absdiff(mDilate, mGray, mContours);
		//imshow("contours", mContours);
		//cv::waitKey();

		std::vector<std::vector<cv::Point>> contours;
		std::vector<Vec4i> hierarchy;
		cv::Mat mForContours = mContours.clone();
		cv::findContours(mForContours, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

		cv::RNG rng;
		for (int i = 0; i < contours.size(); ++i)
		{
			if (contours[i].size() < 4) continue;
			if (contourArea(contours[i]) < 2500)
			{
				//面积太小的区域不适合用次方法判断
				continue;
			}

			cv::Rect rect = boundingRect(contours[i]);
			cv::Mat mRoi(mContours, rect);

			std::vector<cv::Vec4i> lines;
			cv::Mat mHough = mRoi.clone();
			cv::blur(mHough, mHough, cv::Size(2, 2));
			HoughTransP(mHough, lines, 1, CV_PI / 180, 40, 15, 2);

			cv::Mat mHoughCanvas = mSrc;
			RNG rng;
			for (int j = 0; j < lines.size(); ++j)
			{
				Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
				cv::line(mHoughCanvas, cv::Point(lines[j].val[0] + rect.x, lines[j].val[1] + rect.y),
					cv::Point(lines[j].val[2] + rect.x, lines[j].val[3] + rect.y), color, 2);
				cv::putText(mHoughCanvas, sdf.CString2Char(sdf.Int2Cstring(lines.size())),
					Point(rect.x, rect.y), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 255, 0), 1);
			}

			if (lines.size() >= 2)
			{
				drawContours(mHoughCanvas, contours, i, cv::Scalar(0, 255, 0));
			}
			else
			{
				drawContours(mHoughCanvas, contours, i, cv::Scalar(0, 0, 255));
			}

			imshow("mHoughCanvas", mHoughCanvas);
			cv::waitKey();
			cv::destroyWindow("mHoughCanvas");
		}
	}

	MessageBox("处理完成!", "提示!", MB_ICONINFORMATION);
}


void COpenCVFunctionTestDlg::OnBnClickedButtonSpix()
{
	// TODO: Add your control notification handler code here
	CString strFilePath = sdf.OpenFile();

	if (strFilePath.GetLength())
	{
		cv::Mat mSrc = imread(sdf.CString2Char(strFilePath), CV_LOAD_IMAGE_GRAYSCALE);

		int pix = mSrc.at<uchar>(cv::Point(1, 0));
		pix = mSrc.at<uchar>(1, 0); //跟上一个不一样
		pix = mSrc.at<uchar>(cv::Point(3, 4));
		pix = mSrc.at<uchar>(4, 3); //跟上一个一样

		MessageBox(sdf.Int2Cstring(pix), "像素值", MB_ICONINFORMATION);
	}
}


void COpenCVFunctionTestDlg::OnBnClickedButtonContour()
{
	// TODO: Add your control notification handler code here
	CString strFilePath = sdf.OpenFile();

	if (strFilePath.GetLength())
	{
		cv::Mat mSrc = imread(sdf.CString2Char(strFilePath), CV_LOAD_IMAGE_GRAYSCALE);

#ifdef _AFXDLL
		std::vector<std::vector<cv::Point>> contours;
		std::vector<cv::Vec4i> hierarchy;
#else
		std::vector<Mat> contours(100);
		std::vector<Vec4i> hierarchy(100);
#endif // _AFXDLL

		cv::findContours(mSrc, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

		
		for (int i = 0; i < contours.size(); ++i)
		{
			CString strContent;

#ifdef _AFXDLL
			for (int j = 0; j < contours[i].size(); ++j)
			{
				strContent += "x=" + sdf.Int2Cstring(contours[i][j].x) +  " y=" + sdf.Int2Cstring(contours[i][j].x) + " || ";
			}
#else
			//如果使用mat作为参数
			for (int n = 0; n < contours[i].rows; ++n)
			{
				uchar* data = contours[i].ptr<uchar>(n);
				for (int m = 0; m < contours[i].cols; ++m)
				{
					int da = data[m];
					strContent += sdf.Int2Cstring(da) +  " | ";
				}
			}
#endif // _AFXDLL

			cv::Rect rect = boundingRect(contours[i]);
			cv::Mat mCanvas = cv::Mat::zeros(cv::Size(mSrc.cols, mSrc.rows), CV_8UC3);
			cv::putText(mCanvas, sdf.CString2Char(strContent), cv::Point(rect.x, rect.y), FONT_HERSHEY_PLAIN, 1.0, cv::Scalar(0,255,0));

			drawContours(mCanvas, contours, i, Scalar(0,0,255), 1);
			imshow("contour", mCanvas);
			waitKey();
			
			MessageBox(strContent, "轮廓坐标!", MB_ICONINFORMATION);
		}
	}
}


void COpenCVFunctionTestDlg::OnBnClickedButtonFit()
{
	// TODO: Add your control notification handler code here
	CString strFilePath = sdf.OpenFile();
	//输入二值图
	if (strFilePath.GetLength())
	{
		//得到轮廓
		cv::Mat mSrc = imread(sdf.CString2Char(strFilePath), CV_LOAD_IMAGE_COLOR);
		cv::Mat mGray;
		cv::cvtColor(mSrc, mGray, CV_RGB2GRAY);
		std::vector<std::vector<cv::Point>> contours;
		std::vector<Vec4i> hierarchy;
		cv::findContours(mGray, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

		cv::Mat mCanvas = mSrc.clone();
		for (int i = 0; i < contours.size(); ++i)
		{
			cv::Rect rect = boundingRect(contours[i]);
			//原来的图像
			drawContours(mCanvas, contours, i, Scalar(0,0,255), 2);
			cv::Scalar color = cv::Scalar(255,0,0);
			cv::line(mCanvas, cv::Point(rect.x, rect.y), cv::Point(rect.x + rect.width, rect.y), color, 2);
			cv::line(mCanvas, cv::Point(rect.x + rect.width, rect.y), cv::Point(rect.x + rect.width, rect.y + rect.height), color, 2);
			cv::line(mCanvas, cv::Point(rect.x + rect.width, rect.y + rect.height), cv::Point(rect.x, rect.y + rect.height), color, 2);
			cv::line(mCanvas, cv::Point(rect.x, rect.y + rect.height), cv::Point(rect.x, rect.y), color, 2);
		}
		imshow("contour", mCanvas);
		waitKey();

		mCanvas = mSrc.clone();
		for (int i = 0; i < contours.size(); ++i)
		{
			//原来的图像
			drawContours(mCanvas, contours, i, Scalar(0,0,255), 2);

			//旋转矩形拟合
			cv::RotatedRect Rrect = minAreaRect(contours[i]);
			cv::Point2f pf[4];
			Rrect.points(pf);
			cv::Scalar color = cv::Scalar(0, 255, 0);
			for (int j = 0; j < 3; ++j)
			{
				line(mCanvas, pf[j], pf[j + 1], color, 2);
			}
			line(mCanvas, pf[0], pf[3], color, 2);
		}
		imshow("contour", mCanvas);
		waitKey();

#ifdef _AFXDLL
		mCanvas = mSrc.clone();
		for (int i = 0; i < contours.size(); ++i)
		{
			//原来的图像
			drawContours(mCanvas, contours, i, Scalar(0,0,255), 2);
			cv::Scalar color = cv::Scalar(255, 255, 0);
			//多边形拟合
			//静态库的时候,该函数有内存问题
			//参数为:输入图像的2维点集,输出结果,估计精度,是否闭合
			std::vector<cv::Point> vPtOut;
			approxPolyDP(Mat(contours[i]), vPtOut, 5, true);
			//std::cout << "多边形大小:" << poly.size() << std::endl;
			//画出结果  
			std::vector<Point>::const_iterator itp = vPtOut.begin();
			while (itp != vPtOut.end() - 1)
			{
				line(mCanvas, *itp, *(itp + 1), color, 2);
				++itp;
			}
			//将第一个点和最后一点连起来  
			Point p1 = *(vPtOut.begin());
			Point p2 = *(vPtOut.end() - 1);
			line(mCanvas, *(vPtOut.begin()), *(vPtOut.end() - 1), color, 2);
		}
		cv::imshow("contour", mCanvas);
		cv::waitKey();
#endif // _AFXDLL
		cv::destroyAllWindows();

	}
}


void COpenCVFunctionTestDlg::OnBnClickedButtonFitline()
{
	// TODO: Add your control notification handler code here
		IplImage* img = cvCreateImage( cvSize( 500, 500 ), 8, 3 );
		CvRNG rng = cvRNG(-1); //cvRNG()跟一般的C语言srand()使用方法一样,要先给它一个种子,
		//但srand()用到的是unsigned int的32位种子范围,而cvRNG()用的是64位长整数种子。
		//初始化CvRNG资料结构,假如seed给0,它将会自动转成-1	cvRNG(64位种子)
		cvNamedWindow( "fitline", 1 );

		for(;;)
		{
			char key;
			int i;
			int	count = cvRandInt(&rng)%100 + 1; //产生1-100 之间的数
			int outliers = count/5; // 奇异点的个数。0--20 之间的数
			printf("count = %d", count);
			float a = cvRandReal(&rng)*200;  // 0~ 199 之间的浮点数 [cvRandReal 浮点型随机数并更新 RNG ,范围在 0..1 之间,不包括 。
			float b = cvRandReal(&rng)*40; //返回0 ~ 39之间的数
			float angle = cvRandReal(&rng)*CV_PI;  
			printf("count = %f", angle);
			float cos_a = cos(angle), sin_a = sin(angle);
			printf("cos_a = %f", cos_a);

			CvPoint pt1, pt2; //直线的两个端点
			CvPoint* points = (CvPoint*)malloc( count * sizeof(points[0])); //存放随机产生的点点,数目为count
			CvMat pointMat = cvMat( 1, count, CV_32SC2, points ); //点集, 存储count个随机点points
			float line[4]; //输出的直线参数。2D 拟合情况下,它是包含 4 个浮点数的数组 (vx, vy, x0, y0)
			//其中 (vx, vy) 是线的单位向量而 (x0, y0) 是线上的某个点
			float d, t;
			b = MIN(a*0.3, b);

			// generate some points that are close to the line
			for( i = 0; i < count - outliers; i++ )
			{
				float x = (cvRandReal(&rng)*2-1)*a;
				float y = (cvRandReal(&rng)*2-1)*b;
				points[i].x = cvRound(x*cos_a - y*sin_a + img->width/2);
				points[i].y = cvRound(x*sin_a + y*cos_a + img->height/2);
			}
			// generate "completely off" points
			for( ; i < count; i++ )
			{
				points[i].x = cvRandInt(&rng) % img->width;
				points[i].y = cvRandInt(&rng) % img->height;
			}

			// find the optimal line 曲线拟合
			cvFitLine( &pointMat, CV_DIST_L1, 1, 0.001, 0.001, line ); 
			cvZero( img );


			//画出产生的随机分布的点点
			for( i = 0; i < count; i++ )
				cvCircle( img, points[i], 2, i < count - outliers ? CV_RGB(255, 0, 0) :CV_RGB(255,255,0), CV_FILLED, CV_AA, 0 );

			// ... and the long enough line to cross the whole image
			d = sqrt((double)line[0]*line[0] + (double)line[1]*line[1]);  //line[0 & 1]存储的是单位向量,所以d=1
			//printf("\n %f\n", d);
			line[0] /= d;
			line[1] /= d;

			//画出线段的两个端点(避免线太短,以线上一个随机点向两侧延伸line[0]*t )
			t = (float)(img->width + img->height) ;
			pt1.x = cvRound(line[2] - line[0]*t);
			pt1.y = cvRound(line[3] - line[1]*t);
			pt2.x = cvRound(line[2] + line[0]*t);
			pt2.y = cvRound(line[3] + line[1]*t);
			cvLine( img, pt1, pt2, CV_RGB(0,255,0), 3, CV_AA, 0 );

			cvShowImage( "fitline", img );
			key = (char) cvWaitKey(0);
			if( key == 27 || key == 'q' || key == 'Q' ) // 'ESC'
				break;
			free( points );
		}

		cvDestroyWindow( "fitline" );
		return;

}

bool fittingCurve(vector<Point> &vec,int times,float *p) //输入点,次数,输出曲线参数
{
	float *py = new float[vec.size()];
	float *px = new float[times*vec.size()];
	int i = 0;
	Point* P = &vec[0];
	for(vector<Point>::iterator itr = vec.begin();itr!=vec.end();++itr)
	{
		py[i] = (*itr).y;
		int j=0;
		while (j<times)
		{
			px[times*i+j] = pow(((*itr).x),float(j));
			j++;
		}
		i++;
	}
	Mat X = Mat(vec.size(),times,CV_32FC1,px);
	float* Xp = &(X.at<float>(0));
	Mat X_T;
	transpose(X,X_T);
	Mat Y = Mat(vec.size(),1,CV_32FC1,py);
	Mat para = ((X_T*X).inv())*X_T*Y;
	for (int s = 0; s<times;s++)
	{
		p[s] = para.at<float>(s);
	}

	delete[] px;
	delete[] py;
	return true;
}

std::vector<cv::Point> vPoints;
cv::Mat g_mCanvas;
cv::Point prev_pt;

void on_mouse_brokenline(int event, int x, int y, int flags, void* pParameters)
{
	//获取相关的参数
	if ( event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON))  //判断事件为松开鼠标左键或者不是左拖拽
	{
		prev_pt = cv::Point(-1, -1);
	}
	else if (event == CV_EVENT_LBUTTONDOWN)  //判断为按下左键
	{
		prev_pt = cv::Point(x, y);
	}
	else if ( event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON))  //判断移动鼠标并且左拖拽
	{
		cv::Point pt = cv::Point(x, y);
		if ( prev_pt.x < 0)
		{
			prev_pt = pt;
		}
		vPoints.push_back(pt);
		cv::line(g_mCanvas, prev_pt, pt, cv::Scalar(255, 0, 0), 1 ,8,0); //原图上划线
		prev_pt = pt;
		imshow("curve", g_mCanvas);
	}

	if (event == CV_EVENT_RBUTTONUP)
	{

	}
}

int CurveBrokenLine(double* pX, double* pY, const int nNum, double** pOutX, double** pOutY, int* nOutNum);
void COpenCVFunctionTestDlg::OnBnClickedButtonFitcurve()
{
	// TODO: Add your control notification handler code here
	//画一条曲线
	cv::Mat mCanvas = cv::Mat::zeros(cv::Size(800, 600), CV_8UC3);
	g_mCanvas = mCanvas.clone();
	imshow("curve", g_mCanvas);

	cvSetMouseCallback("curve", on_mouse_brokenline, NULL);
	waitKey(0);

	//把获取到的点变成折线,相近的点则去掉

	//debug
	//vPoints.clear();
	//vPoints.push_back(cv::Point(1,10));
	//vPoints.push_back(cv::Point(100,10));
	//vPoints.push_back(cv::Point(100,100));
	//vPoints.push_back(cv::Point(200,100));
	//vPoints.push_back(cv::Point(200,200));
	//vPoints.push_back(cv::Point(250,250));
	//vPoints.push_back(cv::Point(200,250));

	double *pX = new double[vPoints.size()];
	double *pY = new double[vPoints.size()];
	for (int i = 0; i < vPoints.size(); ++i)
	{
		pX[i] = vPoints[i].x;
		pY[i] = vPoints[i].y;
	}

	double* pOutX = NULL, *pOutY = NULL;
	int nOut;
	CurveBrokenLine(pX, pY, vPoints.size(), &pOutX, &pOutY, &nOut);

	//cv::Mat mOut = cv::Mat::zeros(g_mCanvas.size(), CV_8UC3);
	for (int i = 0; i < nOut - 1; ++i)
	{
		cv::line(g_mCanvas, cv::Point(pOutX[i], pOutY[i]), cv::Point(pOutX[i + 1], pOutY[i + 1]), Scalar(0, 255, 0), 1);
	}
	cv::imshow("curve", g_mCanvas);
	cv::waitKey();

}

void COpenCVFunctionTestDlg::OnBnClickedButtonBilateral()
{
	// TODO: Add your control notification handler code here
	CString strFilePath = sdf.OpenFile();
	//输入二值图
	if (strFilePath.GetLength())
	{
		cv::Mat mSrc = imread(sdf.CString2Char(strFilePath), CV_LOAD_IMAGE_GRAYSCALE);
		cv::Mat mBilateral, mCanny;
		//cv::equalizeHist(mSrc, mSrc);

		cv::bilateralFilter(mSrc,mBilateral,25, 25*2, 25/2 );
		cv::adaptiveThreshold(mBilateral, mCanny, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, 3, 5);
		CString strSavePath = sdf.ReplaceSuffix(strFilePath, "bilateral.tif");
		CString strCannyPath = sdf.ReplaceSuffix(strFilePath, "bilateralCanny.tif");
		cv::imwrite(sdf.CString2Char(strSavePath), mBilateral);
		cv::imwrite(sdf.CString2Char(strCannyPath), mCanny);
		
		MessageBox("处理完成!", "提示", MB_ICONINFORMATION);
	}
}

int ImgDijkstra();
void COpenCVFunctionTestDlg::OnBnClickedButtonDijkstra()
{
	// TODO: Add your control notification handler code here
	ImgDijkstra();
}

int ImgShortestPath(const bool& bKeyPts);
void COpenCVFunctionTestDlg::OnBnClickedButtonShortestpath()
{
	// TODO: Add your control notification handler code here
	//优化最短路径算法
	bool bKeyPts = ((CButton*)GetDlgItem(IDC_CHECK_KEYPTS))->GetCheck();
	ImgShortestPath(bKeyPts);
}


void COpenCVFunctionTestDlg::OnBnClickedButtonCutpic()
{
	// TODO: Add your control notification handler code here
	CString strFilePath = sdf.OpenFile();

	if (strFilePath.GetLength())
	{
		SendMessage(WM_CLOSE);
		CCutPic cp;
		cp.InitializePath(strFilePath);
		cp.DoModal();
	}
}


void COpenCVFunctionTestDlg::OnBnClickedButtonOffsettfw()
{
	// TODO: Add your control notification handler code here
	CString strFilePath = sdf.OpenSuffixFile(".tif");

	if (strFilePath.GetLength())
	{
		CString strTfw = sdf.ReplaceSuffix(strFilePath, ".tfw");
		if (!sdf.IfExistsFile(strTfw))
		{
			CTfwReader tr(strTfw);
			tr.m_dXCoordinate = tr.m_dYCoordinate = tr.m_dXRotatePara = tr.m_dYRotatePara = 0.0;
			tr.m_dXResolution = 0.6;
			tr.m_dYResolution = -0.6;
			tr.SaveAsTfwFile(strTfw);
		}

		SendMessage(WM_CLOSE);
		COffsetTifw ot;
		ot.InitializePath(strFilePath);
		ot.DoModal();
	}
}


void COpenCVFunctionTestDlg::OnBnClickedButtonZoomtfw()
{
	// TODO: Add your control notification handler code here
	CString strDirPath = sdf.BrowseDir("选择tfw所在目录");
	CString strNewDirPath = strDirPath + "\\New";

	if (!sdf.IfExistsDir(strNewDirPath))
	{
		CreateDirectory(strNewDirPath, NULL);
	}
	CString strResolution;
	GetDlgItemText(IDC_EDIT_RESOLUTION, strResolution);
	double dNewResolution = sdf.CString2double(strResolution);

	if (strDirPath.GetLength())
	{
		CStringArray arrTifsInDir;
		sdf.ReadDirFiles(strDirPath, &arrTifsInDir, ".tif", false);
		for (int i = 0; i < arrTifsInDir.GetCount(); ++i)
		{
			CTfwReader tr(sdf.ReplaceSuffix(arrTifsInDir[i], ".tfw"));
			//如果源图像存在tfw文件,则产生新的tfw文件
			const double dProp = tr.m_dXResolution / dNewResolution;

			//写入新的tfw文件
			CStringArray arrNewTfw;
			arrNewTfw.Add(sdf.Float2Cstring(dNewResolution) + '\n');
			arrNewTfw.Add(sdf.Float2Cstring(tr.m_dXRotatePara) + '\n');
			arrNewTfw.Add(sdf.Float2Cstring(tr.m_dYRotatePara) + '\n');
			arrNewTfw.Add(sdf.Float2Cstring(-dNewResolution) + '\n');
			arrNewTfw.Add(sdf.Float2Cstring(tr.m_dXCoordinate) + '\n');
			arrNewTfw.Add(sdf.Float2Cstring(tr.m_dYCoordinate) + '\n');
			sdf.SaveTXTFile(strNewDirPath + "\\" + sdf.ReplaceSuffix(sdf.GetNameOfFile(arrTifsInDir[i]), ".tfw"), arrNewTfw);

			//写入新的tif文件
			cv::Mat mSrc = cv::imread(sdf.CString2Char(arrTifsInDir[i]));
			cv::Mat mDst;
			cv::resize(mSrc, mDst, cv::Size(mSrc.cols * dProp, mSrc.rows * dProp));
			cv::imwrite(sdf.CString2Char(strNewDirPath + "\\" + sdf.GetNameOfFile(arrTifsInDir[i])), mDst);
		}

		AfxMessageBox("完成!");
	}
}


void COpenCVFunctionTestDlg::OnBnClickedButtonWtog()
{
	// TODO: Add your control notification handler code here
	CString strDirPath = sdf.BrowseDir("请选择tif所在目录");

	if (strDirPath.GetLength())
	{
		CStringArray arrTifsInDir;
		sdf.ReadDirFiles(strDirPath, &arrTifsInDir, ".tif", false);
		for (int i = 0; i < arrTifsInDir.GetCount(); ++i)
		{
			cv::Mat mSrcGray = cv::imread(sdf.CString2Char(arrTifsInDir[i]), CV_LOAD_IMAGE_GRAYSCALE);
			cv::Mat mDst;
			cv::threshold(mSrcGray, mDst, 100, 100, CV_THRESH_BINARY);
			cv::imwrite(sdf.CString2Char(arrTifsInDir[i]), mDst);
		}
		AfxMessageBox("完成!");
	}
}


void COpenCVFunctionTestDlg::OnBnClickedButtonFillpoly()
{
	// TODO: Add your control notification handler code here
	//方法1
	cv::Mat mSrc = cv::Mat::zeros(150, 200, CV_8UC3);
	std::vector<cv::Point> polyline(8);
	// external rectengular
	polyline[0] = Point(0, 0);
	polyline[1] = Point(80, 0);
	polyline[2] = Point(80, 80);
	polyline[3] = Point(0, 80);
	// internal rectangular
	polyline[4] = Point(20, 20);
	polyline[5] = Point(60, 20);
	polyline[6] = Point(60, 60);
	polyline[7] = Point(20, 60);
	const Point* ppts[] = {&polyline[0], &polyline[0]+4};
	int pn[] = {4, 4};
	fillPoly( mSrc, ppts, pn, 2, Scalar(100, 100, 0));
	cv::imshow("FillPoly", mSrc);
	cv::waitKey();

	//方法2
	//cv::Mat mSrc = cv::Mat::zeros(150, 200, CV_8UC3);
	std::vector<cv::Point> vPoly;
	std::vector<std::vector<cv::Point>> vPolys;
	vPoly.push_back(cv::Point(10, 10));
	vPoly.push_back(cv::Point(100, 10));
	vPoly.push_back(cv::Point(100, 100));
	vPoly.push_back(cv::Point(100, 100));
	vPoly.push_back(cv::Point(10, 10));
	vPolys.push_back(vPoly);

	cv::fillPoly(mSrc, vPolys, cv::Scalar(255,0,0));
	cv::imshow("FillPoly", mSrc);
	cv::waitKey();

	//方法3
	std::vector<cv::Point> vPolyB;
	vPolyB.push_back(cv::Point(20, 20));
	vPolyB.push_back(cv::Point(100, 10));
	vPolyB.push_back(cv::Point(500, 100));
	vPolyB.push_back(cv::Point(500, 500));
	vPolyB.push_back(cv::Point(20, 400));

	cv::fillConvexPoly(mSrc, vPolyB, cv::Scalar(255,255,0), 1);
	cv::imshow("FillPoly", mSrc);
	cv::waitKey();

	cv::fillConvexPoly(mSrc, vPolyB, cv::Scalar(255,255,0));
	for (int i = 0; i < vPolyB.size() - 1; ++i)
	{
		cv::line(mSrc, vPolyB[i], vPolyB[i + 1], Scalar(255,255,0), 10);
	}
	cv::line(mSrc, vPolyB[0], vPolyB[vPolyB.size() - 1], Scalar(255,255,0), 10);

	cv::imshow("FillPoly5", mSrc);
	cv::waitKey();


	cv::rectangle(mSrc, cv::Rect(110, 100, 150, 200), cv::Scalar(0.0, 255.0, 255.0), -1);
	cv::imshow("FillRect", mSrc);
	cv::waitKey();
}


void COpenCVFunctionTestDlg::OnBnClickedButtonCopymat()
{
	// TODO: Add your control notification handler code here
	cv::Mat mSrc = cv::Mat::zeros(cv::Size(10000, 10000), CV_8UC1);
	cv::Mat mSrc2 = cv::Mat::zeros(cv::Size(10000, 5000), CV_8UC1);

	mSrc = mSrc2;
	mSrc.release();
	mSrc2.release();

}


void COpenCVFunctionTestDlg::OnBnClickedButtonDistinguish()
{
	// TODO: Add your control notification handler code here
	cv::Mat mSrcGray = cv::Mat::ones(cv::Size(800, 600), CV_8UC1);
	cv::Mat mRoi(mSrcGray, cv::Rect(200,100,400, 300));
	cv::Mat mValue = cv::Mat(mRoi.size(), CV_8UC1, cv::Scalar(2));
	mValue.copyTo(mRoi);

	cv::imwrite("D:\\rect.tif", mSrcGray);
	cv::imshow("mSrcGray", mSrcGray);
	cv::waitKey();
}

int SmoothBrokenLine(double* pX, double* pY, const int nNum);
void COpenCVFunctionTestDlg::OnBnClickedButtonSmoothbrokenline()
{
	// TODO: 在此添加控件通知处理程序代码
	
	CString strFilePath = sdf.OpenSuffixFile(".rrlx");

	if (strFilePath.GetLength())
	{
		CRrlxContent rc;
		std::vector<cv::Point> vPts;
		rc.ReadFromFile(strFilePath);
		rc.GetPointsInPicByRrlx(vPts);

		int nNum = vPts.size();
		double* pX = new double[nNum];
		double* pY = new double[nNum];
		for (int i = 0; i < nNum; ++i)
		{
			pX[i] = vPts[i].x;
			pY[i] = vPts[i].y;
		}
		SmoothBrokenLine(pX, pY, nNum);
		for (int i = 0; i < nNum; ++i)
		{
			vPts[i] = cv::Point(pX[i], pY[i]);
		}

		rc.CreateBmpByPoints(vPts, false);

		AfxMessageBox("完成!");
	}
}


void COpenCVFunctionTestDlg::OnBnClickedButtonRrlxpixvalue()
{
	// TODO: 在此添加控件通知处理程序代码
	SendMessage(WM_CLOSE);
	CRrlxPixValue rpv;
	rpv.DoModal();
}

int MserTest(char* cFileName);
void COpenCVFunctionTestDlg::OnBnClickedButtonMser()
{
	// TODO: 在此添加控件通知处理程序代码
	CString strFilePath = sdf.OpenSuffixFile(".tif");

	if (strFilePath.GetLength())
	{
		Mat src,yuv;  
		src = imread(sdf.CString2Char(strFilePath));  
		cvtColor(src, yuv, COLOR_BGR2YCrCb);  

		MSER ms;  
		vector<vector<Point>> regions;  
		ms(yuv, regions, Mat());  
		for (int i = 0; i < regions.size(); i++)  
		{  
			ellipse(src, fitEllipse(regions[i]), Scalar(255,0,0));  
		}  
		imshow("mscr", src);
		waitKey(0); 

		cv::imwrite(sdf.CString2Char(sdf.ReplaceSuffix(strFilePath, "mser.tif")), src);

		return;  
	}
}


void COpenCVFunctionTestDlg::OnBnClickedButtonPerspect()
{
	// TODO: 在此添加控件通知处理程序代码
	CString strFilePath = sdf.OpenSuffixFile(".tif");
	cv::Mat src= cv::imread(sdf.CString2Char(strFilePath),0);
	if (!src.data)
		return;
	vector<Point> not_a_rect_shape;
	not_a_rect_shape.push_back(Point(122,0));
	not_a_rect_shape.push_back(Point(814,0));
	not_a_rect_shape.push_back(Point(22,540));
	not_a_rect_shape.push_back(Point(910,540));
	// For debugging purposes, draw green lines connecting those points
	// and save it on disk
	const Point* point = &not_a_rect_shape[0];
	int n = (int )not_a_rect_shape.size();
	Mat draw = src.clone();
	polylines(draw, &point, &n, 1, true, Scalar(0, 255, 0), 3, CV_AA);
	imwrite( "draw.jpg", draw);
	//  topLeft, topRight, bottomRight, bottomLeft
	cv::Point2f src_vertices[4];
	src_vertices[0] = not_a_rect_shape[0];
	src_vertices[1] = not_a_rect_shape[1];
	src_vertices[2] = not_a_rect_shape[2];
	src_vertices[3] = not_a_rect_shape[3];

	Point2f dst_vertices[4];
	dst_vertices[0] = Point(0, 0);
	dst_vertices[1] = Point(960,0);
	dst_vertices[2] = Point(0,540);
	dst_vertices[3] = Point(960,540);
	Mat warpMatrix = getPerspectiveTransform(src_vertices, dst_vertices);
	cv::Mat rotated;
	warpPerspective(src, rotated, warpMatrix, rotated.size(), INTER_LINEAR, BORDER_CONSTANT);
	// Display the image
	cv::namedWindow( "Original Image");
	cv::imshow( "Original Image",src);
	cv::namedWindow( "warp perspective");
	cv::imshow( "warp perspective",rotated);
	imwrite( "result.jpg",src);
	cv::waitKey();
	return;
}

int TransTif(cv::Mat& mSrcGray, std::vector<cv::Point2f>& vPts, std::vector<cv::Point2f>& vGeos, double dGeo = 1.0);
void COpenCVFunctionTestDlg::OnBnClickedButtonPicTrans()
{
	// TODO: 在此添加控件通知处理程序代码
	CString strFilePath = sdf.OpenSuffixFile(".tif");
	cv::Mat src= cv::imread(sdf.CString2Char(strFilePath), 0);
	if (!src.data)
		return;
	std::vector<cv::Point2f> vPts, vGeos;
	vPts.push_back(cv::Point2f(461,644));
	vPts.push_back(cv::Point2f(1343,554));
	vPts.push_back(cv::Point2f(539,1342));
	vPts.push_back(cv::Point2f(1304,1648));

	vGeos.push_back(cv::Point2f(566706, 3883358));
	vGeos.push_back(cv::Point2f(566882, 3883378));
	vGeos.push_back(cv::Point2f(566721, 3883219));
	vGeos.push_back(cv::Point2f(566874, 3883157));

	TransTif(src, vPts, vGeos, 0.2);
}

float GetGaussFilter(int* Filter, int width, int sigma)
{
	int N = width/2;
	int C,i,j;
	float Cof = 0;
	float *Ftemp = new float[(N+1)*(N+1)];
	for(i=0;i<N+1;i++)//取模板大小(2N+1) (2N+1)的右下角部分
	{
		for(j=0;j<N+1;j++)
		{
			float t=(float)(i*i+j*j)/(float)sigma;
			Ftemp[i*(N+1)+j]=(float)(1.0/exp(t/2)); 
		}
	}

	C=(int)ceil(1/Ftemp[(N+1)*(N+1)-1]+0.5);//计算规范化系数
	for(i=0;i<N+1;i++)
		for(j=0;j<N+1;j++)
			Filter[(N+i)*(2*N+1)+(N+j)] =int(Ftemp[i*(N+1)+j]*C+0.5); 

	for(i=N;i<2*N+1;i++)						//给模板左下角付值? ? 
		for(j=0;j<N+1;j++)
			Filter[i*(2*N+1)+j] = Filter[i*(2*N+1)+(2*N-j)];

	for(i=0;i<N;i++)						//给模板上半部分付值
		for(j=0;j<2*N+1;j++)
			Filter[i*(2*N+1)+j] =Filter[(2*N-i)*(2*N+1)+j];

	for(i=0;i<2*N+1;i++)					//计算总的系数
		for(j=0;j<2*N+1;j++)
			Cof +=(float )Filter[i*(2*N+1)+j];

	Cof=(float)( 1.0/Cof); 
	delete []Ftemp;
	return Cof;
}

int GaussianFilter(float* m_data, int m_height, int m_width)
{
	int loops = 2; //进行滤波次数
	int N     = 3; //模板尺寸
	int sigma = 1; //滤波尺度
	int loop = 0;
	int* filter = new int[N*N]; //模板
	float C =  GetGaussFilter(filter,N,sigma);//模板系数
#define INVALIDVALUE -99999
	while(loop<loops)
	{
		float *pData = new float[m_height*m_width];
#ifdef OLD_METHOD
		for (int i=0;i<m_height;i++)
		{
			for (int j=0;j<m_width;j++)
			{
				if (j<(N-1)/2||j>(m_width-(N+1)/2)
					||i<(N-1)/2||i>(m_height-(N+1)/2))
					pData[i*m_width+j] = m_data[i*m_width+j];
				else
				{
					if (m_data[i*m_width+j] > INVALIDVALUE )
					{
						float sum = 0;
						for (int temi=-(N-1)/2;temi<(N+1)/2;temi++)
						{
							for (int tempj=-(N-1)/2;tempj<(N+1)/2;tempj++)
							{
								float data = m_data[(i+temi)*m_width+j+tempj];
								if (data <= INVALIDVALUE)
									data =  m_data[i*m_width+j];
								sum += data*filter[(temi+(N-1)/2)*N+(tempj+(N-1)/2)];
							}
						}
						pData[i*m_width+j] = sum*C;
					}
					else
						pData[i*m_width+j] = INVALIDVALUE;
				}
			}
		}
#else
		for (int i = 0; i < m_height; i++)
		{
			for (int j = 0; j<m_width; j++)
			{
				if (m_data[i*m_width + j] > INVALIDVALUE)
				{
					float sum = 0;
					for (int temi = -(N - 1) / 2; temi < (N + 1) / 2; temi++)
					{
						for (int tempj = -(N - 1) / 2; tempj < (N + 1) / 2; tempj++)
						{
							int nRow = i + temi;
							if (nRow < 0)
							{
								nRow = -nRow;
							}
							else if (nRow >= m_height)
							{
								nRow = 2 * m_height - nRow - 1;
							}

							int nCol = j + tempj;
							if (nCol < 0)
							{
								nCol = -nCol;
							}
							else if (nCol >= m_width)
							{
								nCol = 2 * m_width - nCol - 1;
							}

							float data = m_data[(nRow)*m_width + nCol];
							if (data <= INVALIDVALUE)
								data = m_data[i*m_width + j];
							sum += data*filter[(temi + (N - 1) / 2)*N + (tempj + (N - 1) / 2)];
						}
					}
					pData[i*m_width + j] = sum*C;
				}
				else
					pData[i*m_width + j] = INVALIDVALUE;
			}
		}
#endif // OLD_METHOD


		memcpy(m_data,pData,m_height*m_width*sizeof(float));
		delete []pData;
		loop++;
	}
	delete []filter;
	return 0;
}

void COpenCVFunctionTestDlg::OnBnClickedButtonFeather()
{
	// TODO: 在此添加控件通知处理程序代码
	CString strFilePath = sdf.OpenSuffixFile(".tif");
	cv::Mat mSrc= cv::imread(sdf.CString2Char(strFilePath), 0);
	if (!mSrc.data)
		return;

	long m_imgWidth = mSrc.cols;
	long m_imgHeight = mSrc.rows;
	float* m_data = new float[m_imgHeight*m_imgWidth];

	for (int j = 0; j < mSrc.rows; ++j)
	{
		uchar* data = mSrc.ptr<uchar>(j);
		for (int i = 0; i < mSrc.cols; ++i)
		{
			m_data[j * mSrc.cols + i] = data[i];
		}
	}

	GaussianFilter(m_data, m_imgHeight, m_imgWidth);

	for (int j = 0; j < mSrc.rows; ++j)
	{
		uchar* data = mSrc.ptr<uchar>(j);
		for (int i = 0; i < mSrc.cols; ++i)
		{
			data[i] = m_data[j * mSrc.cols + i];
		}
	}

	cv::imwrite("D:\\GaussianFilter.tif", mSrc);
}

int ScrollImage(const char* pFileName);
void COpenCVFunctionTestDlg::OnBnClickedButtonScroll()
{
	// TODO: 在此添加控件通知处理程序代码
	CString strFilePath = sdf.OpenSuffixFile(".tif");

	if (strFilePath.GetLength())
	{
		ScrollImage(sdf.CString2Char(strFilePath));
		return;  
	}
}

int CalcGrade(cv::Mat& src_gray, cv::Mat& grad, int scale = 1, int delta = 0, int ddepth = CV_16S)
{
	if (!src_gray.data)
	{
		return -1;
	}

	cv::GaussianBlur(src_gray, src_gray, cv::Size(3, 3), 0, 0, cv::BORDER_DEFAULT);

	cv::Mat grad_x, grad_y;
	cv::Mat abs_grad_x, abs_grad_y;

	//改为Scharr滤波器计算x轴导数
	cv::Scharr(src_gray, grad_x, ddepth, 1, 0, scale, delta, cv::BORDER_DEFAULT);
	cv::convertScaleAbs(grad_x, abs_grad_x);

	//改为Scharr滤波器计算y轴导数
	cv::Scharr(src_gray, grad_y, ddepth, 0, 1, scale, delta, cv::BORDER_DEFAULT);
	cv::convertScaleAbs(grad_y, abs_grad_y);

	cv::addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad);

	return 0;
}

int ScaleMat(cv::Mat& mSrcGray, cv::Mat& mDstGray, double dValue = BOUNDARY_VALUE)
{
	double maxVal = 0;
	double minVal = 0;
	cv::minMaxLoc(mSrcGray, &minVal, &maxVal, 0, 0);

	if (fabs(maxVal) <= 1e-5)
	{
		return -1;
	}

	double dScale = dValue / maxVal;

	cv::Mat mTemp = cv::Mat::zeros(mSrcGray.size(), CV_8UC1);
	cv::addWeighted(mTemp, 0.0, mSrcGray, dScale, 0, mTemp);
	mDstGray = mTemp;

	return 0;
}

int PersonalCalcGrade(cv::Mat& mSrcGray, cv::Mat& mDstGray)
{
	cv::Mat mGray = mSrcGray;
	mDstGray = mGray.clone();
	for (int j = 0; j < mGray.rows; ++j)
	{
		uchar* data = mGray.ptr<uchar>(j);
		uchar* dataDst = mDstGray.ptr<uchar>(j);
		for (int i = 0; i < mGray.cols; ++i)
		{
			if (j < mGray.rows - 1 && i < mGray.cols - 1)
			{
				uchar* dataNR = mGray.ptr<uchar>(j + 1);
				dataDst[i] = (abs(data[i + 1] - data[i]) + abs(dataNR[i] - data[i])) / 2;
			}
			else
			{
				//最后一行和最后一列的处理
				if (j == mGray.rows - 1)
				{
					uchar* dataPR = mDstGray.ptr<uchar>(j - 1);
					dataDst[i] = dataPR[i];
				}

				if (i == mGray.cols - 1)
				{
					dataDst[i] = dataDst[i - 1];
				}
			}
		}
	}

	ScaleMat(mDstGray, mDstGray);

	//加入scharr的计算
	cv::Mat mPGrade, mScharr;
	CalcGrade(mSrcGray, mScharr);

#ifdef _DEBUG0
	cv::imwrite("D:\\mPGrade.tif", mDstGray);
	cv::imwrite("D:\\mScharr.tif", mScharr);
#endif // _DEBUG

	int nDilateElementSize = 2;
	cv::Mat elementDilate = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(2 * nDilateElementSize + 1,
		2 * nDilateElementSize + 1), cv::Point(nDilateElementSize, nDilateElementSize));
	cv::dilate(mDstGray, mPGrade, elementDilate);
	cv::dilate(mScharr, mScharr, elementDilate);

	int nErodeElementSize = 1;
	cv::Mat elementErode = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(2 * nErodeElementSize + 1,
		2 * nErodeElementSize + 1), cv::Point(nErodeElementSize, nErodeElementSize));
	cv::erode(mPGrade, mPGrade, elementErode);
	cv::erode(mScharr, mScharr, elementErode);

#ifdef _DEBUG0
	cv::imwrite("D:\\mPGradeC.tif", mPGrade);
	cv::imwrite("D:\\mScharrC.tif", mScharr);
#endif // _DEBUG
	cv::bitwise_not(mPGrade, mPGrade);
	cv::bitwise_not(mScharr, mScharr);
#ifdef _DEBUG0
	cv::imwrite("D:\\mNotPGrade.tif", mPGrade);
	cv::imwrite("D:\\mNotScharr.tif", mScharr);
#endif // _DEBUG
	cv::addWeighted(mPGrade, 0.5, mScharr, 0.5, 0, mDstGray);

#ifdef _DEBUG0
	cv::imwrite("D:\\mDst.tif", mDstGray);
#endif // _DEBUG

	return 0;
}

void COpenCVFunctionTestDlg::OnBnClickedButtonGrade()
{
	// TODO: 在此添加控件通知处理程序代码
	CString strFilePath = sdf.OpenSuffixFile(".tif");

	if (strFilePath.GetLength())
	{
		cv::Mat mSrcGray= cv::imread(sdf.CString2Char(strFilePath), CV_LOAD_IMAGE_GRAYSCALE);
		if (!mSrcGray.data)
			return;

		cv::blur(mSrcGray, mSrcGray, cv::Size(3,3));

		//梯度和
		cv::Mat mDstAnd;
		PersonalCalcGrade(mSrcGray, mDstAnd);
		cv::imwrite(sdf.CString2Char(sdf.ReplaceSuffix(strFilePath, "_a.tif")), mDstAnd);

		//CalcGrade
		cv::Mat mGradeCalc;
		CalcGrade(mSrcGray, mGradeCalc);
		cv::imwrite(sdf.CString2Char(sdf.ReplaceSuffix(strFilePath, "_c.tif")), mGradeCalc);

		//标准梯度
		cv::Mat mDstGray = mSrcGray.clone();
		for (int j = 0; j < mSrcGray.rows; ++j)
		{
			uchar* data = mSrcGray.ptr<uchar>(j);
			uchar* dataDst = mDstGray.ptr<uchar>(j);
			for (int i = 0; i < mSrcGray.cols; ++i)
			{
				if (j < mSrcGray.rows - 1 && i < mSrcGray.cols - 1)
				{
					uchar* dataNR = mSrcGray.ptr<uchar>(j + 1);
					dataDst[i] = (abs(data[i + 1] - data[i]) + abs(dataNR[i] - data[i])) / 2;
				}
				else
				{
					//最后一行和最后一列的处理
					if (j == mSrcGray.rows - 1)
					{
						uchar* dataPR = mDstGray.ptr<uchar>(j - 1);
						dataDst[i] = dataPR[i];
					}

					if (i == mSrcGray.cols - 1)
					{
						dataDst[i] = dataDst[i - 1];
					}
				}
			}
		}

		ScaleMat(mDstGray, mDstGray);
		cv::imwrite(sdf.CString2Char(sdf.ReplaceSuffix(strFilePath, "_g.tif")), mDstGray);
		
		AfxMessageBox("OK!");
	}
}

int PersonalCalcGradeAdd(cv::Mat& mSrcGray, cv::Mat& mDstGray)
{
	cv::Mat mGray = mSrcGray;
	mDstGray = mGray.clone();
	for (int j = 0; j < mGray.rows; ++j)
	{
		uchar* data = mGray.ptr<uchar>(j);
		uchar* dataDst = mDstGray.ptr<uchar>(j);
		for (int i = 0; i < mGray.cols; ++i)
		{
			if (j < mGray.rows - 1 && i < mGray.cols - 1)
			{
				uchar* dataNR = mGray.ptr<uchar>(j + 1);
				dataDst[i] = (abs(data[i + 1] - data[i]) + abs(dataNR[i] - data[i])) / 2;
			}
			else
			{
				//最后一行和最后一列的处理
				if (j == mGray.rows - 1)
				{
					uchar* dataPR = mDstGray.ptr<uchar>(j - 1);
					dataDst[i] = dataPR[i];
				}

				if (i == mGray.cols - 1)
				{
					dataDst[i] = dataDst[i - 1];
				}
			}
		}
	}

	//加入scharr的计算
	cv::Mat mPGrade, mScharr;
	CalcGrade(mGray, mScharr);

	int nDilateElementSize = 2;
	cv::Mat elementDilate = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(2 * nDilateElementSize + 1,
		2 * nDilateElementSize + 1), cv::Point(nDilateElementSize, nDilateElementSize));
	cv::dilate(mDstGray, mPGrade, elementDilate);
	cv::dilate(mScharr, mScharr, elementDilate);

	int nErodeElementSize = 1;
	cv::Mat elementErode = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(2 * nErodeElementSize + 1,
		2 * nErodeElementSize + 1), cv::Point(nErodeElementSize, nErodeElementSize));
	cv::erode(mPGrade, mPGrade, elementErode);
	cv::erode(mScharr, mScharr, elementErode);

#ifdef _DEBUG
	cv::imwrite("D:\\mPGrade.tif", mPGrade);
	cv::imwrite("D:\\mScharr.tif", mScharr);
#endif // _DEBUG
	cv::bitwise_not(mPGrade, mPGrade);
	cv::bitwise_not(mScharr, mScharr);
#ifdef _DEBUG
	cv::imwrite("D:\\mNotPGrade.tif", mPGrade);
	cv::imwrite("D:\\mNotScharr.tif", mScharr);
#endif // _DEBUG
	cv::addWeighted(mPGrade, 0.5, mScharr, 0.5, 0, mDstGray);

	//int height = mScharr.rows;
	//int width = mScharr.cols;
	//for (int j = 0; j < height; ++j)
	//{
	//	const uchar* data1 = mScharr.ptr<uchar>(j);
	//	uchar* data2 = mDst.ptr<uchar>(j);
	//	for (int i = 0; i < width; ++i)
	//	{
	//		if (abs(data2[i]) < 10)
	//		{
	//			data2[i] = 0;
	//		}
	//		else
	//		{
	//			data2[i] = data2[i] + data1[i] > 255 ? 255 : data2[i] + data1[i];
	//		}
	//	}
	//}

	//按位取反

#ifdef _DEBUG
	cv::imwrite("D:\\mDst.tif", mDstGray);
#endif // _DEBUG

	return 0;
}

void COpenCVFunctionTestDlg::OnBnClickedButtonMergegrade()
{
	// TODO: 在此添加控件通知处理程序代码
	CString strFilePath = sdf.OpenSuffixFile(".tif");

	if (strFilePath.GetLength())
	{
		cv::Mat mSrcGray= cv::imread(sdf.CString2Char(strFilePath), CV_LOAD_IMAGE_GRAYSCALE);
		if (!mSrcGray.data)
			return;

		cv::Mat mDstGray;
		cv::blur(mSrcGray, mSrcGray, cv::Size(3,3));

		PersonalCalcGradeAdd(mSrcGray, mDstGray);

		AfxMessageBox("OK!");
	}
}

//十字膨胀,为了留下四个边角区域
int TenExpandRect(std::vector<cv::Point>& vRect, std::vector<cv::Point>& vRes1, std::vector<cv::Point>& vRes2, const double dThick = 0.10)
{
	//将第一个添加到末尾方便计算
	std::vector<cv::Point> vRect5 = vRect;
	vRect5.push_back(vRect[0]);
	double dLeftProp =  1.0 + dThick;
	std::vector<cv::Point> vTmp;
	for (int i = 0; i < vRect5.size() - 1; ++i)
	{
		cv::Point p1 = cv::Point(vRect5[i].x * dLeftProp + vRect5[i + 1].x * (1 - dLeftProp), vRect5[i].y * dLeftProp + vRect5[i + 1].y * (1 - dLeftProp));
		cv::Point p2 = cv::Point(vRect5[i + 1].x * dLeftProp + vRect5[i].x * (1 - dLeftProp), vRect5[i + 1].y * dLeftProp + vRect5[i].y * (1 - dLeftProp));

		vTmp.push_back(p1);
		vTmp.push_back(p2);
	}

	//
	dLeftProp = 1.0 - dThick;
	cv::Point p1 = cv::Point(vTmp[0].x * dLeftProp + vTmp[5].x * (1 - dLeftProp), vTmp[0].y * dLeftProp + vTmp[5].y * (1 - dLeftProp));
	cv::Point p2 = cv::Point(vTmp[1].x * dLeftProp + vTmp[4].x * (1 - dLeftProp), vTmp[1].y * dLeftProp + vTmp[4].y * (1 - dLeftProp));
	cv::Point p3 = cv::Point(vTmp[4].x * dLeftProp + vTmp[1].x * (1 - dLeftProp), vTmp[4].y * dLeftProp + vTmp[1].y * (1 - dLeftProp));
	cv::Point p4 = cv::Point(vTmp[5].x * dLeftProp + vTmp[0].x * (1 - dLeftProp), vTmp[5].y * dLeftProp + vTmp[0].y * (1 - dLeftProp));

	vRes1.push_back(p1);
	vRes1.push_back(p2);
	vRes1.push_back(p3);
	vRes1.push_back(p4);

	p1 = cv::Point(vTmp[7].x * dLeftProp + vTmp[2].x * (1 - dLeftProp), vTmp[7].y * dLeftProp + vTmp[2].y * (1 - dLeftProp));
	p2 = cv::Point(vTmp[2].x * dLeftProp + vTmp[7].x * (1 - dLeftProp), vTmp[2].y * dLeftProp + vTmp[7].y * (1 - dLeftProp));
	p3 = cv::Point(vTmp[3].x * dLeftProp + vTmp[6].x * (1 - dLeftProp), vTmp[3].y * dLeftProp + vTmp[6].y * (1 - dLeftProp));
	p4 = cv::Point(vTmp[6].x * dLeftProp + vTmp[3].x * (1 - dLeftProp), vTmp[6].y * dLeftProp + vTmp[3].y * (1 - dLeftProp));

	vRes2.push_back(p1);
	vRes2.push_back(p2);
	vRes2.push_back(p3);
	vRes2.push_back(p4);

	return 0;
}

int FeatherHouse(cv::Mat m16uCommon, const int& nFeatherRadius/* = FEATHER_RADIUS_M*/, const int& nValue/* = HOUSE_VALUE*/)
{
	//只对房子进行羽化
	cv::imwrite("D:\\m16uCommon0.tif", m16uCommon);
	cv::Mat mHouseMask, mHouse;
	cv::inRange(m16uCommon, nValue, nValue, mHouseMask);
	m16uCommon.copyTo(mHouse, mHouseMask);
	cv::blur(mHouse, mHouse, cv::Size(nFeatherRadius * 2, nFeatherRadius * 2));
	cv::bitwise_not(mHouseMask, mHouseMask);
	cv::Mat mAdd = cv::Mat::zeros(m16uCommon.size(), m16uCommon.type());
	mHouse.copyTo(mAdd, mHouseMask);
	cv::addWeighted(m16uCommon, 1.0, mAdd, 1.0, 0.0, m16uCommon);
	cv::imwrite("D:\\m16uCommon1.tif", m16uCommon);

	return 0;
}

void COpenCVFunctionTestDlg::OnBnClickedButtonTenexpand()
{
	// TODO: 在此添加控件通知处理程序代码

	cv::Mat mCanvas = cv::Mat::zeros(cv::Size(800, 600), CV_8UC3);
	
	std::vector<cv::Point> vRect, vRes1, vRes2;
	vRect.push_back(cv::Point(190, 10));
	vRect.push_back(cv::Point(103, 174));
	vRect.push_back(cv::Point(407, 322));
	vRect.push_back(cv::Point(487, 155));

	//偏移图像
	for (int i = 0; i < vRect.size(); ++i)
	{
		vRect[i].x += 120;
		vRect[i].y += 100;
	}

	TenExpandRect(vRect, vRes1, vRes2, 0.20);

	for (int i = 0; i < vRect.size(); ++i)
	{
		if (i == vRect.size() - 1)
		{
			cv::line(mCanvas, vRect[i], vRect[0], CV_RGB(0, 255, 0), 2);
		}
		else
		{
			cv::line(mCanvas, vRect[i], vRect[i + 1], CV_RGB(0, 255, 0), 2);
		}
	}
	
	for (int i = 0; i < vRes1.size(); ++i)
	{
		if (i == 3)
		{
			cv::line(mCanvas, vRes1[i], vRes1[0], CV_RGB(255, 0, 0), 2);
		}
		else
		{
			cv::line(mCanvas, vRes1[i], vRes1[i + 1], CV_RGB(255, 0, 0), 2);
		}
	}

	for (int i = 0; i < vRes2.size(); ++i)
	{
		if (i == 3)
		{
			cv::line(mCanvas, vRes2[i], vRes2[0], CV_RGB(255, 0, 0), 2);
		}
		else
		{
			cv::line(mCanvas, vRes2[i], vRes2[i + 1], CV_RGB(255, 0, 0), 2);
		}
	}

	cv::imshow("tmp", mCanvas);

	std::vector<std::vector<cv::Point>> vContours;
	vContours.push_back(vRect);
	vContours.push_back(vRes1);
	vContours.push_back(vRes2);
	cv::Mat mRes = cv::Mat::zeros(cv::Size(800, 600), CV_8UC1);

	for (int i = 0; i < vContours.size(); ++i)
	{
		cv::drawContours(mRes, vContours, i, cv::Scalar(200), -1);
	}

	FeatherHouse(mRes, 5, 200);

	cv::imshow("res", mRes);

	cv::waitKey();
	cv::destroyAllWindows();
}


void COpenCVFunctionTestDlg::OnBnClickedButtonFillfeather()
{
	// TODO: 在此添加控件通知处理程序代码
	cv::Mat mCanvas = cv::Mat::zeros(cv::Size(800, 600), CV_8UC1);


	std::vector<cv::Point> vPts;
	std::vector<std::vector<cv::Point>> vContours;

	vPts.push_back(cv::Point(190, 10));
	vPts.push_back(cv::Point(103, 174));
	vPts.push_back(cv::Point(200, 300));
	vPts.push_back(cv::Point(407, 322));
	vPts.push_back(cv::Point(487, 155));

	vContours.push_back(vPts);
	cv::drawContours(mCanvas, vContours, 0, cv::Scalar(200), CV_FILLED);
	FeatherHouse(mCanvas, 5, 200);

	cv::imwrite("D:\\res.tif", mCanvas);
}

void COpenCVFunctionTestDlg::OnBnClickedButtonBgfill()
{
	// TODO: 在此添加控件通知处理程序代码
	CString strFilePath = sdf.OpenSuffixFile(".tif");

	if (strFilePath.GetLength())
	{
		cv::Mat mSrcGray= cv::imread(sdf.CString2Char(strFilePath), CV_LOAD_IMAGE_GRAYSCALE);
		if (!mSrcGray.data)
			return;

		cv::Mat mDst;
		std::vector<cv::Point> vSeeds;
		vSeeds.push_back(cv::Point(0, 0));
		vSeeds.push_back(cv::Point(0, mSrcGray.rows - 1));
		vSeeds.push_back(cv::Point(mSrcGray.cols - 1, mSrcGray.rows - 1));
		vSeeds.push_back(cv::Point(mSrcGray.cols - 1, 0));

		for (int i = 0; i < vSeeds.size(); ++i)
		{
			cv::floodFill(mSrcGray, vSeeds[i], cv::Scalar(255));
		}

		//PersonalCalcGradeAdd(mSrcGray, mDst);
		std::string strSavePath = sdf.ReplaceSuffix(sdf.CString2Char(strFilePath), "f.tif");
		cv::imwrite(strSavePath.c_str(), mSrcGray);

		AfxMessageBox("OK!");
	}
}

int PersonalAddSrcGray(cv::Mat& srcDst, const cv::Mat& srcAdd)
{
	int width = srcDst.cols;
	int height = srcDst.rows;

	for (int j = 0; j < height; ++j)
	{
		uchar* dataDst = srcDst.ptr<uchar>(j);
		const uchar* data2 = srcAdd.ptr<uchar>(j);
		for (int i = 0; i < width; ++i)
		{
			if (dataDst[i] == 255 || data2[i] == 255)
			{
				//如果一边是边界,则输出边界
				dataDst[i] = 255;
			}
			else if (data2[i] < GRAD_MIN)
			{
				if (dataDst[i] < GRAD_MIN)
				{
					dataDst[i] -= 2;
				}
				else
				{
					dataDst[i] = 8;	//10 - 2
				}
			}
			else if (data2[i] > GRAD_MAX)
			{
				if (dataDst[i] < GRAD_MIN)
				{
					dataDst[i] = dataDst[i];
				}
				else if (dataDst[i] > GRAD_MAX)
				{
					dataDst[i] += 10;
				}
				else
				{
					dataDst[i] = HOUSE_VALUE + 10;
				}
			}
			else
			{
				if (dataDst[i] >= GRAD_MIN && dataDst[i] <= GRAD_MAX)
				{
					dataDst[i] = (dataDst[i] + data2[i]) / 2;
				}
				else
				{
					dataDst[i] = dataDst[i];
				}
			}
		}
	}

	return 0;
}

void COpenCVFunctionTestDlg::OnBnClickedButtonAddtif()
{
	// TODO: 在此添加控件通知处理程序代码
	CString strFilePath = sdf.OpenSuffixFile(".tif");


	if (strFilePath.GetLength())
	{
		cv::Mat MatC2= cv::imread(sdf.CString2Char(strFilePath), CV_LOAD_IMAGE_GRAYSCALE);
		if (!MatC2.data)
			return;

		cv::Mat mDst(MatC2.size(), CV_8UC1, cv::Scalar(100));
		PersonalAddSrcGray(mDst, MatC2);
		cv::imwrite("D:\\PersonalAddSrcGray.tif", mDst);

		AfxMessageBox("OK!");
	}
}


void COpenCVFunctionTestDlg::OnBnClickedButtonMat2txt()
{
	// TODO: 在此添加控件通知处理程序代码
	CString strFilePath = sdf.OpenSuffixFile(".tif");


	if (strFilePath.GetLength())
	{
		cv::Mat mSrcGray= cv::imread(sdf.CString2Char(strFilePath), CV_LOAD_IMAGE_GRAYSCALE);
		if (!mSrcGray.data)
			return;
		
		CStringArray arrContentInFile;
		for (int j = 0; j < mSrcGray.rows; ++j)
		{
			const uchar* data = mSrcGray.ptr<uchar>(j);
			CString strLine, strCoor;
			for (int i = 0; i < mSrcGray.cols; ++i)
			{
				strCoor.Format("x = %d, y = %d, v = %d\t", i, j, data[i]);
				strLine += strCoor;
			}
			strLine += "\n";
			arrContentInFile.Add(strLine);
		}

		CString strTxtPath = sdf.ReplaceSuffix(strFilePath, ".txt");
		sdf.SaveTXTFile(strTxtPath, arrContentInFile);

		AfxMessageBox("OK!Saved to\n" + strTxtPath);
	}
}


void COpenCVFunctionTestDlg::OnBnClickedButtonFindroad()
{
	// TODO: 在此添加控件通知处理程序代码
	//CString strDirPath = sdf.BrowseDir();
	CString strDirPath = "J:\\test13p\\geocode\\tmp_ph";
	CStringArray arrFiles;
	sdf.ReadDirFiles(strDirPath, &arrFiles, ".tif");

	CString strSaveDir = "D:\\Roads";
	CreateDirectory(strSaveDir, NULL);
	for (int i = 0; i < arrFiles.GetCount(); ++i)
	{
		CString strFilePath = arrFiles[i];
		cv::Mat mSrcGray= cv::imread(sdf.CString2Char(strFilePath), CV_LOAD_IMAGE_GRAYSCALE);
		if (!mSrcGray.data)
			return;
		//寻找是路的区域
		//根据形状和面积来判断是路的可能性
		cv::Mat mRoad;
		//虽然注释中说明的是开区间,但是经过测试,实际上是闭区间
		//注意在opencv3.0当中,cv::inRange的两个参数的值的意义发生变化,在3.0中是闭区间
		cv::inRange(mSrcGray, ROAD_VALUE, ROAD_VALUE + 1, mRoad);

		cv::imshow("mRoad", mRoad);
		int an = 2;
		cv::Mat element = getStructuringElement(MORPH_ELLIPSE, Size(an*2+1, an*2+1), Point(an, an) );
		cv::erode(mRoad, mRoad, element);
		element = getStructuringElement(MORPH_ELLIPSE, Size(an*2+1, an*2+1), Point(an, an) );
		cv::dilate(mRoad, mRoad, element);
 		cv::imshow("ED", mRoad);

		int nk = cv::waitKey();
		if (nk == 'e' || nk == 27)
		{
			break;
		}
		else
		{
			cv::imwrite(sdf.CString2Char(strSaveDir + "\\" + sdf.Int2Cstring(i) + ".tif"), mRoad);
		}

	}
	cv::destroyAllWindows();
}

int FeatherByPoint(cv::Mat& mSrcGray, const cv::Point& pt, const int& nRadius = 30, const int& nMaxValue = 30)
{
	if (mSrcGray.depth() == CV_8UC1)
	{
		for (int j = 0; j < mSrcGray.rows; ++j)
		{
			uchar * data = mSrcGray.ptr<uchar>(j);
			for (int i = 0; i < mSrcGray.cols; ++i)
			{
				double dGap = sqrt((double)(i - pt.x) * (i - pt.x) + (j - pt.y) * (j - pt.y));
				if (dGap <= nRadius)
				{
					int v = data[i];
					v += int((1 - dGap / nRadius) * nMaxValue);
					if (v > 255)
					{
						data[i] = 255;
					}
					else
					{
						data[i] = v;
					}
				}
			}
		}
	}
	else if (mSrcGray.depth() == CV_16UC1)
	{
		for (int j = 0; j < mSrcGray.rows; ++j)
		{
			ushort * data = mSrcGray.ptr<ushort>(j);
			for (int i = 0; i < mSrcGray.cols; ++i)
			{
				double dGap = sqrt((double)(i - pt.x) * (i - pt.x) + (j - pt.y) * (j - pt.y));
				if (dGap <= nRadius)
				{
					int v = data[i];
					v += int((1 - dGap / nRadius) * nMaxValue);
					if (v > 65535)
					{
						data[i] = 65535;
					}
					else
					{
						data[i] = v;
					}
				}
			}
		}
	}

	return 0;
}

void COpenCVFunctionTestDlg::OnBnClickedButtonPointfeather()
{
	// TODO: 在此添加控件通知处理程序代码
	CString strFilePath = sdf.OpenSuffixFile(".tif");


	if (strFilePath.GetLength())
	{
		cv::Mat mSrcGray= cv::imread(sdf.CString2Char(strFilePath), CV_LOAD_IMAGE_GRAYSCALE);
		if (!mSrcGray.data)
			return;
		cv::imshow("src", mSrcGray);
		//把mSrcGray转化成16u
		cv::Mat m16uC1;
		mSrcGray.convertTo(m16uC1, CV_16UC1, 257);

		FeatherByPoint(m16uC1, cv::Point(100, 100), 50, 65535);
		cv::imshow("res", m16uC1);
		cv::waitKey();
	}
}


void COpenCVFunctionTestDlg::OnBnClickedButtonDrawcontours()
{
	// TODO: 在此添加控件通知处理程序代码
	CString strFilePath = sdf.OpenSuffixFile(".tif");


	if (strFilePath.GetLength())
	{
		cv::Mat mSrcGray= cv::imread(sdf.CString2Char(strFilePath));
		if (!mSrcGray.data)
			return;
		
		std::vector<std::vector<cv::Point>> vContours;
		std::vector<cv::Point> contour;
		contour.push_back(cv::Point(139, 9));
		contour.push_back(cv::Point(139, 10));
		contour.push_back(cv::Point(137, 10));
		contour.push_back(cv::Point(137, 16));
		contour.push_back(cv::Point(139, 16));
		contour.push_back(cv::Point(139, 17));
		contour.push_back(cv::Point(140, 17));
		contour.push_back(cv::Point(140, 16));
		contour.push_back(cv::Point(142, 16));
		contour.push_back(cv::Point(142, 15));
		contour.push_back(cv::Point(143, 15));
		contour.push_back(cv::Point(143, 11));
		contour.push_back(cv::Point(142, 11));
		contour.push_back(cv::Point(142, 10));
		contour.push_back(cv::Point(140, 10));
		contour.push_back(cv::Point(140, 9));

		vContours.push_back(contour);

		cv::drawContours(mSrcGray, vContours, 0, cv::Scalar(0, 255, 0), -1);

		cv::imshow("res", mSrcGray);
		cv::waitKey();
	}

}

int GetShortestPathOnImg(cv::Mat& mSrc, cv::Point& pStart, cv::Point& pEnd, std::vector<cv::Point>& vPathPts);
int PutCoorInRect(const int& nWidth, const int& nHeight, int& nX, int& nY)
{
	int nChange = 0;

	if (nX < 0)
	{
		nX = 0;
		++nChange;
	}

	if (nY < 0)
	{
		nY = 0;
		++nChange;
	}

	if (nX >= nWidth)
	{
		nX = nWidth - 1;
		++nChange;
	}

	if (nY >= nHeight)
	{
		nY = nHeight - 1;
		++nChange;
	}

	return nChange;
}

void COpenCVFunctionTestDlg::OnBnClickedButtonBigShortest()
{
	// TODO: 在此添加控件通知处理程序代码
	//读取配置文件,输出路径以及图像
	std::string strIniPath = "bigShortest.ini";
	std::fstream _file;
	_file.open(strIniPath, std::ios::in);
	bool bRes = (bool)_file != 0;
	_file.close();

	CSimpleIni Ini;
	Ini.SetUnicode();

	cv::Point ptStart, ptEnd;

	std::string strTifPath = "a.tif";
	std::fstream _filet;
	_filet.open(strTifPath, std::ios::in);
	bool bResT = (bool)_filet != 0;
	_filet.close();

	if (!bResT)
	{
		strTifPath = std::string(sdf.CString2Char(sdf.OpenSuffixFile(".tif")));
		if (!strTifPath.length())
		{
			return;
		}
	}

	cv::Mat mSrcGray = cv::imread(strTifPath.c_str(), CV_LOAD_IMAGE_GRAYSCALE);

	if (bRes)
	{
		Ini.LoadFile(strIniPath.c_str());

		ptStart.x = Ini.GetLongValue("ShortestPath", "StartX", 0);
		ptStart.y = Ini.GetLongValue("ShortestPath", "StartY", 0);
		ptEnd.x = Ini.GetLongValue("ShortestPath", "EndX", mSrcGray.cols - 1);
		ptEnd.y = Ini.GetLongValue("ShortestPath", "EndY", mSrcGray.rows - 1);
	}
	else
	{

		Ini.SetLongValue("ShortestPath", "StartX", 0);
		Ini.SetLongValue("ShortestPath", "StartY", 0);
		Ini.SetLongValue("ShortestPath", "EndX", mSrcGray.cols - 1);
		Ini.SetLongValue("ShortestPath", "EndY", mSrcGray.rows - 1);
		Ini.SaveFile(strIniPath.c_str());
		ptStart.x = 0;
		ptStart.y = 0;
		ptEnd.x = mSrcGray.cols - 1;
		ptEnd.y = mSrcGray.rows - 1;
	}

	cv::Mat mPyramid(mSrcGray);
	int nP = 1;
	do 
	{
		nP *= 2;
		cv::Mat mTmp;
		cv::pyrDown(mPyramid, mTmp);
		mPyramid = mTmp;

	} while (mPyramid.rows * mPyramid.step > 2 * 1024 * 1024);

	cv::Point ptStartPy(ptStart.x / nP, ptStart.y /nP);
	cv::Point ptEndPy(ptEnd.x / nP, ptEnd.y /nP);
	std::vector<cv::Point> vPyPath;

	GetShortestPathOnImg(mPyramid, ptStartPy, ptEndPy, vPyPath);

	cv::Mat mCanvas;
	cv::cvtColor(mPyramid, mCanvas, CV_GRAY2BGR);
	for (int i = 0; i < vPyPath.size() -1; ++i)
	{ 
		cv::line(mCanvas, vPyPath[i], vPyPath[i + 1], cv::Scalar(0,255,0), 1);
	}
	cv::imwrite("D:\\result.tif", mCanvas);

	//将金字塔上的结果映射到原图上,然后在原图上的每个区域进行走线
	//其中映射的比例大概为每(BLOCK_PIX_NUM / nP)个像素
	std::vector<cv::Point> vKeyPts;
	int nGap = BLOCK_PIX_NUM > nP ? BLOCK_PIX_NUM / nP : 1;
	for (int i = 0; i < vPyPath.size(); ++i)
	{
		if (i % nGap == 0)
		{
			vKeyPts.push_back(cv::Point(vPyPath[i].x * nP, vPyPath[i].y * nP));
		}
	}
	int nEnd = vPyPath.size() - 1;
	if ((nEnd) % nGap != 0)
	{
		vKeyPts.push_back(cv::Point(vPyPath[nEnd].x * nP, vPyPath[nEnd].y * nP));
	}

	std::vector<cv::Point> vWholePath;
	vWholePath.reserve(10000);
	for (int i = 0; i < vKeyPts.size() -1; ++i)
	{ 
		COneSeg os(vKeyPts[i], vKeyPts[i + 1]);
		cv::Rect rc = os.GetRect(mSrcGray.cols, mSrcGray.rows);

		cv::Mat mCurrentRoi(mSrcGray, rc);
		std::vector<cv::Point> vBlockPath;
		vBlockPath.reserve(1000);
		cv::Point ptBlockStart = cv::Point(vKeyPts[i].x - rc.x, vKeyPts[i].y - rc.y);
		cv::Point ptBlockEnd = cv::Point(vKeyPts[i + 1].x - rc.x, vKeyPts[i + 1].y - rc.y);
		PutCoorInRect(mCurrentRoi.cols, mCurrentRoi.rows, ptBlockStart.x, ptBlockStart.y);
		PutCoorInRect(mCurrentRoi.cols, mCurrentRoi.rows, ptBlockEnd.x, ptBlockEnd.y);
		GetShortestPathOnImg(mCurrentRoi, ptBlockStart, ptBlockEnd, vBlockPath);
		int nBlockPathSize = vBlockPath.size();
		for (int j = 0; j < nBlockPathSize; ++j)
		{
			vBlockPath[j].x += rc.x;
			vBlockPath[j].y += rc.y;
		}

		if (vWholePath.size() > 0)
		{
			cv::Point ptLastBlockLastPoint = vWholePath[vWholePath.size() - 1];
			if (ptLastBlockLastPoint == vBlockPath[0])
			{
				vBlockPath.erase(vBlockPath.begin());
			}
		}
		vWholePath.insert(vWholePath.end(), vBlockPath.begin(), vBlockPath.end());
	}

	cv::cvtColor(mSrcGray, mCanvas, CV_GRAY2BGR);
	for (int i = 0; i < vWholePath.size() -1; ++i)
	{ 
		cv::line(mCanvas, vWholePath[i], vWholePath[i + 1], cv::Scalar(0,255,0), 2);
	}
	cv::imwrite("D:\\resultOri.tif", mCanvas);
}


void COpenCVFunctionTestDlg::OnBnClickedButtonPyramid()
{
	// TODO: 在此添加控件通知处理程序代码
	std::string strTifPath = "a.tif";
	std::fstream _filet;
	_filet.open(strTifPath, std::ios::in);
	bool bResT = (bool)_filet != 0;
	_filet.close();

	if (!bResT)
	{
		strTifPath = std::string(sdf.CString2Char(sdf.OpenSuffixFile(".tif")));
		if (!strTifPath.length())
		{
			return;
		}
	}

	cv::Mat mSrcGray = cv::imread(strTifPath.c_str());


	cv::Mat mPyramid(mSrcGray);
	int nP = 1;
	do 
	{
		nP *= 2;
		cv::Mat mTmp;
		cv::pyrDown(mPyramid, mTmp);
		cv::imwrite(strTifPath + "_" + sdf.CString2Char(sdf.Int2Cstring(nP) + sdf.GetNameOfSuffix(strTifPath.c_str())), mTmp);
		mPyramid = mTmp;

	} while (mPyramid.rows * mPyramid.step > 20 * 1024 * 1024);

	AfxMessageBox("Over!");
}

void CubicTest();
void COpenCVFunctionTestDlg::OnBnClickedButtonCubic()
{
	// TODO: 在此添加控件通知处理程序代码
	CubicTest();

	AfxMessageBox("Over!");
}


void COpenCVFunctionTestDlg::OnBnClickedButtonOverflow()
{
	// TODO: 在此添加控件通知处理程序代码
	cv::Mat mSrcGray =  cv::Mat::zeros(cv::Size(800, 600), CV_8UC1);

	int m = 0;
	for (int j = 0; j < mSrcGray.rows; ++j)
	{
		uchar* data = mSrcGray.ptr<uchar>(j);
		for (int i = 0; i < mSrcGray.cols; ++i)
		{
			data[i] = m++;
		}
	}

	cv::imwrite("D:\\overflow.tif", mSrcGray);
	AfxMessageBox("Over!");
}


void COpenCVFunctionTestDlg::OnBnClickedButtonDrawfill()
{
	// TODO: 在此添加控件通知处理程序代码
	cv::Mat mSrcGray = cv::Mat::zeros(cv::Size(20, 20), CV_8UC1);
	std::vector<std::vector<cv::Point>> contours;

	std::vector<cv::Point> vPts;
	vPts.push_back(cv::Point(0,0));
	vPts.push_back(cv::Point(3,3));
	vPts.push_back(cv::Point(3,5));
	contours.push_back(vPts);
	vPts.clear();
	vPts.push_back(cv::Point(6,6));
	vPts.push_back(cv::Point(6,6));
	vPts.push_back(cv::Point(6,6));
	vPts.push_back(cv::Point(6,6));
	contours.push_back(vPts);
	vPts.clear();
	vPts.push_back(cv::Point(12,12));
	vPts.push_back(cv::Point(12,18));
	vPts.push_back(cv::Point(18,18));
	vPts.push_back(cv::Point(18,17));
	contours.push_back(vPts);

	for (int i = 0; i < contours.size(); ++i)
	{
		cv::drawContours(mSrcGray, contours, i, cv::Scalar(255), -1);
	}

	cv::imwrite("D:\\DrawFill.tif", mSrcGray);
	AfxMessageBox("Over!");
}

bool RectIntersect(const cv::Rect& rSrc, const cv::Rect& rIn, cv::Rect& rRes)
{
	int nSrcRight = rSrc.x + rSrc.width;
	int nSrcDown = rSrc.y + rSrc.height;
	int nInRight = rIn.x + rIn.width;
	int nInDown = rIn.y + rIn.height;

	//如果不相交
	if (nInRight < rSrc.x || rIn.x >= nSrcRight || rIn.y >= nSrcDown || nInDown < rSrc.y)
	{
		return false;
	}

	int x = rSrc.x > rIn.x ? rSrc.x : rIn.x;
	int y = rSrc.y > rIn.y ? rSrc.y : rIn.y;
	int right = nSrcRight < nInRight ? nSrcRight : nInRight;
	int down = nSrcDown < nInDown ? nSrcDown : nInDown;
	int width = right - x;
	int height = down - y;

	rRes = cv::Rect(x - rSrc.x, y - rSrc.y, width, height);

	return true;
}

void COpenCVFunctionTestDlg::OnBnClickedButtonRectboundary()
{
	// TODO: 在此添加控件通知处理程序代码
// 	COneSeg os(-10,-10,20,30);
// 	std::vector<cv::Point> vLinePts = os.GetLinePoints();

	cv::Rect rect1(0,0,30,30), rect2(30,30,1,1);
	RectIntersect(rect1, rect2, rect1);

	cv::Mat mCanvas = cv::Mat(cv::Size(80, 60), CV_16UC1, cv::Scalar(65535));
	cv::Mat mRoi = mCanvas(rect1);
	cv::Rect rc(79, 59, 1, 1);

	if (rc.contains(cv::Point(79,59)))
	{
		cv::Mat m = mCanvas(rc);

		cv::imshow("RC", m);
		cv::waitKey();
	}
}

void COpenCVFunctionTestDlg::OnBnClickedButtonScalemat()
{
	CString strFilePath = sdf.OpenSuffixFile(".tif");

	if (strFilePath.GetLength())
	{
		cv::Mat mSrcGray= cv::imread(sdf.CString2Char(strFilePath), CV_LOAD_IMAGE_GRAYSCALE);
		if (!mSrcGray.data)
			return;

		ScaleMat(mSrcGray, mSrcGray, HOUSESUS_VALUE);

		std::string strSavePath = sdf.ReplaceSuffix(sdf.CString2Char(strFilePath), "scale.tif");
		cv::imwrite(strSavePath.c_str(), mSrcGray);

		AfxMessageBox("OK!");
	}
}

bool FindCommonRect(const geodetic& gLU1, const geodetic& gRD1, const geodetic& gLU2, const geodetic& gRD2, geodetic& gCLU, geodetic& gCRD)
{
	gCLU.x = gLU1.x > gLU2.x ? gLU1.x : gLU2.x;
	gCLU.y = gLU1.y < gLU2.y ? gLU1.y : gLU2.y;

	gCRD.x = gRD1.x < gRD2.x ? gRD1.x : gRD2.x;
	gCRD.y = gRD1.y > gRD2.y ? gRD1.y : gRD2.y;

	if (gCLU.x >= gCRD.x)
	{
		return false;
	}

	if (gCLU.y <= gCRD.y)
	{
		return false;
	}

	return true;
}

bool GetTifInter(cv::Mat& mSrcGray1, CTfwReader tr1, cv::Mat& mSrcGray2, CTfwReader tr2, cv::Mat& mDst, CTfwReader trDst,
	double& dXOverlap, double& dYOverlap, const int& nMethod = 0)
{
	double dX1 = 0;
	double dY1 = 0;
	double dX2 = 0;
	double dY2 = 0;

	tr1.CalcGeoCoordinate(mSrcGray1.cols, mSrcGray1.rows, dX1, dY1);
	tr2.CalcGeoCoordinate(mSrcGray2.cols, mSrcGray2.rows, dX2, dY2);

	geodetic gCLU, gCRD;
	if (FindCommonRect(geodetic(tr1.m_dXCoordinate, tr1.m_dYCoordinate), geodetic(dX1, dY1), geodetic(tr2.m_dXCoordinate, tr2.m_dYCoordinate), geodetic(dX2, dY2), gCLU, gCRD))
	{
		//得到了相交的范围
		int nX1 = 0, nY1 = 0, nX2 = 0, nY2 = 0;
		int nX3 = 0, nY3 = 0, nX4 = 0, nY4 = 0;
		tr1.CalcPixCoordinate(gCLU.x, gCLU.y, nX1, nY1);
		tr1.CalcPixCoordinate(gCRD.x, gCRD.y, nX2, nY2);
		tr2.CalcPixCoordinate(gCLU.x, gCLU.y, nX3, nY3);
		tr2.CalcPixCoordinate(gCRD.x, gCRD.y, nX4, nY4);

		cv::Rect r1 = cv::Rect(nX1, nY1, (nX2 - nX1), (nY2 - nY1));
		cv::Rect r2 = cv::Rect(nX3, nY3, (nX4 - nX3), (nY4 - nY3));

		r1.width = r1.width < r2.width ? r1.width : r2.width;
		r1.height = r1.height < r2.height ? r1.height : r2.height;
		r2.width = r1.width;
		r2.height = r1.height;

		//保证不越界
		while (r1.x + r1.width > mSrcGray1.cols || r2.x + r2.width > mSrcGray2.cols)
		{
			--r1.width;
			--r2.width;
		}

		while (r1.y + r1.height > mSrcGray1.rows || r2.y + r2.height > mSrcGray2.rows)
		{
			--r1.height;
			--r2.height;
		}

		if (r1.width > 0 && r1.height > 0 && r2.width > 0 && r2.height > 0)
		{
			double dWidth = r1.width, dHeight = r1.height;
			dXOverlap = (dWidth / mSrcGray1.cols + dWidth/ mSrcGray2.cols) / 2;
			dYOverlap = (dHeight / mSrcGray1.rows + dHeight / mSrcGray2.rows) / 2;
			cv::Mat MatC1(mSrcGray1, r1);
			cv::Mat MatC2(mSrcGray2, r2);
			//输出灰度图
			switch (nMethod)
			{
			case 0:
				cv::absdiff(MatC1, MatC2, mDst);
			case 1:
				break;
			default:
				break;
			}

			trDst.m_dXCoordinate = gCLU.x;
			trDst.m_dYCoordinate = gCLU.y;
			trDst.m_dXResolution = tr1.m_dXResolution;
			trDst.m_dYResolution = tr1.m_dYResolution;
			trDst.m_dXRotatePara = tr1.m_dXRotatePara;
			trDst.m_dYRotatePara = tr1.m_dYRotatePara;

			//正常情况下到达此处
			return true;
		}
	}

	return false;
}

void COpenCVFunctionTestDlg::OnBnClickedButtonTifsub()
{
	CString strDirPath = sdf.BrowseDir();
	std::list<CString> lFilesInDir;
	sdf.ReadDirFiles(strDirPath, lFilesInDir, ".tif", false);

	if (lFilesInDir.size() != 2)
	{
		MessageBox("影像数目不对,只能为2张!", "提示!", MB_ICONERROR);
		return;
	}

	CString strTif1 = *(lFilesInDir.begin());
	CString strTif2 = *(lFilesInDir.rbegin());

	cv::Mat mGray1= cv::imread(sdf.CString2Char(strTif1), CV_LOAD_IMAGE_GRAYSCALE);
	cv::Mat mGray2= cv::imread(sdf.CString2Char(strTif2), CV_LOAD_IMAGE_GRAYSCALE);

	CString strTfw1 = sdf.ReplaceSuffix(strTif1, ".tfw");
	CString strTfw2 = sdf.ReplaceSuffix(strTif2, ".tfw");

	cv::Mat mDstGray;
	CString strSavePath = sdf.AppendSlash(sdf.GetDirOfFile(strTif1)) + "result.tif";

	if (!sdf.IfExistsFile(strTfw1) || !sdf.IfExistsFile(strTfw2))
	{
		if (mGray1.size() == mGray2.size())
		{
			//图像直接相减
			cv::absdiff(mGray1, mGray2, mDstGray);
			cv::imwrite(sdf.CString2Char(strSavePath), mDstGray);
		}
	}
	else
	{
		//根据tfw相减
		CTfwReader tr1(strTfw1);
		CTfwReader tr2(strTfw2);
		CTfwReader trDst(tr1);
		double dXOverlap = 0.0, dYOverlap = 0.0;

		GetTifInter(mGray1, tr1, mGray2, tr2, mDstGray, trDst, dXOverlap, dYOverlap);
		cv::imwrite(sdf.CString2Char(strSavePath), mDstGray);
		trDst.SaveAsTfwFile(sdf.ReplaceSuffix(strSavePath, ".tfw"));
	}

	MessageBox("处理完成!", "提示!", MB_ICONINFORMATION);
}

int SurfPics(const std::string strPic1, const std::string strPic2);
int SurfPics2(const std::string strPic1, const std::string strPic2);
void COpenCVFunctionTestDlg::OnBnClickedButtonSurf()
{
	// TODO: 在此添加控件通知处理程序代码
	CString strPic1 = sdf.OpenSuffixFile(".tif");
	CString strPic2 = sdf.OpenSuffixFile(".tif");

	SurfPics(sdf.CString2Char(strPic1), sdf.CString2Char(strPic2));

	AfxMessageBox(_T("Over!"));
}

void COpenCVFunctionTestDlg::OnBnClickedButtonSurf2()
{
	// TODO: 在此添加控件通知处理程序代码
	CString strPic1 = sdf.OpenSuffixFile(".tif");
	CString strPic2 = sdf.OpenSuffixFile(".tif");

	SurfPics2(sdf.CString2Char(strPic1), sdf.CString2Char(strPic2));

	AfxMessageBox(_T("Over!"));
}

int Colorfloodfill(char* filename = nullptr);
void COpenCVFunctionTestDlg::OnBnClickedButtonFloodfill()
{
	// TODO: 在此添加控件通知处理程序代码
	CString strPic1 = sdf.OpenSuffixFile(".jpg");

	Colorfloodfill(sdf.CString2Char(strPic1));

	AfxMessageBox(_T("Over!"));
}

int Nearestmain(const char* szFilePath, const char* szDstDir, const char* szEvalutionPath);

void COpenCVFunctionTestDlg::OnBnClickedButtonNearest()
{
	// TODO: 在此添加控件通知处理程序代码
		// TODO: 在此添加控件通知处理程序代码
	CString strPic1 = sdf.OpenSuffixFile(".bmp");

	const char* szFilePath = sdf.CString2Char(strPic1);

	//char load_srimg[] = "./data/dqh-0.6m-4.bmp";
	//char output_path[] = "./output/";
	//char evalution_path[] = "./output/evalution.txt";

	Nearestmain(szFilePath, "D:\\output\\", "D:\\output\evalution.txt");

	AfxMessageBox(_T("Over!"));
}

内容就如上面的按钮所示了,每个按钮都实现了对应的功能,不过也存在问题,比如闪退,崩溃啥的,毕竟只是测试程序,正式项目里面解决了问题但是这个测试代码未更新也是正常的。

下面是可执行程序:

下载地址:opencv249.rar - 蓝奏云文件大小:4.3 M|https://autumoon.lanzouq.com/ihx3206hompa

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值