소스 검색

1、完成18个常用接口,其余接口后期开发;
2、各接口测试用例完成,testcpp.cpp

scbc.sat2 5 년 전
부모
커밋
b528f49cf5
5개의 변경된 파일416개의 추가작업 그리고 34개의 파일을 삭제
  1. 304 28
      cv/cv/cv.cpp
  2. 20 6
      cv/cv/cv.h
  3. 1 0
      cv/cv/cv.vcxproj
  4. 3 0
      cv/cv/cv.vcxproj.filters
  5. 88 0
      cv/cv/testcpp.cpp

+ 304 - 28
cv/cv/cv.cpp

@@ -9,7 +9,9 @@
 #define new DEBUG_NEW
 #endif
 
-
+#ifdef _DEBUG
+extern void test();
+#endif
 // 唯一的应用程序对象
 
 CWinApp theApp;
@@ -34,15 +36,7 @@ int main()
         else
         {
             // TODO: 在此处为应用程序的行为编写代码。
-            printf("开始程序……");
-
-            cv::Mat thresholdImg;
-            if (GetBinaryImage("E:\\bin\\test.jpg", 100, 255, thresholdImg))
-            {
-                cv::imwrite("E:\\bin\\thresholdImg.jpg", thresholdImg);
-                thresholdImg.release();
-            }
-
+			test();
         }
     }
     else
@@ -52,8 +46,6 @@ int main()
         nRetCode = 1;
     }
 
-    //system("pause"); 
-
     return nRetCode;
 }
 
@@ -71,7 +63,7 @@ CV_API bool ReadImage(std::string strImgPath, cv::Mat& img)
 	// 以BGR三通道方式读取图片;
 	img = cv::imread(strImgPath.c_str(), cv::IMREAD_COLOR);
     // 判断图片是否为空;
-	if (!img.empty()) {
+	if (img.empty()) {
 #ifdef _DEBUG
 		OutputDebugString("读取图片失败!");
 #endif
@@ -107,7 +99,7 @@ CV_API bool GetBinaryImage(std::string strImgPath, long nThresholdVal, long nMax
     gaussImg.release();
 
     // 判断图片是否空;
-    if (!thresholdImg.empty())
+    if (thresholdImg.empty())
         return false;
 
     return true;
@@ -138,7 +130,7 @@ CV_API bool GetOTSUBinaryImage(std::string strImgPath, long nThresholdVal, long
 	gaussImg.release();
 
 	// 判断图片是否空;
-	if (!thresholdImg.empty())
+	if (thresholdImg.empty())
 		return false;
 
 	return true;
@@ -176,7 +168,7 @@ CV_API bool GetAdaptiveBinaryImage(std::string strImgPath, long nMaxThresholdVal
 	blurImg.release();
 
 	// 判断图片是否空;
-	if (!thresholdImg.empty())
+	if (thresholdImg.empty())
 		return false;
 
 	return true;
@@ -184,13 +176,13 @@ CV_API bool GetAdaptiveBinaryImage(std::string strImgPath, long nMaxThresholdVal
 
 CV_API bool GaussianBlur(cv::Mat& img, cv::Size cvSize, cv::Mat& gaussImg)
 {
-	if (!img.empty())
+	if (img.empty())
 		return false;
 
 	// 再高斯模糊处理(滤波);
 	cv::GaussianBlur(img, gaussImg, cvSize, 0, 0);
 	// 判断图片是否空;
-	if (!gaussImg.empty())
+	if (gaussImg.empty())
 		return false;
 
 	return true;
@@ -206,7 +198,7 @@ CV_API bool GaussianBlur(std::string strImgPath, cv::Size cvSize, cv::Mat& gauss
 	// 再高斯模糊处理(滤波);
 	cv::GaussianBlur(img, gaussImg, cvSize, 0, 0);
 	// 判断图片是否空;
-	if (!gaussImg.empty())
+	if (gaussImg.empty())
 		return false;
 
 	return true;
@@ -214,13 +206,13 @@ CV_API bool GaussianBlur(std::string strImgPath, cv::Size cvSize, cv::Mat& gauss
 
 CV_API bool Color2Gray(cv::Mat& img, cv::Mat& grayImg)
 {
-	if (!img.empty())
+	if (img.empty())
 		return false;
 
 	// 再高斯模糊处理(滤波);
 	cv::cvtColor(img, grayImg, cv::COLOR_BGR2GRAY);
 	// 判断图片是否空;
-	if (!grayImg.empty())
+	if (grayImg.empty())
 		return false;
 
 	return true;
@@ -236,7 +228,7 @@ CV_API bool Color2Gray(std::string strImgPath, cv::Mat& grayImg)
 	// 再高斯模糊处理(滤波);
 	cv::cvtColor(img, grayImg, cv::COLOR_BGR2GRAY);
 	// 判断图片是否空;
-	if (!grayImg.empty())
+	if (grayImg.empty())
 		return false;
 
 	return true;
@@ -244,13 +236,13 @@ CV_API bool Color2Gray(std::string strImgPath, cv::Mat& grayImg)
 
 CV_API bool Gray2Color(cv::Mat& img, cv::Mat& colorImg)
 {
-	if (!img.empty())
+	if (img.empty())
 		return false;
 
 	// 再高斯模糊处理(滤波);
 	cv::cvtColor(img, colorImg, cv::COLOR_GRAY2BGR);
 	// 判断图片是否空;
-	if (!colorImg.empty())
+	if (colorImg.empty())
 		return false;
 
 	return true;
@@ -258,7 +250,7 @@ CV_API bool Gray2Color(cv::Mat& img, cv::Mat& colorImg)
 
 CV_API bool ErodeImg(cv::Mat& img, cv::MorphShapes kernelShape, cv::Size kernelSize, cv::Mat& erodeImg)
 {
-	if (!img.empty())
+	if (img.empty())
 		return false;
 
 	// 获取自定义核(核形状:矩形MORPH_RECT、十字架CROSS、椭圆ELLIPSE )
@@ -266,7 +258,7 @@ CV_API bool ErodeImg(cv::Mat& img, cv::MorphShapes kernelShape, cv::Size kernelS
 	// 再高斯模糊处理(滤波);
 	cv::erode(img, erodeImg, element);
 	// 判断图片是否空;
-	if (!erodeImg.empty())
+	if (erodeImg.empty())
 		return false;
 
 	return true;
@@ -274,7 +266,7 @@ CV_API bool ErodeImg(cv::Mat& img, cv::MorphShapes kernelShape, cv::Size kernelS
 
 CV_API bool DilateImg(cv::Mat& img, cv::MorphShapes kernelShape, cv::Size kernelSize, cv::Mat& dilateImg)
 {
-	if (!img.empty())
+	if (img.empty())
 		return false;
 
 	// 获取自定义核(核形状:矩形MORPH_RECT、十字架CROSS、椭圆ELLIPSE )
@@ -282,8 +274,292 @@ CV_API bool DilateImg(cv::Mat& img, cv::MorphShapes kernelShape, cv::Size kernel
 	// 再高斯模糊处理(滤波);
 	cv::dilate(img, dilateImg, element);
 	// 判断图片是否空;
-	if (!dilateImg.empty())
+	if (dilateImg.empty())
+		return false;
+
+	return true;
+}
+
+CV_API bool CutPictures(cv::Mat& img, cv::Rect cvRect, cv::Mat& roiImg)
+{
+	if (img.empty())
+		return false;
+
+	if (cvRect.empty())
+		return false;
+
+	// 裁剪ROI区域;
+	roiImg = img(cvRect);
+	// 判断图片是否空;
+	if (roiImg.empty())
+		return false;
+
+	return true;
+}
+
+CV_API bool CutPictures(std::string strImgPath, cv::Rect cvRect, cv::Mat& roiImg)
+{
+	cv::Mat img;
+	// 读取图片;
+	if (!ReadImage(strImgPath, img))
+		return false;
+
+	if (cvRect.empty())
+		return false;
+
+	// 裁剪ROI区域;
+	roiImg = img(cvRect);
+	// 释放原图;
+	img.release();
+	// 判断图片是否空;
+	if (roiImg.empty())
+		return false;
+
+	return true;
+}
+
+CV_API bool CutPictures(std::string strImgPath, cv::Rect cvRect, std::string strRoiImgPath)
+{
+	cv::Mat img;
+	// 读取图片;
+	if (!ReadImage(strImgPath, img))
+		return false;
+
+	if (cvRect.empty())
+		return false;
+
+	cv::Mat roiImg;
+	// 裁剪ROI区域;
+	roiImg = img(cvRect);
+	// 释放原图;
+	img.release();
+	// 判断图片是否空;
+	if (roiImg.empty())
+		return false;
+
+	cv::imwrite(strRoiImgPath.c_str(), roiImg);
+	roiImg.release();
+
+	return true;
+}
+
+CV_API bool DrawContours(cv::Mat& binImg, cv::Mat& drawImg, bool InternalContour, bool bPerimeter, long nMinPerimeter, long nMaxPerimeter, bool bArea, long nMinArea, long nMaxArea)
+{
+	// 图片空或都不是单通道;
+	if (binImg.empty() || binImg.channels() > 1)
+		return false;
+
+	if (drawImg.empty()) {
+		// 复制到目标中;
+		binImg.copyTo(drawImg);
+		// 再转为BGR;
+		cv::cvtColor(drawImg, drawImg, cv::COLOR_GRAY2BGR);
+	}
+
+	// 轮廓;
+	vector<vector<cv::Point>> contours;
+	// 轮廓关系;
+	vector<cv::Vec4i> hierarchy;
+	// 获取轮廓区域;
+	if (InternalContour)
+	{
+		// 所有轮廓,内外轮廓分等级;
+		findContours(binImg, contours, 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(binImg, contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
+	}
+
+	vector<vector<cv::Point>>::iterator it = contours.begin();
+	for (int i = 0; it != 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;
+		}
+
+		// 随机色填充轮廓;
+		cv::Scalar color = cv::Scalar(rand() % 255, rand() % 255, rand() % 255);
+		// 输出轮廓图;
+		cv::drawContours(drawImg, contours, i, color, cv::FILLED, 8, hierarchy);
+	}
+
+	if (drawImg.empty())
+		return false;
+
+	return true;
+}
+
+CV_API bool MatchSingleImage(cv::Mat& img, cv::Mat templImg, double& matchVal, cv::Rect& matchRect)
+{
+	if (img.empty() || templImg.empty())
+		return false;
+
+	/*
+	模板匹配的匹配方式:
+	0:CV_TM_SQDIFF 平方差匹配法:最好匹配为0。 匹配越差,匹配值越大。
+		这类方法利用图像与模板各个像素差值的平方和来进行匹配,最好匹配为 0。 匹配越差,匹配值越大。
+	1:CV_TM_SQDIFF_NORMED 归一化平方差匹配法:最好匹配为0。 匹配越差,匹配值越大。
+		这个方法其实和差值平方和算法是类似的。只不过对图像和模板进行了标准化操作
+	2:CV_TM_CCORR 相关匹配法:0最差匹配,越接近1越完美;
+		这类方法采用模板和图像的互相关计算作为相似度的度量方法,所以较大的数表示匹配程度较高,0标识最坏的匹配效果。
+	3:CV_TM_CCORR_NORMED 归一化相关匹配法:0最差匹配,越接近1越完美;
+		这个方法和 标准化差值平方和匹配 类似,都是去除了亮度线性变化对相似度计算的影响。可以保证图像和模板同时变亮或变暗k倍时结果不变。
+	4:CV_TM_CCOEFF 相关系数匹配法:1表示完美的匹配;-1表示最差的匹配。
+		这种方法也叫做相关匹配,但是和上面的 CV_TM_CCORR 匹配方法还是有不通过的。简单的说,这里是把图像和模板都减去了各自的平均值,使得这两幅图像都没有直流分量
+	5:CV_TM_CCOEFF_NORMED 归一化相关系数匹配法:1表示完美的匹配;-1表示最差的匹配。
+		这是 OpenCV 支持的最复杂的一种相似度算法。
+		这里的相关运算就是数理统计学科的相关系数计算方法。
+		具体的说,就是在减去了各自的平均值之外,还要各自除以各自的方差。
+		经过减去平均值和除以方差这么两步操作之后,无论是我们的待检图像还是模板都被标准化了,
+		这样可以保证图像和模板分别改变光照亮不影响计算结果。计算出的相关系数被限制在了 -1 到 1 之间,
+		1 表示完全相同,-1 表示两幅图像的亮度正好相反,0 表示两幅图像之间没有线性关系。
+	*/
+	cv::Mat resultImg;
+	cv::matchTemplate(img, templ, resultImg, cv::TM_CCOEFF_NORMED);
+	if (resultImg.empty())
 		return false;
 
+	// 最小和最大匹配值;
+	double lv_nMinVal = 0.0;
+	double lv_nMaxVal = 0.0;
+	// 匹配的坐标点;
+	cv::Point lv_nMinLoc = cv::Point(0, 0);
+	cv::Point lv_nMaxLoc = cv::Point(0, 0);
+	cv::minMaxLoc(resultImg, &lv_nMinVal, &lv_nMaxVal, &lv_nMinLoc, &lv_nMaxLoc);
+
+	// TM_CCOEFF_NORMED匹配是取最大值为匹配值;
+	matchVal = lv_nMaxVal;
+	// 匹配区域,使用最大区域;
+	matchRect.x = lv_nMaxLoc.x;
+	matchRect.y = lv_nMaxLoc.y;
+	matchRect.width = templ.cols;
+	matchRect.height = templ.rows;
+
+#ifdef _DEBUG
+	// 在原图上框出模板位置;
+	cv::Mat showImg;
+	img.copyTo(showImg);
+	cv::rectangle(showImg,
+		cv::Point(lv_nMaxLoc.x, lv_nMaxLoc.y),
+		cv::Point(lv_nMaxLoc.x + templ.cols, lv_nMaxLoc.y + templ.rows),
+		cv::Scalar(rand() % 255, rand() % 255, rand() % 255),
+		2,
+		cv::LINE_AA,
+		0);
+	// 输出到文件中;
+	imwrite("showImg.png", showImg);
+#endif
+
+	return true;
+}
+
+CV_API bool MatchSingleImage(cv::Mat& img, std::string strTmpImg, double& matchVal, cv::Rect& matchRect)
+{
+	if (img.empty() || !PathFileExists(strTmpImg.c_str()))
+		return false;
+
+	// 读取模板图片;
+	cv::Mat templ = imread(strTmpImg.c_str(), cv::IMREAD_COLOR);
+	if (templ.empty())
+		return false;
+
+	cv::Mat resultImg;
+	cv::matchTemplate(img, templ, resultImg, cv::TM_CCOEFF_NORMED);
+	if (resultImg.empty() )
+		return false;
+
+	// 最小和最大匹配值;
+	double lv_nMinVal = 0.0;
+	double lv_nMaxVal = 0.0;
+	// 匹配的坐标点;
+	cv::Point lv_nMinLoc = cv::Point(0, 0);
+	cv::Point lv_nMaxLoc = cv::Point(0, 0);
+	cv::minMaxLoc(resultImg, &lv_nMinVal, &lv_nMaxVal, &lv_nMinLoc, &lv_nMaxLoc);
+	
+	// TM_CCOEFF_NORMED匹配是取最大值为匹配值;
+	matchVal = lv_nMaxVal;
+	// 匹配区域,使用最大区域;
+	matchRect.x = lv_nMaxLoc.x;
+	matchRect.y = lv_nMaxLoc.y;
+	matchRect.width = templ.cols;
+	matchRect.height = templ.rows;
+
+#ifdef _DEBUG
+	// 在原图上框出模板位置;
+	cv::Mat showImg;
+	img.copyTo(showImg);
+	cv::rectangle(showImg,
+		cv::Point(lv_nMaxLoc.x, lv_nMaxLoc.y), 
+		cv::Point(lv_nMaxLoc.x + templ.cols, lv_nMaxLoc.y + templ.rows),
+		cv::Scalar(rand() % 255, rand() % 255, rand() % 255), 
+		2, 
+		cv::LINE_AA, 
+		0);
+	// 输出到文件中;
+	imwrite("showImg.png", showImg);
+#endif
+
+	return true;
+}
+
+CV_API bool MatchSingleImage(std::string strImg, std::string strTmpImg, double& matchVal, cv::Rect& matchRect)
+{
+	cv::Mat img;
+	cv::Mat templ;
+	if (!ReadImage(strImg.c_str(), img) || !ReadImage(strTmpImg.c_str(), templ))
+		return false;
+
+	cv::Mat resultImg;
+	cv::matchTemplate(img, templ, resultImg, cv::TM_CCOEFF_NORMED);
+	if (resultImg.empty())
+		return false;
+
+	// 最小和最大匹配值;
+	double lv_nMinVal = 0.0;
+	double lv_nMaxVal = 0.0;
+	// 匹配的坐标点;
+	cv::Point lv_nMinLoc = cv::Point(0, 0);
+	cv::Point lv_nMaxLoc = cv::Point(0, 0);
+	cv::minMaxLoc(resultImg, &lv_nMinVal, &lv_nMaxVal, &lv_nMinLoc, &lv_nMaxLoc);
+
+	// TM_CCOEFF_NORMED匹配是取最大值为匹配值;
+	matchVal = lv_nMaxVal;
+	// 匹配区域,使用最大区域;
+	matchRect.x = lv_nMaxLoc.x;
+	matchRect.y = lv_nMaxLoc.y;
+	matchRect.width = templ.cols;
+	matchRect.height = templ.rows;
+
+#ifdef _DEBUG
+	// 在原图上框出模板位置;
+	cv::Mat showImg;
+	img.copyTo(showImg);
+	cv::rectangle(showImg,
+		cv::Point(lv_nMaxLoc.x, lv_nMaxLoc.y),
+		cv::Point(lv_nMaxLoc.x + templ.cols, lv_nMaxLoc.y + templ.rows),
+		cv::Scalar(rand() % 255, rand() % 255, rand() % 255),
+		2,
+		cv::LINE_AA,
+		0);
+	// 输出到文件中;
+	imwrite("showImg.png", showImg);
+#endif
+
 	return true;
 }

+ 20 - 6
cv/cv/cv.h

@@ -50,10 +50,24 @@ CV_API bool ErodeImg(cv::Mat& img, cv::MorphShapes kernelShape, cv::Size kernelS
 // 9、对图片膨胀处理
 CV_API bool DilateImg(cv::Mat& img, cv::MorphShapes kernelShape, cv::Size kernelSize, cv::Mat& dilateImg);
 
-//8、获取图片指定RGB颜色域的轮廓图像结果
-//9、裁剪图片指定区域
+// 10、裁剪图片指定区域
+CV_API bool CutPictures(cv::Mat& img, cv::Rect cvRect, cv::Mat& roiImg);
+CV_API bool CutPictures(std::string strImgPath, cv::Rect cvRect, cv::Mat& roiImg);
+CV_API bool CutPictures(std::string strImgPath, cv::Rect cvRect, std::string strRoiImgPath);
+
+// 11、输出图片二值化轮廓填充图像结果;
+// binImg必须为单通道
+// drawimg必须在binImg基础上Copyto或在原图上Copyto,即drawImg必须是binImg的克隆或原图的克隆; 
+// 如果drawImg空,则从函数内部使用binImg来克隆;
+CV_API bool DrawContours(cv::Mat& binImg, cv::Mat& drawImg, bool InternalContour, bool bPerimeter, long nMinPerimeter, long nMaxPerimeter, bool bArea, long nMinArea, long nMaxArea);
+
 //10、单个模板图片匹配
-//11、多个模板图片匹配
-//12、获取图片的LUV平均值
-//13、输出图片二值化轮廓填充图像结果
-//14、两图片相似度比较
+CV_API bool MatchSingleImage(cv::Mat& img, cv::Mat templImg, double& matchVal, cv::Rect& matchRect);
+CV_API bool MatchSingleImage(cv::Mat& img, std::string strTmpImg, double &matchVal, cv::Rect &matchRect);
+CV_API bool MatchSingleImage(std::string strImg, std::string strTmpImg, double& matchVal, cv::Rect& matchRect);
+
+// 待开发
+// 11、获取图片指定RGB颜色域的轮廓图像结果
+// 12、多个模板图片匹配
+// 13、获取图片的LUV平均值
+// 14、两图片相似度比较

+ 1 - 0
cv/cv/cv.vcxproj

@@ -175,6 +175,7 @@
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
     </ClCompile>
+    <ClCompile Include="testcpp.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="cv.rc" />

+ 3 - 0
cv/cv/cv.vcxproj.filters

@@ -38,6 +38,9 @@
     <ClCompile Include="stdafx.cpp">
       <Filter>源文件</Filter>
     </ClCompile>
+    <ClCompile Include="testcpp.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="cv.rc">

+ 88 - 0
cv/cv/testcpp.cpp

@@ -0,0 +1,88 @@
+#include "stdafx.h"
+#include "cv.h"
+
+void test()
+{
+	printf("测试用例开始!\n");
+
+	cv::Mat img;
+	cv::Mat thresholdImg;
+	ReadImage("E:\\bin\\test.jpg", img);
+	if (GetBinaryImage("E:\\bin\\test.jpg", 100, 255, thresholdImg))
+	{
+		cv::Mat drawImg;		
+		img.copyTo(drawImg);
+		DrawContours(thresholdImg, drawImg, true, false, 0, 0, false, 0, 0);
+		if (!drawImg.empty())
+		{
+			cv::imwrite("E:\\bin\\drawImg.jpg", drawImg);
+			drawImg.release();
+		}
+
+		cv::imwrite("E:\\bin\\thresholdImg.jpg", thresholdImg);
+		thresholdImg.release();
+	}
+
+	if (GetOTSUBinaryImage("E:\\bin\\test.jpg", 0, 255, thresholdImg))
+	{
+		cv::imwrite("E:\\bin\\otsu-thresholdImg.jpg", thresholdImg);
+		thresholdImg.release();
+	}
+
+	if (GetAdaptiveBinaryImage("E:\\bin\\test.jpg", 100, thresholdImg))
+	{
+		cv::imwrite("E:\\bin\\adpat-thresholdImg.jpg", thresholdImg);
+		thresholdImg.release();
+	}
+
+	if (GaussianBlur("E:\\bin\\test.jpg", cv::Size(15, 15), thresholdImg))
+	{
+		cv::imwrite("E:\\bin\\gaussImg.jpg", thresholdImg);
+		thresholdImg.release();
+	}
+
+	if (Color2Gray("E:\\bin\\test.jpg", thresholdImg))
+	{
+		cv::imwrite("E:\\bin\\grayImg.jpg", thresholdImg);
+		thresholdImg.release();
+	}
+
+	
+	if (ReadImage("E:\\bin\\test.jpg", img))
+	{
+		if (Color2Gray(img, thresholdImg))
+		{
+			cv::Mat colorImg;
+			if ( Gray2Color(thresholdImg, colorImg) )
+			{
+				cv::imwrite("E:\\bin\\colorImg.jpg", colorImg);
+				colorImg.release();
+			}
+
+			cv::imwrite("E:\\bin\\grayImg2.jpg", thresholdImg);
+			thresholdImg.release();
+		}
+
+		if (ErodeImg(img, cv::MORPH_RECT, cv::Size(15,15), thresholdImg))
+		{
+			cv::imwrite("E:\\bin\\ErodeImg.jpg", thresholdImg);
+			thresholdImg.release();
+		}
+
+		if (DilateImg(img, cv::MORPH_RECT, cv::Size(15, 15), thresholdImg))
+		{
+			cv::imwrite("E:\\bin\\DilateImg.jpg", thresholdImg);
+			thresholdImg.release();
+		}
+	}
+
+	CutPictures("E:\\bin\\test.jpg", cv::Rect(100, 100, 900, 800), "E:\\bin\\roi.jpg");
+
+	double matchVal;
+	cv::Rect matchRect;
+	MatchSingleImage("E:\\bin\\未选中1.png", "E:\\bin\\未选中.png", matchVal, matchRect);
+	printf("匹配度:%lf, 坐标:[%d,%d,%d,%d]\n", matchVal, matchRect.x, matchRect.y, matchRect.width, matchRect.height);
+
+	//////////////////////////////////////////////////////////////////////////
+	printf("测试用例结束!\n");
+}