123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671 |
-
- // ThresholdToolsDlg.cpp: 实现文件
- //
- #include "stdafx.h"
- #include "ThresholdTools.h"
- #include "ThresholdToolsDlg.h"
- #include "afxdialogex.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #endif
- // 用于应用程序“关于”菜单项的 CAboutDlg 对话框
- class CAboutDlg : public CDialogEx
- {
- public:
- CAboutDlg();
- // 对话框数据
- #ifdef AFX_DESIGN_TIME
- enum { IDD = IDD_ABOUTBOX };
- #endif
- protected:
- virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
- // 实现
- protected:
- DECLARE_MESSAGE_MAP()
- };
- CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
- {
- }
- void CAboutDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialogEx::DoDataExchange(pDX);
- }
- BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
- END_MESSAGE_MAP()
- // CThresholdToolsDlg 对话框
- CThresholdToolsDlg::CThresholdToolsDlg(CWnd* pParent /*=nullptr*/)
- : CDialogEx(IDD_THRESHOLDTOOLS_DIALOG, pParent)
- , m_strMaxVal(_T(""))
- , m_strLeft(_T(""))
- , m_strTop(_T(""))
- , m_strRight(_T(""))
- , m_strBottom(_T(""))
- , m_bThreshold(FALSE)
- {
- m_strMaxVal = _T("255");
- m_nRadio = 0;
- m_bPress = FALSE;
- m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
- }
- void CThresholdToolsDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialogEx::DoDataExchange(pDX);
- DDX_Control(pDX, IDC_SLIDER1, m_slider);
- DDX_Text(pDX, IDC_EDIT2, m_strMaxVal);
- DDX_Control(pDX, IDC_SPIN1, m_Spin1);
- DDX_Control(pDX, IDC_SPIN2, m_Spin2);
- DDX_Control(pDX, COMBO_THRESHOLD_TYPE, m_cbThresholdType);
- DDX_Text(pDX, TX_LEFT, m_strLeft);
- DDX_Text(pDX, TX_TOP, m_strTop);
- DDX_Text(pDX, TX_RIGHT, m_strRight);
- DDX_Text(pDX, TX_BOTTOM, m_strBottom);
- DDX_Radio(pDX, RADIO_NONE, m_nRadio);
- }
- // 该函数,只用于Pictrue Control控件中,在Static不适合;
- // static text控件要使用,必须先GetDlgItem(IDC_MY_PIC)->ModifyStyle( SS_TYPEMASK, SS_OWNERDRAW );
- void CThresholdToolsDlg::DrawMat(Mat & img, UINT uId)
- {
- if (img.data == NULL)
- return;
- CRect rc;
- Mat imgTmp;
- // 获取控件大小;
- GetDlgItem(uId)->GetClientRect(&rc);
- // 按控件大小,缩小或放大图片;
- cv::resize(img, imgTmp, cv::Size(rc.Width(), rc.Height()));
- // 转换格式;
- switch (imgTmp.channels())
- {
- case 1:
- cv::cvtColor(imgTmp, imgTmp, COLOR_GRAY2BGRA);
- break;
- case 3:
- cv::cvtColor(imgTmp, imgTmp, COLOR_BGR2BGRA);
- break;
- default:
- break;
- }
- int pixelBytes = imgTmp.channels()*(imgTmp.depth() + 1); // 计算一个像素多少个字节
- // 制作bitmapinfo(数据头);
- BITMAPINFO bitInfo;
- bitInfo.bmiHeader.biBitCount = 8 * pixelBytes;
- bitInfo.bmiHeader.biWidth = imgTmp.cols;
- bitInfo.bmiHeader.biHeight = -imgTmp.rows;
- bitInfo.bmiHeader.biPlanes = 1;
- bitInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bitInfo.bmiHeader.biCompression = BI_RGB;
- bitInfo.bmiHeader.biClrImportant = 0;
- bitInfo.bmiHeader.biClrUsed = 0;
- bitInfo.bmiHeader.biSizeImage = 0;
- bitInfo.bmiHeader.biXPelsPerMeter = 0;
- bitInfo.bmiHeader.biYPelsPerMeter = 0;
- // 双缓存;
- CDC *pDC = GetDlgItem(uId)->GetDC();
- CDC MemDC; //首先定义一个显示设备对象
- CBitmap MemBitmap;//定义一个位图对象
- //随后建立与屏幕显示兼容的内存显示设备
- MemDC.CreateCompatibleDC(NULL);
- //这时还不能绘图,因为没有地方画 ^_^
- //下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小
- MemBitmap.CreateCompatibleBitmap(pDC, rc.Width(), rc.Height());
- //将位图选入到内存显示设备中
- //只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上
- CBitmap *pOldBit = MemDC.SelectObject(&MemBitmap);
- //先用背景色将位图清除干净,这里我用的是白色作为背景
- //你也可以用自己应该用的颜色
- MemDC.FillSolidRect(0, 0, rc.Width(), rc.Height(), RGB(255, 255, 255));
- // Mat.data + bitmap数据头 -> MFC
- int nRet = ::StretchDIBits(
- MemDC,
- 0, 0, rc.Width(), rc.Height(),
- 0, 0, rc.Width(), rc.Height(),
- imgTmp.data,
- &bitInfo,
- DIB_RGB_COLORS,
- SRCCOPY
- );
- //将内存中的图拷贝到屏幕上进行显示
- pDC->BitBlt(0, 0, rc.Width(), rc.Height(), &MemDC, 0, 0, SRCCOPY);
- //绘图完成后的清理
- MemBitmap.DeleteObject();
- MemDC.DeleteDC();
- ReleaseDC(pDC);
- }
- void CThresholdToolsDlg::RefreshCanvas()
- {
- CRect rc;
- GetDlgItem(IDC_IMG)->GetWindowRect(&rc);
- ScreenToClient(&rc);
- InvalidateRect(rc, FALSE);//True会闪烁;
- }
- BOOL CThresholdToolsDlg::ImgThreshold(long nThresholdVal, long nMaxThresholdVal)
- {
- GetROI();
- if (m_ImgROI.data == NULL)
- return FALSE;
- int nCurSel = m_cbThresholdType.GetCurSel();
- if (nCurSel == CB_ERR)
- return FALSE;
- switch (nCurSel)
- {
- case 0:
- {
- // 赋值效果图;
- m_pRenderings = &m_ImgShow;
- // 刷新画布区域;
- RefreshCanvas();
- }
- break;
- case 1://全局阀值;
- {
- // 转成灰阶图;
- cvtColor(m_ImgROI, m_ImgThreshold, COLOR_BGR2GRAY);
- // 再高斯模糊处理(滤波);
- GaussianBlur(m_ImgThreshold, m_ImgThreshold, Size(5, 5), 0, 0);
- // 二值化;//全局化指定的阀值与返回值相等;
- double dRetVal = threshold(m_ImgThreshold, m_ImgThreshold, nThresholdVal, nMaxThresholdVal, THRESH_BINARY);
- // 赋值效果对象;
- //m_pRenderings = &m_ImgThreshold;
- // ROI为三通道,所以必须将灰度转回BGR格式,copyTo才有效;
- cvtColor(m_ImgThreshold, m_ImgROI, COLOR_GRAY2BGR);
- // 将二值图复制ROI上;
- //m_ImgThreshold.copyTo(m_ImgROI);
- // 赋值效果图;
- m_pRenderings = &m_ImgShow;
- // 刷新画布区域;
- RefreshCanvas();
- }
- break;
- case 2://自适应阀值;
- {
- // 转成灰阶图;
- cvtColor(m_ImgROI, m_ImgThreshold, COLOR_BGR2GRAY);
- // 再高斯模糊处理(滤波);
- GaussianBlur(m_ImgThreshold, m_ImgThreshold, Size(3, 3), 0, 0);
- // 自适应阀值;
- medianBlur(m_ImgThreshold, m_ImgThreshold, 3);
- // 局部二值化;//blocksize一般取3、5、7
- adaptiveThreshold(m_ImgThreshold, m_ImgThreshold, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 3, 4.5);
- // 赋值效果对象;
- //m_pRenderings = &m_ImgThreshold;
- // ROI为三通道,所以必须将灰度转回BGR格式,copyTo才有效;
- cvtColor(m_ImgThreshold, m_ImgROI, COLOR_GRAY2BGR);
- // 将二值图复制ROI上;
- //m_ImgThreshold.copyTo(m_ImgROI);
- // 赋值效果图;
- m_pRenderings = &m_ImgShow;
- // 刷新画布区域;
- RefreshCanvas();
- }
- break;
- case 3:// otsu阀值;
- {
- cvtColor(m_ImgROI, m_ImgThreshold, COLOR_BGR2GRAY);
- // 高斯模糊;
- GaussianBlur(m_ImgThreshold, m_ImgThreshold, Size(3, 3), 0, 0);
- #if 0
- // otus;//阀值必须为0;
- Mat tempImg;
- m_ImgThreshold.copyTo(tempImg);
- double dRetVal = threshold(m_ImgThreshold, tempImg, nThresholdVal, nMaxThresholdVal, THRESH_BINARY | THRESH_OTSU);
- //TRACE1("当前阀值:%lf\n", dRetVal);
- threshold(m_ImgThreshold, m_ImgThreshold, dRetVal, nMaxThresholdVal, THRESH_BINARY);
- #else
- threshold(m_ImgThreshold, m_ImgThreshold, nThresholdVal, nMaxThresholdVal, THRESH_BINARY | THRESH_OTSU);
- #endif
- // 赋值效果对象;
- //m_pRenderings = &m_ImgThreshold;
- // ROI为三通道,所以必须将灰度转回BGR格式,copyTo才有效;
- cvtColor(m_ImgThreshold, m_ImgROI, COLOR_GRAY2BGR);
- // 将二值图复制ROI上;
- //m_ImgThreshold.copyTo(m_ImgROI);
- // 赋值效果图;
- m_pRenderings = &m_ImgShow;
- // 刷新画布区域;
- RefreshCanvas();
- }
- break;
- default:
- break;
- }
- if (m_ImgThreshold.data) {
- // 查找轮廓;
- m_contours.clear();
- m_hierarchy.clear();
- BOOL bCheck = ((CButton*)GetDlgItem(IDC_CHECK3))->GetCheck();
- if (bCheck == TRUE)
- {
- // 所有轮廓,内外轮廓分等级;
- findContours(m_ImgThreshold, m_contours, m_hierarchy, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE);
- // 所有轮廓,内外轮廓不分等级,独立;
- //findContours(m_ImgThreshold, m_contours, m_hierarchy, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE);
- }
- else
- {
- // RETR_EXTERNAL=只检索最外面的轮廓;
- findContours(m_ImgThreshold, m_contours, m_hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
- }
- }
- return TRUE;
- }
- BOOL CThresholdToolsDlg::DrawContours(BOOL bPerimeter,long nMinPerimeter, long nMaxPerimeter, BOOL bArea,long nMinArea, long nMaxArea)
- {
- //if ( m_ImgThreshold.data == NULL)
- // return FALSE;
- //
- //// 查找轮廓;
- //m_contours.clear();
- //m_hierarchy.clear();
- //BOOL bCheck = ((CButton*)GetDlgItem(IDC_CHECK3))->GetCheck();
- //if (bCheck == TRUE)
- //{
- // // 所有轮廓,内外轮廓分等级;
- // findContours(m_ImgThreshold, m_contours, m_hierarchy, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE);
- // // 所有轮廓,内外轮廓不分等级,独立;
- // //findContours(m_ImgThreshold, m_contours, m_hierarchy, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE);
- //}
- //else
- //{
- // // RETR_EXTERNAL=只检索最外面的轮廓;
- // findContours(m_ImgThreshold, m_contours, m_hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
- //}
- // 过滤不符合要求的轮廓;
- int i = 0;
- GetROI();
- m_ImgContours = m_ImgROI.clone();
- vector<vector<Point>>::iterator it = m_contours.begin();
- for ( ; it != m_contours.end(); it++,i++)
- {
- if (bPerimeter && !bArea)
- {
- if (arcLength(*it, true) < nMinPerimeter || arcLength(*it, true) > nMaxPerimeter)
- continue;
- }
- else if (!bPerimeter && bArea)
- {
- if (contourArea(*it) < nMinArea || contourArea(*it) > nMaxArea)
- continue;
- }
- else if (bArea && bPerimeter)
- {
- if ((arcLength(*it, true) < nMinPerimeter || arcLength(*it, true) > nMaxPerimeter) || (contourArea(*it) < nMinArea || contourArea(*it) > nMaxArea))
- continue;
- }
- // 填充轮廓;
- Scalar color = Scalar(rand() % 255, rand() % 255, rand() % 255);
- drawContours(m_ImgContours, m_contours, i, color, CV_FILLED, 8, m_hierarchy);
- }
- m_ImgContours.copyTo(m_ImgROI);
- m_pRenderings = &m_ImgShow;
- // 刷新画布区域;
- RefreshCanvas();
- return TRUE;
- }
- void CThresholdToolsDlg::GetPointInfo(CPoint pt, long &nPerimeter, long &nArea, Rect &rc)
- {
- long a1 = 0, p1 = 0;
- vector<vector<Point>>::iterator it = m_contours.begin();
- BOOL bCheck = ((CButton*)GetDlgItem(IDC_CHECK3))->GetCheck();
- int left = GetDlgItemInt(TX_LEFT);
- int top = GetDlgItemInt(TX_TOP);
- for (; it != m_contours.end(); it++)
- {
- // 检测点是否在轮廓内;
- if (pointPolygonTest(*it, cv::Point(pt.x, pt.y), false) == 1)
- {
- a1 = contourArea(*it);
- p1 = arcLength(*it, true);
- if (bCheck == FALSE)
- {// 外轮廓;
- nArea = a1, nPerimeter = p1;
- #if 1
- // 计算轮廓的垂直边界最小矩形,矩形是与图像上下边界平行的;
- rc = boundingRect(*it);
- rc.x = rc.x + left;
- rc.y = rc.y + top;
- #else
- vector<Point> contours_poly;
- // 把一个连续光滑曲线折线化,对图像轮廓点进行多边形拟合
- approxPolyDP(*it, contours_poly, 3, TRUE);
- // 计算轮廓的垂直边界最小矩形,矩形是与图像上下边界平行的;
- rc = boundingRect(contours_poly);
- // minAreaRect,minEnclosingTriangle,minEnclosingCircle
- RotatedRect rc_ = minAreaRect(contours_poly);//有角度的矩形;
- #endif
- break;
- }
- else
- {// 内轮廓;
- if (nArea > a1)
- nArea = a1;
- if (nPerimeter > p1)
- nPerimeter = p1;
- #if 1
- // 计算轮廓的垂直边界最小矩形,矩形是与图像上下边界平行的;
- rc = boundingRect(*it);
- rc.x = rc.x + left;
- rc.y = rc.y + top;
- #else
- vector<Point> contours_poly;
- // 把一个连续光滑曲线折线化,对图像轮廓点进行多边形拟合
- approxPolyDP(*it, contours_poly, 3, TRUE);
- // 计算轮廓的垂直边界最小矩形,矩形是与图像上下边界平行的;
- rc = boundingRect(contours_poly);
- // minAreaRect,minEnclosingTriangle,minEnclosingCircle
- RotatedRect rc_ = minAreaRect(contours_poly);//有角度的矩形;
- #endif
- }
- }
- }
- }
- CPoint CThresholdToolsDlg::WndPt2ImgPt(CPoint WndPt)
- {
- // 1.屏幕坐标转成窗口坐标;
- //ScreenToClient(&WndPt);
- // 2.窗口坐标转成控件坐标;
- CRect rcWnd;
- CWnd *pWnd = GetDlgItem(IDC_IMG);
- pWnd->GetWindowRect(&rcWnd);
- ScreenToClient(&rcWnd);
- WndPt.x -= rcWnd.left;
- WndPt.y -= rcWnd.top;
- // 3.将控件坐标转成图像坐标;
- // 计算出png原图缩放显示到窗口的缩放比例;
- float fScalex = (float)rcWnd.Width() / m_Img.cols;
- float fScaley = (float)rcWnd.Height() / m_Img.rows;
- #if 0
- CString str;
- str.Format(_T("控件坐标点:x=%d,y=%d, scalex=%lf=%ld,%ld, scaley=%lf=%ld,%ld\n"),
- WndPt.x, WndPt.y, fScalex, rcWnd.Width() , m_Img.cols, fScaley, rcWnd.Height(), m_Img.rows);
- OutputDebugString(str);
- #endif
- // 3.再将窗口点缩放到PNG原图比例;
- WndPt.x /= fScalex;
- WndPt.y /= fScaley;
- return WndPt;
- }
- void CThresholdToolsDlg::GetROI()
- {
- if ( m_ImgShow.data)
- {
- m_ImgShow.release();
- }
- if ( m_ImgROI.data)
- {
- m_ImgROI.release();
- }
- m_Img.copyTo(m_ImgShow);
- m_ImgROI = m_ImgShow([&]()-> Rect {
- long left = GetDlgItemInt(TX_LEFT);
- long top = GetDlgItemInt(TX_TOP);
- long right = GetDlgItemInt(TX_RIGHT);
- long bottom = GetDlgItemInt(TX_BOTTOM);
- if (left < 0)
- left = 0;
- if (top < 0)
- top = 0;
- if (top > m_Img.rows)
- top = m_Img.rows;
- if (left > m_Img.cols)
- left = m_Img.cols;
- left = left > m_Img.cols ? 0 : left;
- top = top > m_Img.rows ? 0 : top;
- // 注意是x,y,w=cols,h=rows
- return Rect( left, top, right - left, bottom - top);
- }());
- }
- BEGIN_MESSAGE_MAP(CThresholdToolsDlg, CDialogEx)
- ON_WM_SYSCOMMAND()
- ON_WM_PAINT()
- ON_WM_QUERYDRAGICON()
- ON_BN_CLICKED(BTN_OPENIMG, &CThresholdToolsDlg::OnBnClickedOpenimg)
- ON_WM_SIZE()
- ON_WM_HSCROLL()
- ON_BN_CLICKED(IDOK, &CThresholdToolsDlg::OnBnClickedOk)
- ON_BN_CLICKED(IDCANCEL, &CThresholdToolsDlg::OnBnClickedCancel)
- ON_BN_CLICKED(BTN_RESET, &CThresholdToolsDlg::OnBnClickedReset)
- ON_BN_CLICKED(IDC_BUTTON2, &CThresholdToolsDlg::OnBnClickedButton2)
- ON_BN_CLICKED(IDC_CHECK1, &CThresholdToolsDlg::OnBnClickedCheck1)
- ON_BN_CLICKED(IDC_CHECK2, &CThresholdToolsDlg::OnBnClickedCheck2)
- ON_EN_CHANGE(TX_Perimeter, &CThresholdToolsDlg::OnEnChangePerimeter)
- ON_EN_CHANGE(TX_Square, &CThresholdToolsDlg::OnEnChangeSquare)
- ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN1, &CThresholdToolsDlg::OnDeltaposSpin1)
- ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN2, &CThresholdToolsDlg::OnDeltaposSpin2)
- ON_EN_CHANGE(TX_Perimeter2, &CThresholdToolsDlg::OnEnChangePerimeter2)
- ON_EN_CHANGE(TX_Square2, &CThresholdToolsDlg::OnEnChangeSquare2)
- ON_WM_MOUSEWHEEL()
- ON_WM_MOUSEMOVE()
- ON_BN_CLICKED(IDC_CHECK3, &CThresholdToolsDlg::OnBnClickedCheck3)
- ON_CBN_SELCHANGE(COMBO_THRESHOLD_TYPE, &CThresholdToolsDlg::OnCbnSelchangeThresholdType)
- ON_EN_CHANGE(TX_LEFT, &CThresholdToolsDlg::OnEnChangeLeft)
- ON_EN_CHANGE(TX_TOP, &CThresholdToolsDlg::OnEnChangeTop)
- ON_EN_CHANGE(TX_RIGHT, &CThresholdToolsDlg::OnEnChangeRight)
- ON_EN_CHANGE(TX_BOTTOM, &CThresholdToolsDlg::OnEnChangeBottom)
- ON_BN_CLICKED(BTN_PREVE, &CThresholdToolsDlg::OnBnClickedPreve)
- ON_BN_CLICKED(BTN_NEXT, &CThresholdToolsDlg::OnBnClickedNext)
- ON_BN_CLICKED(RADIO_NONE, &CThresholdToolsDlg::OnBnClickedThreshold)
- ON_BN_CLICKED(RADIO_THRESHOLD, &CThresholdToolsDlg::OnBnClickedThreshold)
- ON_BN_CLICKED(RADIO_FILLCONTOUR, &CThresholdToolsDlg::OnBnClickedThreshold)
- ON_BN_CLICKED(RADIO_TEMP, &CThresholdToolsDlg::OnBnClickedThreshold)
- ON_BN_CLICKED(BTN_OPEN_TEMP, &CThresholdToolsDlg::OnBnClickedOpenTemp)
- ON_BN_CLICKED(BTN_FIND_TEMP, &CThresholdToolsDlg::OnBnClickedFindTemp)
- END_MESSAGE_MAP()
- // CThresholdToolsDlg 消息处理程序
- BOOL CThresholdToolsDlg::OnInitDialog()
- {
- CDialogEx::OnInitDialog();
- // 将“关于...”菜单项添加到系统菜单中。
- // IDM_ABOUTBOX 必须在系统命令范围内。
- ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
- ASSERT(IDM_ABOUTBOX < 0xF000);
- CMenu* pSysMenu = GetSystemMenu(FALSE);
- if (pSysMenu != nullptr)
- {
- 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); // 设置小图标
- SetDlgItemText(TX_Perimeter, _T("500"));
- SetDlgItemText(TX_Square, _T("500"));
- SetDlgItemText(TX_Perimeter2, _T("1000"));
- SetDlgItemText(TX_Square2, _T("1000"));
- #if 0
- m_Img = imread("E:\\IMCapture\\AVerCapSDK.png");
- m_img_bak = m_Img.clone();
- DrawMat(m_Img, IDC_IMG);
- #endif
- GetClientRect(&m_WndRect);
- // 将static控件样式修改;
- GetDlgItem(IDC_IMG)->ModifyStyle(SS_TYPEMASK, SS_OWNERDRAW);
- // 设置范围;
- m_slider.SetRange(0, 255);
- // 每10个值设置一个刻度;
- m_slider.SetTicFreq(10);
- // 设置滑动刻度;
- m_slider.SetPageSize(1);
- // 设置全局阀值为默认;
- m_cbThresholdType.SetCurSel(0);
- //m_Spin1.SetRange(100000, 0);
- //m_Spin2.SetRange(100000, 0);
- // m_Spin1.SetRange(0, 100000);
- // m_Spin2.SetRange(0, 100000);
- return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
- }
- void CThresholdToolsDlg::OnSysCommand(UINT nID, LPARAM lParam)
- {
- if ((nID & 0xFFF0) == IDM_ABOUTBOX)
- {
- CAboutDlg dlgAbout;
- dlgAbout.DoModal();
- }
- else
- {
- CDialogEx::OnSysCommand(nID, lParam);
- }
- }
- // 如果向对话框添加最小化按钮,则需要下面的代码
- // 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
- // 这将由框架自动完成。
- void CThresholdToolsDlg::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();
- // 绘图;
- if (m_pRenderings)
- {
- DrawMat(*m_pRenderings, IDC_IMG);
- //DrawMat(m_ImgShow, IDC_IMG);
- }
- // 模板图片;
- if ( m_ImgTemp.data)
- {
- DrawMat(m_ImgTemp, IDC_TEMP);
- }
- }
- }
- //当用户拖动最小化窗口时系统调用此函数取得光标
- //显示。
- HCURSOR CThresholdToolsDlg::OnQueryDragIcon()
- {
- return static_cast<HCURSOR>(m_hIcon);
- }
- void CThresholdToolsDlg::OnBnClickedOpenimg() // 打开图片;
- {
- // TODO: 在此添加控件通知处理程序代码
- CString strFindFile = _T("");
- CString strFilters = _T("图片(*.jpg;*.jpeg;*.png;*.bmp;)||所有文件 (*.*)|*.*||");
- CString strDeftExt = _T("default Files (*.png)");
- CString strTitle = _T("请选择要取阀值的图片");
- DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_ENABLESIZING;
- CFileDialog dlg(TRUE, strDeftExt, NULL, dwFlags, strFilters, NULL);
- dlg.m_ofn.lpstrTitle = strTitle; // 显示的标题, 应该做成参数传入;
- dlg.m_ofn.lpstrInitialDir = NULL; // 默认打开的文件夹, 应该做成参数传入;
- // 显示文件对话框,获得文件名集合;
- if (dlg.DoModal() == IDCANCEL)
- return;
- CString strFiles = dlg.GetPathName();
- CString strPath = dlg.GetFolderPath();
- m_files.clear();
- filehelpImpl fhelp;
- fhelp.getfiles_findout_subfolder(strPath.GetString(), _T("*.png|*.jpg|*.bmp"), &m_files);
- OpenImg(strFiles.GetString(), TRUE);
- m_curIndex = GetFileIndex(strFiles.GetString(), m_files);
- }
- void CThresholdToolsDlg::OnSize(UINT nType, int cx, int cy)
- {
- return CDialogEx::OnSize(nType, cx, cy);
- // 获取控件句柄;
- CWnd *pWnd = GetDlgItem(IDC_IMG);
- if ( pWnd )
- {
- CRect rcContrl;
- pWnd->GetWindowRect(&rcContrl);
- ScreenToClient(&rcContrl);
- rcContrl.right = cx - 20;
- rcContrl.bottom = cy - 50;
- pWnd->MoveWindow(rcContrl);
- }
- }
- void CThresholdToolsDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
- {
- // TODO: 在此添加消息处理程序代码和/或调用默认值
- if ((&m_slider) == (CSliderCtrl *)pScrollBar) // mSlider 为你的slider控件
- {
- // 获取当前刻度;
- long lVal = m_slider.GetPos();
- long lMaxVal = GetDlgItemInt(IDC_EDIT2);
- // 图像二值化;
- if ( ImgThreshold(lVal, lMaxVal) )
- {
- CString str;
- str.Format(_T("当前值:%ld"), lVal);
- SetWindowText(str);
- }
- m_bPerimeter = ((CButton*)GetDlgItem(IDC_CHECK1))->GetCheck();
- if (m_nRadio != 2)
- return;
- long nPerimeter = GetDlgItemInt(TX_Perimeter);
- long nSquare = GetDlgItemInt(TX_Square);
- long nPerimeter2 = GetDlgItemInt(TX_Perimeter2);
- long nSquare2 = GetDlgItemInt(TX_Square2);
- DrawContours(m_bPerimeter, nPerimeter, nPerimeter2, m_bSquare, nSquare, nSquare2);
- }
- CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar);
- }
- void CThresholdToolsDlg::OnBnClickedOk()
- {
- // TODO: 在此添加控件通知处理程序代码
- CDialogEx::OnOK();
- }
- void CThresholdToolsDlg::OnBnClickedCancel()
- {
- // TODO: 在此添加控件通知处理程序代码
- CDialogEx::OnCancel();
- }
- void CThresholdToolsDlg::OnBnClickedReset() // 复位;
- {
- m_slider.SetPos(0);
- m_Img.copyTo(m_ImgShow);
- m_pRenderings = &m_ImgShow;
- // 刷新画布;
- RefreshCanvas();
- }
- void CThresholdToolsDlg::OnBnClickedButton2() // 轮廓;
- {
- // TODO: 在此添加控件通知处理程序代码
- // 获取当前刻度;
- long lVal = m_slider.GetPos();
- long lMaxVal = GetDlgItemInt(IDC_EDIT2);
- long nPerimeter = GetDlgItemInt(TX_Perimeter);
- long nSquare = GetDlgItemInt(TX_Square);
- long nPerimeter2 = GetDlgItemInt(TX_Perimeter2);
- long nSquare2 = GetDlgItemInt(TX_Square2);
- if ( !m_bThreshold)
- {
- DrawContours(m_bPerimeter, nPerimeter, nPerimeter2, m_bSquare, nSquare, nSquare2);
- SetDlgItemText(IDC_BUTTON2, _T("二值化"));
- }
- else
- {
- GetROI();
- if (m_ImgThreshold.data)
- {
- cvtColor(m_ImgThreshold, m_ImgROI, COLOR_GRAY2BGR);
- m_ImgThreshold.copyTo(m_ImgROI);
- m_pRenderings = &m_ImgShow;
- }
- // 刷新;
- RefreshCanvas();
- SetDlgItemText(IDC_BUTTON2, _T("轮廓"));
- }
- m_bThreshold = !m_bThreshold;
- }
- void CThresholdToolsDlg::OnBnClickedCheck1() // 周长;
- {
- m_bPerimeter = ((CButton*)GetDlgItem(IDC_CHECK1))->GetCheck();
- if (m_nRadio != 2)
- return;
- long lVal = m_slider.GetPos();
- long lMaxVal = GetDlgItemInt(IDC_EDIT2);
- long nPerimeter = GetDlgItemInt(TX_Perimeter);
- long nSquare = GetDlgItemInt(TX_Square);
- long nPerimeter2 = GetDlgItemInt(TX_Perimeter2);
- long nSquare2 = GetDlgItemInt(TX_Square2);
- DrawContours(m_bPerimeter, nPerimeter, nPerimeter2, m_bSquare, nSquare, nSquare2);
- }
- void CThresholdToolsDlg::OnBnClickedCheck2() // 面积;
- {
- m_bSquare = ((CButton*)GetDlgItem(IDC_CHECK2))->GetCheck();
- if (m_nRadio != 2)
- return;
- long lVal = m_slider.GetPos();
- long lMaxVal = GetDlgItemInt(IDC_EDIT2);
- long nPerimeter = GetDlgItemInt(TX_Perimeter);
- long nSquare = GetDlgItemInt(TX_Square);
- long nPerimeter2 = GetDlgItemInt(TX_Perimeter2);
- long nSquare2 = GetDlgItemInt(TX_Square2);
- DrawContours(m_bPerimeter, nPerimeter, nPerimeter2, m_bSquare, nSquare, nSquare2);
- }
- void CThresholdToolsDlg::OnEnChangePerimeter()
- {
- // TODO: 如果该控件是 RICHEDIT 控件,它将不
- // 发送此通知,除非重写 CDialogEx::OnInitDialog()
- // 函数并调用 CRichEditCtrl().SetEventMask(),
- // 同时将 ENM_CHANGE 标志“或”运算到掩码中。
- if ( m_nRadio == 2 )
- {
- long lVal = m_slider.GetPos();
- long lMaxVal = GetDlgItemInt(IDC_EDIT2);
-
- long nPerimeter = GetDlgItemInt(TX_Perimeter);
- long nSquare = GetDlgItemInt(TX_Square);
- long nPerimeter2 = GetDlgItemInt(TX_Perimeter2);
- long nSquare2 = GetDlgItemInt(TX_Square2);
- DrawContours(m_bPerimeter, nPerimeter, nPerimeter2, m_bSquare, nSquare, nSquare2);
- }
- // TODO: 在此添加控件通知处理程序代码
- }
- void CThresholdToolsDlg::OnEnChangeSquare()
- {
- // TODO: 如果该控件是 RICHEDIT 控件,它将不
- // 发送此通知,除非重写 CDialogEx::OnInitDialog()
- // 函数并调用 CRichEditCtrl().SetEventMask(),
- // 同时将 ENM_CHANGE 标志“或”运算到掩码中。
- if (m_nRadio == 2)
- {
- long lVal = m_slider.GetPos();
- long lMaxVal = GetDlgItemInt(IDC_EDIT2);
-
- long nPerimeter = GetDlgItemInt(TX_Perimeter);
- long nSquare = GetDlgItemInt(TX_Square);
- long nPerimeter2 = GetDlgItemInt(TX_Perimeter2);
- long nSquare2 = GetDlgItemInt(TX_Square2);
- DrawContours(m_bPerimeter, nPerimeter, nPerimeter2, m_bSquare, nSquare, nSquare2);
- }
- // TODO: 在此添加控件通知处理程序代码
- }
- void CThresholdToolsDlg::OnDeltaposSpin1(NMHDR *pNMHDR, LRESULT *pResult)
- {
- LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
- // TODO: 在此添加控件通知处理程序代码
- long val = GetDlgItemInt(TX_Perimeter);
- if ( pNMUpDown->iDelta == 1) // 向下;
- {
- val--;
- }
- else if (pNMUpDown->iDelta == -1)// 向上;
- {
- val++;
- }
- *pResult = 0;
-
- SetDlgItemInt(TX_Perimeter, val);
- }
- void CThresholdToolsDlg::OnDeltaposSpin2(NMHDR *pNMHDR, LRESULT *pResult)
- {
- LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
- // TODO: 在此添加控件通知处理程序代码
- long val = GetDlgItemInt(TX_Square);
- if (pNMUpDown->iDelta == 1) // 向下;
- {
- val--;
- }
- else if (pNMUpDown->iDelta == -1)// 向上;
- {
- val++;
- }
- *pResult = 0;
- SetDlgItemInt(TX_Square, val);
- }
- void CThresholdToolsDlg::OnEnChangePerimeter2()
- {
- // TODO: 如果该控件是 RICHEDIT 控件,它将不
- // 发送此通知,除非重写 CDialogEx::OnInitDialog()
- // 函数并调用 CRichEditCtrl().SetEventMask(),
- // 同时将 ENM_CHANGE 标志“或”运算到掩码中。
- if (m_nRadio == 2)
- {
- long lVal = m_slider.GetPos();
- long lMaxVal = GetDlgItemInt(IDC_EDIT2);
- long nPerimeter = GetDlgItemInt(TX_Perimeter);
- long nSquare = GetDlgItemInt(TX_Square);
- long nPerimeter2 = GetDlgItemInt(TX_Perimeter2);
- long nSquare2 = GetDlgItemInt(TX_Square2);
- DrawContours(m_bPerimeter, nPerimeter, nPerimeter2, m_bSquare, nSquare, nSquare2);
- }
- // TODO: 在此添加控件通知处理程序代码
- }
- void CThresholdToolsDlg::OnEnChangeSquare2()
- {
- // TODO: 如果该控件是 RICHEDIT 控件,它将不
- // 发送此通知,除非重写 CDialogEx::OnInitDialog()
- // 函数并调用 CRichEditCtrl().SetEventMask(),
- // 同时将 ENM_CHANGE 标志“或”运算到掩码中。
- if (m_nRadio == 2)
- {
- long lVal = m_slider.GetPos();
- long lMaxVal = GetDlgItemInt(IDC_EDIT2);
- long nPerimeter = GetDlgItemInt(TX_Perimeter);
- long nSquare = GetDlgItemInt(TX_Square);
- long nPerimeter2 = GetDlgItemInt(TX_Perimeter2);
- long nSquare2 = GetDlgItemInt(TX_Square2);
- DrawContours(m_bPerimeter, nPerimeter, nPerimeter2, m_bSquare, nSquare, nSquare2);
- }
- // TODO: 在此添加控件通知处理程序代码
- }
- BOOL CThresholdToolsDlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
- {
- // TODO: 在此添加消息处理程序代码和/或调用默认值
- CWnd *pWnd = GetFocus();
- if ( pWnd == GetDlgItem(TX_Perimeter) || pWnd == GetDlgItem(TX_Perimeter2)
- || pWnd == GetDlgItem(TX_Square) || pWnd == GetDlgItem(TX_Square2))
- {
- long nVal = GetDlgItemInt(pWnd->GetDlgCtrlID());
- if ( zDelta > 0 )
- {//向上滚动;
- nVal++;
- }
- else
- {
- nVal--;
- }
- SetDlgItemInt(pWnd->GetDlgCtrlID(), nVal);
- }
- if (pWnd == GetDlgItem(TX_LEFT) )
- {
- long nVal = GetDlgItemInt(pWnd->GetDlgCtrlID());
- if (zDelta > 0)
- {//向上滚动;
- if (nVal < m_Img.cols)
- nVal++;
- }
- else
- {
- if (nVal > 0 )
- nVal--;
- }
- SetDlgItemInt(pWnd->GetDlgCtrlID(), nVal);
- }
- if ( pWnd == GetDlgItem(TX_TOP))
- {
- long nVal = GetDlgItemInt(pWnd->GetDlgCtrlID());
- if (zDelta > 0)
- {//向上滚动;
- if (nVal < m_Img.rows)
- nVal++;
- }
- else
- {
- if (nVal > 0)
- nVal--;
- }
- SetDlgItemInt(pWnd->GetDlgCtrlID(), nVal);
- }
- if ( pWnd == GetDlgItem(TX_RIGHT) )
- {
- long nVal = GetDlgItemInt(pWnd->GetDlgCtrlID());
- if (zDelta > 0)
- {//向上滚动;
- if (nVal < m_Img.cols)
- nVal++;
- }
- else
- {
- if (nVal > 0)
- nVal--;
- }
- SetDlgItemInt(pWnd->GetDlgCtrlID(), nVal);
- }
- if ( pWnd == GetDlgItem(TX_BOTTOM))
- {
- long nVal = GetDlgItemInt(pWnd->GetDlgCtrlID());
- if (zDelta > 0)
- {//向上滚动;
- if (nVal < m_Img.rows)
- nVal++;
- }
- else
- {
- if (nVal > 0)
- nVal--;
- }
- SetDlgItemInt(pWnd->GetDlgCtrlID(), nVal);
- }
- return CDialogEx::OnMouseWheel(nFlags, zDelta, pt);
- }
- BOOL CThresholdToolsDlg::PreTranslateMessage(MSG* pMsg)
- {
- // TODO: 在此添加专用代码和/或调用基类
- if (pMsg->message == WM_KEYDOWN)
- {
- CWnd *pWnd = GetFocus();
- if (pWnd == GetDlgItem(TX_Perimeter) || pWnd == GetDlgItem(TX_Perimeter2)
- || pWnd == GetDlgItem(TX_Square) || pWnd == GetDlgItem(TX_Square2)
- || pWnd == GetDlgItem(TX_LEFT) || pWnd == GetDlgItem(TX_TOP)
- || pWnd == GetDlgItem(TX_RIGHT) || pWnd == GetDlgItem(TX_BOTTOM)
- )
- {
- long nVal = GetDlgItemInt(pWnd->GetDlgCtrlID());
- if (pMsg->wParam == VK_UP)
- {
- nVal++;
- SetDlgItemInt(pWnd->GetDlgCtrlID(), nVal);
- }
- else if (pMsg->wParam == VK_DOWN)
- {
- nVal--;
- SetDlgItemInt(pWnd->GetDlgCtrlID(), nVal);
- }
- }
- }
- else if (pMsg->message == WM_LBUTTONDOWN)
- {
- CPoint point;
- GetCursorPos(&point);
- CRect rcWnd;
- CWnd *pWnd = GetDlgItem(IDC_IMG);
- pWnd->GetWindowRect(&rcWnd);
- if (!PtInRect(&rcWnd, point))
- return CDialogEx::PreTranslateMessage(pMsg);
- ScreenToClient(&point);
- point = WndPt2ImgPt(point);
- m_bPress = TRUE;
- m_firstPt.x = point.x;
- m_firstPt.y = point.y;
- long nPerimeter = 100000, nArea = 1000000;
- Rect rc;
- GetPointInfo(point, nPerimeter, nArea, rc);
- if (nPerimeter > 200 || nArea > 1000)
- {
- CString str;
- GetWindowText(str);
- int nIndex = str.Find(_T(" \t\t\t"));
- str.Format(_T("%s \t\t\t 周长:%ld,面积:%ld\n, 坐标=[%d,%d,%d,%d]"), (nIndex == -1 ? str : str.Left(nIndex)), nPerimeter, nArea, rc.x, rc.y, rc.x+rc.width, rc.y+rc.height);
- SetWindowText(str);
- }
- }
- else if (pMsg->message == WM_LBUTTONUP)
- {
- if (m_bPress)
- {
- m_bPress = FALSE;
- // 最后的点;
- CPoint point;
- GetCursorPos(&point);
- CRect rcWnd;
- CWnd *pWnd = GetDlgItem(IDC_IMG);
- pWnd->GetWindowRect(&rcWnd);
- if (!PtInRect(&rcWnd, point))
- return CDialogEx::PreTranslateMessage(pMsg);
- ScreenToClient(&point);
- point = WndPt2ImgPt(point);
- m_lastPt.x = point.x;
- m_lastPt.y = point.y;
- SetDlgItemInt(TX_LEFT, m_firstPt.x);
- SetDlgItemInt(TX_TOP, m_firstPt.y);
- SetDlgItemInt(TX_RIGHT, m_lastPt.x);
- SetDlgItemInt(TX_BOTTOM, m_lastPt.y);
- }
- }
- return CDialogEx::PreTranslateMessage(pMsg);
- }
- void CThresholdToolsDlg::OnMouseMove(UINT nFlags, CPoint point)
- {
- // TODO: 在此添加消息处理程序代码和/或调用默认值
- #if 0
- if (m_contours.size())
- {
- // 坐标转换;
- CString str;
- point = WndPt2ImgPt(point);
- long nPerimeter = 0, nArea = 0;
- GetPointInfo(point, nPerimeter, nArea);
- if (nPerimeter > 200 || nArea > 1000)
- {
- #if _DEBUG
- str.Format(_T("周长:%ld,面积:%ld\n"), nPerimeter, nArea);
- OutputDebugString(str);
- #endif
- }
- }
- #endif
- if ( m_bPress )
- {
- if (m_ImgShow.data)
- m_ImgShow.release();
- CPoint point;
- GetCursorPos(&point);
- CRect rcWnd;
- CWnd *pWnd = GetDlgItem(IDC_IMG);
- pWnd->GetWindowRect(&rcWnd);
- if (!PtInRect(&rcWnd, point))
- return CDialogEx::OnMouseMove(nFlags, point);
- ScreenToClient(&point);
- point = WndPt2ImgPt(point);
- m_lastPt.x = point.x;
- m_lastPt.y = point.y;
- m_Img.copyTo(m_ImgShow);
- rectangle(m_ImgShow, m_firstPt, Point(m_lastPt.x, m_lastPt.y), Scalar(rand() % 255, rand() % 255, rand() % 255), 1, CV_AA, 0);
- m_pRenderings = &m_ImgShow;
- SetWindowText([&]()->CString {
- CString str;
- str.Format(_T("坐标=[%d,%d,%d,%d]"), m_firstPt.x, m_firstPt.y, point.x, point.y);
- return str;
- }());
- RefreshCanvas();
- }
- CDialogEx::OnMouseMove(nFlags, point);
- }
- void CThresholdToolsDlg::OnBnClickedCheck3() // 内轮廓;
- {
- int nPos = m_slider.GetPos();
- long nPerimeter = GetDlgItemInt(TX_Perimeter);
- long nSquare = GetDlgItemInt(TX_Square);
- long nPerimeter2 = GetDlgItemInt(TX_Perimeter2);
- long nSquare2 = GetDlgItemInt(TX_Square2);
- if (nPos != 0)
- {
- // 二值化;
- long lMaxVal = GetDlgItemInt(IDC_EDIT2);
- ImgThreshold(nPos, lMaxVal);
- if (m_nRadio == 2)
- {
- DrawContours(m_bPerimeter, nPerimeter, nPerimeter2, m_bSquare, nSquare, nSquare2);
- }
- else
- {
- // 刷新;
- RefreshCanvas();
- }
- }
- else
- {
- int nCurSel = m_cbThresholdType.GetCurSel();
- if (nCurSel != 0)
- {
- // 二值化;
- long lMaxVal = GetDlgItemInt(IDC_EDIT2);
- ImgThreshold(nPos, lMaxVal);
- if (m_nRadio == 2)
- {
- DrawContours(m_bPerimeter, nPerimeter, nPerimeter2, m_bSquare, nSquare, nSquare2);
- }
- else
- {
- // 刷新;
- RefreshCanvas();
- }
- }
- else
- {
- m_pRenderings = &m_ImgShow;
- }
- RefreshCanvas();
- }
- }
- void CThresholdToolsDlg::OnCbnSelchangeThresholdType()
- {
- // TODO: 在此添加控件通知处理程序代码
- int nPos = m_slider.GetPos();
- long nPerimeter = GetDlgItemInt(TX_Perimeter);
- long nSquare = GetDlgItemInt(TX_Square);
- long nPerimeter2 = GetDlgItemInt(TX_Perimeter2);
- long nSquare2 = GetDlgItemInt(TX_Square2);
- if (nPos != 0)
- {
- // 二值化;
- long lMaxVal = GetDlgItemInt(IDC_EDIT2);
- ImgThreshold(nPos, lMaxVal);
- if (m_nRadio == 2)
- {
- DrawContours(m_bPerimeter, nPerimeter, nPerimeter2, m_bSquare, nSquare, nSquare2);
- }
- else
- {
- // 刷新;
- RefreshCanvas();
- }
- }
- else
- {
- int nCurSel = m_cbThresholdType.GetCurSel();
- if (nCurSel != 0)
- {
- // 二值化;
- long lMaxVal = GetDlgItemInt(IDC_EDIT2);
- ImgThreshold(nPos, lMaxVal);
- if (m_nRadio == 2)
- {
- DrawContours(m_bPerimeter, nPerimeter, nPerimeter2, m_bSquare, nSquare, nSquare2);
- }
- else
- {
- // 刷新;
- RefreshCanvas();
- }
- }
- else
- {
- m_pRenderings = &m_ImgShow;
- }
- RefreshCanvas();
- }
- }
- void CThresholdToolsDlg::OnEnChangeLeft()
- {
- // TODO: 如果该控件是 RICHEDIT 控件,它将不
- // 发送此通知,除非重写 CDialogEx::OnInitDialog()
- // 函数并调用 CRichEditCtrl().SetEventMask(),
- // 同时将 ENM_CHANGE 标志“或”运算到掩码中。
- m_Img.copyTo(m_ImgShow);
- int nPos = m_slider.GetPos();
- long nPerimeter = GetDlgItemInt(TX_Perimeter);
- long nSquare = GetDlgItemInt(TX_Square);
- long nPerimeter2 = GetDlgItemInt(TX_Perimeter2);
- long nSquare2 = GetDlgItemInt(TX_Square2);
- if (nPos != 0)
- {
- // 二值化;
- long lMaxVal = GetDlgItemInt(IDC_EDIT2);
- ImgThreshold(nPos, lMaxVal);
- if (m_nRadio == 2)
- {
- DrawContours(m_bPerimeter, nPerimeter, nPerimeter2, m_bSquare, nSquare, nSquare2);
- }
- else
- {
- // 刷新;
- RefreshCanvas();
- }
- }
- else
- {
- int nCurSel = m_cbThresholdType.GetCurSel();
- if (nCurSel == 2 || nCurSel == 3)
- {
- // 二值化;
- long lMaxVal = GetDlgItemInt(IDC_EDIT2);
- ImgThreshold(nPos, lMaxVal);
- if (m_nRadio == 2)
- {
- DrawContours(m_bPerimeter, nPerimeter, nPerimeter2, m_bSquare, nSquare, nSquare2);
- }
- else
- {
- // 刷新;
- RefreshCanvas();
- }
- }
- else
- {
- m_pRenderings = &m_ImgShow;
- }
- RefreshCanvas();
- }
- // TODO: 在此添加控件通知处理程序代码
- }
- void CThresholdToolsDlg::OnEnChangeTop()
- {
- // TODO: 如果该控件是 RICHEDIT 控件,它将不
- // 发送此通知,除非重写 CDialogEx::OnInitDialog()
- // 函数并调用 CRichEditCtrl().SetEventMask(),
- // 同时将 ENM_CHANGE 标志“或”运算到掩码中。
- OnEnChangeLeft();
- // TODO: 在此添加控件通知处理程序代码
- }
- void CThresholdToolsDlg::OnEnChangeRight()
- {
- // TODO: 如果该控件是 RICHEDIT 控件,它将不
- // 发送此通知,除非重写 CDialogEx::OnInitDialog()
- // 函数并调用 CRichEditCtrl().SetEventMask(),
- // 同时将 ENM_CHANGE 标志“或”运算到掩码中。
- OnEnChangeLeft();
- // TODO: 在此添加控件通知处理程序代码
- }
- void CThresholdToolsDlg::OnEnChangeBottom()
- {
- // TODO: 如果该控件是 RICHEDIT 控件,它将不
- // 发送此通知,除非重写 CDialogEx::OnInitDialog()
- // 函数并调用 CRichEditCtrl().SetEventMask(),
- // 同时将 ENM_CHANGE 标志“或”运算到掩码中。
- OnEnChangeLeft();
- // TODO: 在此添加控件通知处理程序代码
- }
- void CThresholdToolsDlg::OnBnClickedPreve()
- {
- // TODO: 在此添加控件通知处理程序代码
- if (m_files.size() == 0)
- return;
- if (m_curIndex == 0 )
- {
- m_curIndex = m_files.size();
- MessageBox(_T("已到第一张,将从最后一张继续"));
- }
- m_curIndex--;
- OpenImg(m_files[m_curIndex].c_str());
- }
- void CThresholdToolsDlg::OnBnClickedNext()
- {
- if (m_files.size() == 0)
- return;
- if (m_curIndex == m_files.size()-1)
- {
- MessageBox(_T("已到最后一张,将从第一张继续"));
- m_curIndex = -1;
- }
- m_curIndex++;
- OpenImg(m_files[m_curIndex].c_str());
- }
- //打开图片;
- void CThresholdToolsDlg::OpenImg(LPCTSTR lpFile, BOOL bResetROI /* = FALSE */)
- {
- int lastr = 0, lastc = 0;
- if (m_Img.data != NULL)
- {
- lastr = m_Img.rows, lastc = m_Img.cols;
- m_Img.release();
- }
- if (m_ImgThreshold.data)
- {
- m_ImgThreshold.release();
- }
- if ( m_ImgShow.data )
- {
- m_ImgShow.release();
- }
- if ( m_ImgROI.data )
- {
- m_ImgROI.release();
- }
- SetDlgItemText(IDC_EDIT1, lpFile);
- m_Img = imread(lpFile, CV_LOAD_IMAGE_COLOR);
- if (m_Img.data)
- {
- if (lastr != m_Img.rows && lastc != m_Img.cols)
- bResetROI = TRUE;
- if (bResetROI)
- {
- m_strLeft = _T("0");
- m_strTop = _T("0");
- m_strRight.Format(_T("%ld"), m_Img.cols);
- m_strBottom.Format(_T("%ld"), m_Img.rows);
- UpdateData(FALSE);
- }
- m_Img.copyTo(m_ImgShow);
- }
- int nPos = m_slider.GetPos();
- int nCurSel = m_cbThresholdType.GetCurSel();
- // 二值化;
- long lMaxVal = GetDlgItemInt(IDC_EDIT2);
- ImgThreshold(nPos, lMaxVal);
- long nPerimeter = GetDlgItemInt(TX_Perimeter);
- long nSquare = GetDlgItemInt(TX_Square);
- long nPerimeter2 = GetDlgItemInt(TX_Perimeter2);
- long nSquare2 = GetDlgItemInt(TX_Square2);
- if (nCurSel == 2 || nCurSel == 3)
- {
- if (m_nRadio == 2)
- {
- DrawContours(m_bPerimeter, nPerimeter, nPerimeter2, m_bSquare, nSquare, nSquare2);
- }
- else
- {
- // 刷新;
- RefreshCanvas();
- }
- }
- else
- {
- if (nPos != 0)
- {
- if (m_nRadio == 2)
- {
- DrawContours(m_bPerimeter, nPerimeter, nPerimeter2, m_bSquare, nSquare, nSquare2);
- }
- else
- {
- // 刷新;
- RefreshCanvas();
- }
- }
- else
- {
- if (m_nRadio == 3)
- {
- OnBnClickedFindTemp();
- }
- else {
- m_pRenderings = &m_Img;
- RefreshCanvas();
- }
- }
- }
-
- //if (nPos != 0)
- //{
- // // 二值化;
- // long lMaxVal = GetDlgItemInt(IDC_EDIT2);
- // ImgThreshold(nPos, lMaxVal);
- // long nPerimeter = GetDlgItemInt(TX_Perimeter);
- // long nSquare = GetDlgItemInt(TX_Square);
- // long nPerimeter2 = GetDlgItemInt(TX_Perimeter2);
- // long nSquare2 = GetDlgItemInt(TX_Square2);
- // if (m_nRadio == 2)
- // {
- // DrawContours(m_bPerimeter, nPerimeter, nPerimeter2, m_bSquare, nSquare, nSquare2);
- // }
- // else
- // {
- // //if (m_ImgThreshold.data)
- // // m_pRenderings = &m_ImgThreshold;
- // // 刷新;
- // RefreshCanvas();
- // }
- //}
- //else
- //{
- // m_pRenderings = &m_ImgShow;
- // RefreshCanvas();
- //}
- }
- int CThresholdToolsDlg::GetFileIndex(LPCTSTR lpCurFile, STR_VEC & vtFiles)
- {
- int nIndex = -1;
- int nCount = vtFiles.size();
- for ( int i = 0; i < nCount; i++ )
- {
- if (!_tcsicmp(lpCurFile, vtFiles[i].c_str()) )
- {
- nIndex = i;
- break;
- }
- }
- return nIndex;
- }
- void CThresholdToolsDlg::OnBnClickedThreshold()
- {
- // TODO: 在此添加控件通知处理程序代码
- UpdateData(TRUE);
- long lVal = m_slider.GetPos();
- long lMaxVal = GetDlgItemInt(IDC_EDIT2);
- long nPerimeter = GetDlgItemInt(TX_Perimeter);
- long nSquare = GetDlgItemInt(TX_Square);
- long nPerimeter2 = GetDlgItemInt(TX_Perimeter2);
- long nSquare2 = GetDlgItemInt(TX_Square2);
- switch (m_nRadio)
- {
- case 0:
- {
- m_pRenderings = &m_Img;
- // 刷新;
- RefreshCanvas();
- }
- break;
- case 1://二值图;
- {
- GetROI();
- if (m_ImgThreshold.data)
- {
- cvtColor(m_ImgThreshold, m_ImgROI, COLOR_GRAY2BGR);
- m_ImgThreshold.copyTo(m_ImgROI);
- m_pRenderings = &m_ImgShow;
- }
- // 刷新;
- RefreshCanvas();
- }
- break;
- case 2:// 轮廓填充;
- {
- DrawContours(m_bPerimeter, nPerimeter, nPerimeter2, m_bSquare, nSquare, nSquare2);
- }
- break;
- case 3:
- {
- OnBnClickedFindTemp();
- }
- break;
- default:
- break;
- }
- }
- void CThresholdToolsDlg::OnBnClickedOpenTemp()//打开模板图片;
- {
- // TODO: 在此添加控件通知处理程序代码
- CString strFindFile = _T("");
- CString strFilters = _T("图片(*.jpg;*.jpeg;*.png;*.bmp;)||所有文件 (*.*)|*.*||");
- CString strDeftExt = _T("default Files (*.png)");
- CString strTitle = _T("请选择要取阀值的图片");
- DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_ENABLESIZING;
- CFileDialog dlg(TRUE, strDeftExt, NULL, dwFlags, strFilters, NULL);
- dlg.m_ofn.lpstrTitle = strTitle; // 显示的标题, 应该做成参数传入;
- dlg.m_ofn.lpstrInitialDir = NULL; // 默认打开的文件夹, 应该做成参数传入;
- // 显示文件对话框,获得文件名集合;
- if (dlg.DoModal() == IDCANCEL)
- return;
- CString strFiles = dlg.GetPathName();
- CString strPath = dlg.GetFolderPath();
- if ( m_ImgTemp.data )
- {
- m_ImgTemp.release();
- }
- m_ImgTemp = imread(strFiles.GetString(), CV_LOAD_IMAGE_COLOR);
- if ( m_ImgTemp.data)
- {
- DrawMat(m_ImgTemp, IDC_TEMP);
- }
- }
- void CThresholdToolsDlg::OnBnClickedFindTemp()
- {
- // TODO: 在此添加控件通知处理程序代码
- if (m_ImgTemp.data == NULL)
- return;
- if ( m_ImgTemp.cols > m_Img.cols || m_ImgTemp.rows > m_Img.rows)
- return;
- GetROI();
- if (m_ImgROI.data == NULL)
- return;
- Mat ImgResult;
- matchTemplate(m_ImgROI, m_ImgTemp, ImgResult, TM_CCOEFF_NORMED);
- // 归一化到0~1
- //normalize(ImgResult, ImgResult, 0, 1, NORM_MINMAX, -1);
- //
- double lv_nMinVal = 0.0;
- double lv_nMaxVal = 0.0;
- Point lv_nMinLoc = Point(0, 0);
- Point lv_nMaxLoc = Point(0,0);
- Point lv_MatchLoc = Point(0,0);
- minMaxLoc(ImgResult, &lv_nMinVal, &lv_nMaxVal, &lv_nMinLoc, &lv_nMaxLoc);
- // TM_CCOEFF_NORMED:匹配值越大越相似;
- SetDlgItemText(MATCH_VAL, [&]()->CString{
- CString str;
- str.Format(_T("%0.13lf"), lv_nMaxVal);
- return str;
- }());
- SetWindowText([&]()->CString {
- CString str;
- str.Format(_T("相似度=%0.13lf 坐标=[%d,%d,%d,%d]"), lv_nMaxVal, lv_nMaxLoc.x, lv_nMaxLoc.y, lv_nMaxLoc.x + m_ImgTemp.cols, lv_nMaxLoc.y + m_ImgTemp.rows);
- return str;
- }());
- //m_Img.copyTo(m_ImgShow);
- //m_ImgROI = m_ImgShow(Rect(lv_nMaxLoc.x-2, lv_nMaxLoc.y-2, m_ImgTemp.cols+4, m_ImgTemp.rows+4));
- //m_ImgROI = m_ImgShow(Rect(lv_nMaxLoc.x, lv_nMaxLoc.y , m_ImgTemp.cols , m_ImgTemp.rows ));
- //CV_AA
- rectangle(m_ImgROI, Point(lv_nMaxLoc.x, lv_nMaxLoc.y), Point(lv_nMaxLoc.x+ m_ImgTemp.cols, lv_nMaxLoc.y+ m_ImgTemp.rows), Scalar(rand() % 255, rand() % 255, rand() % 255), 2, CV_AA, 0);
- m_pRenderings = &m_ImgShow;
- RefreshCanvas();
- }
- void CThresholdToolsDlg::DrawTempContours()
- {
- }
|