这个小工具是当年学习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 = ¬_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!"));
}
内容就如上面的按钮所示了,每个按钮都实现了对应的功能,不过也存在问题,比如闪退,崩溃啥的,毕竟只是测试程序,正式项目里面解决了问题但是这个测试代码未更新也是正常的。
下面是可执行程序: