图像的矩

矩的计算:moments()函数

计算轮廓面积:contourArea()函数



  1. #include "opencv2/highgui/highgui.hpp"
  2. #include "opencv2/imgproc/imgproc.hpp"
  3. #include<iostream>
  4. using namespace cv;
  5. using namespace std;
  6. //-----------------------------------【main( )函数】--------------------------------------------
  7. // 描述:控制台应用程序的入口函数,我们的程序从这里开始执行
  8. //-----------------------------------------------------------------------------------------------
  9. int main()
  10. {
  11. vector<Point> contour;
  12. contour.push_back(Point2f(0, 0));
  13. contour.push_back(Point2f(10, 0));
  14. contour.push_back(Point2f(10, 10));
  15. contour.push_back(Point2f(5, 4));
  16. double area0 = contourArea(contour);
  17. vector<Point> approx;
  18. approxPolyDP(contour, approx, 5, true);
  19. double area1 = contourArea(approx);
  20. cout << "area0=" << area0 << endl << "area1=" << area1 << endl << "approx poly vertices=" << approx.size() << endl;
  21. waitKey(0);
  22. system("pause");
  23. return(0);
  24. }

计算轮廓长度:arcLength()函数



综合实例程序:查找和绘制图像轮廓矩

  1. #include "opencv2/highgui/highgui.hpp"
  2. #include "opencv2/imgproc/imgproc.hpp"
  3. #include <iostream>
  4. using namespace cv;
  5. using namespace std;
  6. //-----------------------------------【宏定义部分】--------------------------------------------
  7. // 描述:定义一些辅助宏
  8. //------------------------------------------------------------------------------------------------
  9. #define WINDOW_NAME1 "【原始图】" //为窗口标题定义的宏
  10. #define WINDOW_NAME2 "【图像轮廓】" //为窗口标题定义的宏
  11. //-----------------------------------【全局变量声明部分】--------------------------------------
  12. // 描述:全局变量的声明
  13. //-----------------------------------------------------------------------------------------------
  14. Mat g_srcImage; Mat g_grayImage;
  15. int g_nThresh = 100;
  16. int g_nMaxThresh = 255;
  17. RNG g_rng(12345);
  18. Mat g_cannyMat_output;
  19. vector<vector<Point> > g_vContours;
  20. vector<Vec4i> g_vHierarchy;
  21. //-----------------------------------【全局变量声明部分】--------------------------------------
  22. // 描述:全局变量的声明
  23. //-----------------------------------------------------------------------------------------------
  24. void on_ThreshChange(int, void*);
  25. static void ShowHelpText();
  26. //-----------------------------------【main( )函数】--------------------------------------------
  27. // 描述:控制台应用程序的入口函数,我们的程序从这里开始执行
  28. //-----------------------------------------------------------------------------------------------
  29. int main(int argc, char** argv)
  30. {
  31. //【0】改变console字体颜色
  32. system("color 9F");
  33. ShowHelpText();
  34. // 读入原图像, 返回3通道图像数据
  35. g_srcImage = imread("1.jpg", 1);
  36. // 把原图像转化成灰度图像并进行平滑
  37. cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);
  38. blur(g_grayImage, g_grayImage, Size(3, 3));
  39. // 创建新窗口
  40. namedWindow(WINDOW_NAME1, WINDOW_AUTOSIZE);
  41. imshow(WINDOW_NAME1, g_srcImage);
  42. //创建滚动条并进行初始化
  43. createTrackbar(" 阈值", WINDOW_NAME1, &g_nThresh, g_nMaxThresh, on_ThreshChange);
  44. on_ThreshChange(0, 0);
  45. waitKey(0);
  46. return(0);
  47. }
  48. //-----------------------------------【on_ThreshChange( )函数】-------------------------------
  49. // 描述:回调函数
  50. //-----------------------------------------------------------------------------------------------
  51. void on_ThreshChange(int, void*)
  52. {
  53. // 使用Canndy检测边缘
  54. Canny(g_grayImage, g_cannyMat_output, g_nThresh, g_nThresh * 2, 3);
  55. // 找到轮廓
  56. findContours(g_cannyMat_output, g_vContours, g_vHierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
  57. // 计算矩
  58. vector<Moments> mu(g_vContours.size());
  59. for (unsigned int i = 0; i < g_vContours.size(); i++)
  60. {
  61. mu[i] = moments(g_vContours[i], false);
  62. }
  63. // 计算中心矩
  64. vector<Point2f> mc(g_vContours.size());
  65. for (unsigned int i = 0; i < g_vContours.size(); i++)
  66. {
  67. mc[i] = Point2f(static_cast<float>(mu[i].m10 / mu[i].m00), static_cast<float>(mu[i].m01 / mu[i].m00));
  68. }
  69. // 绘制轮廓
  70. Mat drawing = Mat::zeros(g_cannyMat_output.size(), CV_8UC3);
  71. for (unsigned int i = 0; i < g_vContours.size(); i++)
  72. {
  73. Scalar color = Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255));//随机生成颜色值
  74. drawContours(drawing, g_vContours, i, color, 2, 8, g_vHierarchy, 0, Point());//绘制外层和内层轮廓
  75. circle(drawing, mc[i], 4, color, -1, 8, 0);;//绘制圆
  76. }
  77. // 显示到窗口中
  78. namedWindow(WINDOW_NAME2, WINDOW_AUTOSIZE);
  79. imshow(WINDOW_NAME2, drawing);
  80. // 通过m00计算轮廓面积并且和OpenCV函数比较
  81. printf("\t 输出内容: 面积和轮廓长度\n");
  82. for (unsigned int i = 0; i < g_vContours.size(); i++)
  83. {
  84. printf(" >通过m00计算出轮廓[%d]的面积: (M_00) = %.2f \n OpenCV函数计算出的面积=%.2f , 长度: %.2f \n\n", i, mu[i].m00, contourArea(g_vContours[i]), arcLength(g_vContours[i], true));
  85. Scalar color = Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255));
  86. drawContours(drawing, g_vContours, i, color, 2, 8, g_vHierarchy, 0, Point());
  87. circle(drawing, mc[i], 4, color, -1, 8, 0);
  88. }
  89. }
  90. //-----------------------------------【ShowHelpText( )函数】-----------------------------
  91. // 描述:输出一些帮助信息
  92. //----------------------------------------------------------------------------------------------
  93. void ShowHelpText()
  94. {
  95. //输出欢迎信息和OpenCV版本
  96. printf("\n\n\t\t\t 当前使用的OpenCV版本为:" CV_VERSION);
  97. printf("\n\n ----------------------------------------------------------------------------\n");
  98. }

分水岭算法



实现分水岭算法:watershed()函数

综合示例程序:分水岭算法

  1. #include "opencv2/imgproc/imgproc.hpp"
  2. #include "opencv2/highgui/highgui.hpp"
  3. #include <iostream>
  4. using namespace cv;
  5. using namespace std;
  6. //-----------------------------------【宏定义部分】--------------------------------------------
  7. // 描述:定义一些辅助宏
  8. //------------------------------------------------------------------------------------------------
  9. #define WINDOW_NAME1 "【程序窗口1】" //为窗口标题定义的宏
  10. #define WINDOW_NAME2 "【分水岭算法效果图】" //为窗口标题定义的宏
  11. //-----------------------------------【全局函变量声明部分】--------------------------------------
  12. // 描述:全局变量的声明
  13. //-----------------------------------------------------------------------------------------------
  14. Mat g_maskImage, g_srcImage;
  15. Point prevPt(-1, -1);
  16. //-----------------------------------【全局函数声明部分】--------------------------------------
  17. // 描述:全局函数的声明
  18. //-----------------------------------------------------------------------------------------------
  19. static void ShowHelpText();
  20. static void on_Mouse(int event, int x, int y, int flags, void*);
  21. //-----------------------------------【main( )函数】--------------------------------------------
  22. // 描述:控制台应用程序的入口函数,我们的程序从这里开始执行
  23. //-----------------------------------------------------------------------------------------------
  24. int main(int argc, char** argv)
  25. {
  26. //【0】改变console字体颜色
  27. system("color 6F");
  28. //【0】显示帮助文字
  29. ShowHelpText();
  30. //【1】载入原图并显示,初始化掩膜和灰度图
  31. g_srcImage = imread("1.jpg", 1);
  32. imshow(WINDOW_NAME1, g_srcImage);
  33. Mat srcImage, grayImage;
  34. g_srcImage.copyTo(srcImage);
  35. cvtColor(g_srcImage, g_maskImage, COLOR_BGR2GRAY);
  36. cvtColor(g_maskImage, grayImage, COLOR_GRAY2BGR);
  37. g_maskImage = Scalar::all(0);
  38. //【2】设置鼠标回调函数
  39. setMouseCallback(WINDOW_NAME1, on_Mouse, 0);
  40. //【3】轮询按键,进行处理
  41. while (1)
  42. {
  43. //获取键值
  44. int c = waitKey(0);
  45. //若按键键值为ESC时,退出
  46. if ((char)c == 27)
  47. break;
  48. //按键键值为2时,恢复源图
  49. if ((char)c == '2')
  50. {
  51. g_maskImage = Scalar::all(0);
  52. srcImage.copyTo(g_srcImage);
  53. imshow("image", g_srcImage);
  54. }
  55. //若检测到按键值为1或者空格,则进行处理
  56. if ((char)c == '1' || (char)c == ' ')
  57. {
  58. //定义一些参数
  59. int i, j, compCount = 0;
  60. vector<vector<Point> > contours;
  61. vector<Vec4i> hierarchy;
  62. //寻找轮廓
  63. findContours(g_maskImage, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
  64. //轮廓为空时的处理
  65. if (contours.empty())
  66. continue;
  67. //拷贝掩膜
  68. Mat maskImage(g_maskImage.size(), CV_32S);
  69. maskImage = Scalar::all(0);
  70. //循环绘制出轮廓
  71. for (int index = 0; index >= 0; index = hierarchy[index][0], compCount++)
  72. drawContours(maskImage, contours, index, Scalar::all(compCount + 1), -1, 8, hierarchy, INT_MAX);
  73. //compCount为零时的处理
  74. if (compCount == 0)
  75. continue;
  76. //生成随机颜色
  77. vector<Vec3b> colorTab;
  78. for (i = 0; i < compCount; i++)
  79. {
  80. int b = theRNG().uniform(0, 255);
  81. int g = theRNG().uniform(0, 255);
  82. int r = theRNG().uniform(0, 255);
  83. colorTab.push_back(Vec3b((uchar)b, (uchar)g, (uchar)r));
  84. }
  85. //计算处理时间并输出到窗口中
  86. double dTime = (double)getTickCount();
  87. watershed(srcImage, maskImage);
  88. dTime = (double)getTickCount() - dTime;
  89. printf("\t处理时间 = %gms\n", dTime*1000. / getTickFrequency());
  90. //双层循环,将分水岭图像遍历存入watershedImage中
  91. Mat watershedImage(maskImage.size(), CV_8UC3);
  92. for (i = 0; i < maskImage.rows; i++)
  93. for (j = 0; j < maskImage.cols; j++)
  94. {
  95. int index = maskImage.at<int>(i, j);
  96. if (index == -1)
  97. watershedImage.at<Vec3b>(i, j) = Vec3b(255, 255, 255);
  98. else if (index <= 0 || index > compCount)
  99. watershedImage.at<Vec3b>(i, j) = Vec3b(0, 0, 0);
  100. else
  101. watershedImage.at<Vec3b>(i, j) = colorTab[index - 1];
  102. }
  103. //混合灰度图和分水岭效果图并显示最终的窗口
  104. watershedImage = watershedImage * 0.5 + grayImage * 0.5;
  105. imshow(WINDOW_NAME2, watershedImage);
  106. }
  107. }
  108. return 0;
  109. }
  110. //-----------------------------------【onMouse( )函数】---------------------------------------
  111. // 描述:鼠标消息回调函数
  112. //-----------------------------------------------------------------------------------------------
  113. static void on_Mouse(int event, int x, int y, int flags, void*)
  114. {
  115. //处理鼠标不在窗口中的情况
  116. if (x < 0 || x >= g_srcImage.cols || y < 0 || y >= g_srcImage.rows)
  117. return;
  118. //处理鼠标左键相关消息
  119. if (event == EVENT_LBUTTONUP || !(flags & EVENT_FLAG_LBUTTON))
  120. prevPt = Point(-1, -1);
  121. else if (event == EVENT_LBUTTONDOWN)
  122. prevPt = Point(x, y);
  123. //鼠标左键按下并移动,绘制出白色线条
  124. else if (event == EVENT_MOUSEMOVE && (flags & EVENT_FLAG_LBUTTON))
  125. {
  126. Point pt(x, y);
  127. if (prevPt.x < 0)
  128. prevPt = pt;
  129. line(g_maskImage, prevPt, pt, Scalar::all(255), 5, 8, 0);
  130. line(g_srcImage, prevPt, pt, Scalar::all(255), 5, 8, 0);
  131. prevPt = pt;
  132. imshow(WINDOW_NAME1, g_srcImage);
  133. }
  134. }
  135. //-----------------------------------【ShowHelpText( )函数】----------------------------------
  136. // 描述:输出一些帮助信息
  137. //----------------------------------------------------------------------------------------------
  138. static void ShowHelpText()
  139. {
  140. //输出欢迎信息和OpenCV版本
  141. printf("\n\n\t\t\t 当前使用的OpenCV版本为:" CV_VERSION);
  142. printf("\n\n ----------------------------------------------------------------------------\n");
  143. //输出一些帮助信息
  144. printf("\n\n\n\t欢迎来到【分水岭算法】示例程序~\n\n");
  145. printf("\t请先用鼠标在图片窗口中标记出大致的区域,\n\n\t然后再按键【1】或者【SPACE】启动算法。"
  146. "\n\n\t按键操作说明: \n\n"
  147. "\t\t键盘按键【1】或者【SPACE】- 运行的分水岭分割算法\n"
  148. "\t\t键盘按键【2】- 恢复原始图片\n"
  149. "\t\t键盘按键【ESC】- 退出程序\n\n\n");
  150. }

图像修补





实现图像修补:inpaint()函数



综合示例程序:图像修补

  1. #include "opencv2/highgui/highgui.hpp"
  2. #include "opencv2/imgproc/imgproc.hpp"
  3. #include "opencv2/photo/photo.hpp"
  4. #include <iostream>
  5. using namespace cv;
  6. using namespace std;
  7. //-----------------------------------【宏定义部分】--------------------------------------------
  8. // 描述:定义一些辅助宏
  9. //----------------------------------------------------------------------------------------------
  10. #define WINDOW_NAME0 "【原始图参考】" //为窗口标题定义的宏
  11. #define WINDOW_NAME1 "【原始图】" //为窗口标题定义的宏
  12. #define WINDOW_NAME2 "【修补后的效果图】" //为窗口标题定义的宏
  13. //-----------------------------------【全局变量声明部分】--------------------------------------
  14. // 描述:全局变量声明
  15. //-----------------------------------------------------------------------------------------------
  16. Mat srcImage0, srcImage1, inpaintMask;
  17. Point previousPoint(-1, -1);//原来的点坐标
  18. //-----------------------------------【ShowHelpText( )函数】----------------------------------
  19. // 描述:输出一些帮助信息
  20. //----------------------------------------------------------------------------------------------
  21. static void ShowHelpText()
  22. {
  23. //输出欢迎信息和OpenCV版本
  24. printf("\n\n\t\t\t 当前使用的OpenCV版本为:" CV_VERSION);
  25. printf("\n\n ----------------------------------------------------------------------------\n");
  26. //输出一些帮助信息
  27. printf("\n\n\n\t欢迎来到【图像修复】示例程序~\n");
  28. printf("\n\t请在进行图像修复操作之前,在【原始图】窗口中进行适量的绘制"
  29. "\n\n\t按键操作说明: \n\n"
  30. "\t\t【鼠标左键】-在图像上绘制白色线条\n\n"
  31. "\t\t键盘按键【ESC】- 退出程序\n\n"
  32. "\t\t键盘按键【1】或【SPACE】-进行图像修复操作 \n\n");
  33. }
  34. //-----------------------------------【On_Mouse( )函数】--------------------------------
  35. // 描述:响应鼠标消息的回调函数
  36. //----------------------------------------------------------------------------------------------
  37. static void On_Mouse(int event, int x, int y, int flags, void*)
  38. {
  39. //鼠标左键弹起消息
  40. if (event == EVENT_LBUTTONUP || !(flags & EVENT_FLAG_LBUTTON))
  41. previousPoint = Point(-1, -1);
  42. //鼠标左键按下消息
  43. else if (event == EVENT_LBUTTONDOWN)
  44. previousPoint = Point(x, y);
  45. //鼠标按下并移动,进行绘制
  46. else if (event == EVENT_MOUSEMOVE && (flags & EVENT_FLAG_LBUTTON))
  47. {
  48. Point pt(x, y);
  49. if (previousPoint.x < 0)
  50. previousPoint = pt;
  51. //绘制白色线条
  52. line(inpaintMask, previousPoint, pt, Scalar::all(255), 5, 8, 0);
  53. line(srcImage1, previousPoint, pt, Scalar::all(255), 5, 8, 0);
  54. previousPoint = pt;
  55. imshow(WINDOW_NAME1, srcImage1);
  56. }
  57. }
  58. //--------------------------------------【main( )函数】-----------------------------------------
  59. // 描述:控制台应用程序的入口函数,我们的程序从这里开始执行
  60. //-----------------------------------------------------------------------------------------------
  61. int main(int argc, char** argv)
  62. {
  63. //改变console字体颜色
  64. system("color 2F");
  65. //显示帮助文字
  66. ShowHelpText();
  67. //载入原始图并进行掩膜的初始化
  68. Mat srcImage = imread("1.jpg", -1);
  69. if (!srcImage.data) { printf("读取图片错误,请确定目录下是否有imread函数指定图片存在~! \n"); return false; }
  70. srcImage0 = srcImage.clone();
  71. srcImage1 = srcImage.clone();
  72. inpaintMask = Mat::zeros(srcImage1.size(), CV_8U);
  73. //显示原始图参考
  74. imshow(WINDOW_NAME0, srcImage0);
  75. //显示原始图
  76. imshow(WINDOW_NAME1, srcImage1);
  77. //设置鼠标回调消息
  78. setMouseCallback(WINDOW_NAME1, On_Mouse, 0);
  79. //轮询按键,根据不同的按键进行处理
  80. while (1)
  81. {
  82. //获取按键键值
  83. char c = (char)waitKey();
  84. //键值为ESC,程序退出
  85. if (c == 27)
  86. break;
  87. //键值为2,恢复成原始图像
  88. if (c == '2')
  89. {
  90. inpaintMask = Scalar::all(0);
  91. srcImage.copyTo(srcImage1);
  92. imshow(WINDOW_NAME1, srcImage1);
  93. }
  94. //键值为1或者空格,进行图像修补操作
  95. if (c == '1' || c == ' ')
  96. {
  97. Mat inpaintedImage;
  98. inpaint(srcImage1, inpaintMask, inpaintedImage, 3, INPAINT_TELEA);
  99. imshow(WINDOW_NAME2, inpaintedImage);
  100. }
  101. }
  102. return 0;
  103. }

opencv 6 图像轮廓与图像分割修复 3 图像的矩,分水岭,图像修补的更多相关文章

  1. opencv 6 图像轮廓与图像分割修复 2 使用多边形将轮廓包围

    使用多边形将轮廓包围 返回外部矩阵边界(boundingRect()函数) 寻找最小包围矩形(minAreaRect()函数) 寻找最小包围圆形(minEnclosingCircle函数) 用椭圆拟合 ...

  2. opencv 6 图像轮廓与图像分割修复 1 查找并绘制轮廓 寻找物体的凸包

    查找并绘制轮廓 寻找轮廓(findContours)函数 绘制轮廓(drawContours()函数) 基础实例程序:轮廓查找 #include <opencv2/opencv.hpp> ...

  3. opencv2.4.13+python2.7学习笔记--OpenCV中的图像处理--图像轮廓

    阅读对象:无要求. 1.代码 ''' OpenCV中的轮廓 轮廓可以简单认为成将连续的点(连着边界)连在一起的曲线,具有相同的颜色或者灰度.为了更加准确,要使用二值化图像.在寻找轮廓之前,要进行阈值化 ...

  4. Python 图像处理 OpenCV (15):图像轮廓

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

  5. OpenCV计算机视觉学习(8)——图像轮廓处理(轮廓绘制,轮廓检索,轮廓填充,轮廓近似)

    如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 1, ...

  6. OpenCV笔记(3)(Canny边缘检测、高斯金字塔、拉普拉斯金字塔、图像轮廓、模板匹配)

    一.Canny边缘检测 Canny边缘检测是一系列方法综合的结果.其中主要包含以下步骤: 1.使用高斯滤波器,平滑图像,滤除噪声. 2.计算图像中每个像素点的梯度强度和方向. 3.应用非极大值抑制(N ...

  7. OpenCV学习笔记(12)——OpenCV中的轮廓

    什么是轮廓 找轮廓.绘制轮廓等 1.什么是轮廓 轮廓可看做将连续的点(连着边界)连在一起的曲线,具有相同的颜色和灰度.轮廓在形态分析和物体的检测和识别中很有用. 为了更加准确,要使用二值化图像.在寻找 ...

  8. OpenCV3入门(十)图像轮廓

    1.图像轮廓 1.1图像轮廓与API函数 轮廓是一系列相连的点组成的曲线,代表了物体的基本外形,相对于边缘,轮廓是连续的,边缘并不全部连续.一般地,获取图像轮廓要经过下面几个步骤: 1)     读取 ...

  9. Opencv中的轮廓(不全)

    1.初识轮廓 为了准确,要使用二值化图像.在寻找轮廓之前,要进行阈值化处理,或者Canny边界检测. 查找轮廓的函数会修改原始图像.如果你在找到轮廓之后还想使用原始图像的话,你应该将原始图像存储到其他 ...

随机推荐

  1. 自学php有哪些好的方法

    很多php新手对于如何自学php很苦恼,找不到入门到方法,有些时候一个软件都下载不下来,后者环境都不能安装好,大大打击了学习的信心.那么如何能自学好php,学好php有哪些方法呢,接下来我就给同学们提 ...

  2. 21.Linux系统服务之大坑

    1.CentOS6启动流程 2.CentOS7启动流程 3.C6和C7的区别 4.运行级别C6&C7 0 关机 1 单用户模式 (超级权限 必须面对实体硬件) 2 暂未使用 3 字符界面(黑框 ...

  3. JVM学习记录3--垃圾收集器

    贴个图 Serial收集器 最简单的收集器,单线程,收集器会暂停用户线程,称为"stop the world". ParNew收集器 Serial收集器的多线程版本,其它类似.默认 ...

  4. linux端口查询

    常用端口 下面的表格中列举了包括在红帽企业 Linux 中的服务.守护进程.和程序所使用的最常见的通信端口.该列表还可以在 /etc/services 文件中找到.要查看由互联网号码分派局(IANA) ...

  5. windows安装web服务器看这一篇就够了(Apache PHP MySQL)

    本文将为您描述Windows Server Install Apache PHP MySQL(图文详解),Windows搭建web服务器(php+Apache+mysql) 的方法 环境准备: Win ...

  6. js控制进度条数据

    <style><!-- #time{ width:500px; height: 20px; background: red; border-radius: 10px; } --> ...

  7. 让你的sql开启氮气加速

    事情的过程是:公司有一个上百行的sql 运行在MySQL数据库,速度奇慢无比,逻辑乱七八糟,我就不贴出来了,经过这次修改想总结一下如何写一个不被人骂的sql. 说一些被人诟病的问题: 一.子查询 把你 ...

  8. spring cloud 2.x版本 Ribbon服务发现教程(内含集成Hystrix熔断机制)

    本文采用Spring cloud本文为2.1.8RELEASE,version=Greenwich.SR3 前言 本文基于前两篇文章eureka-server和eureka-client的实现. 参考 ...

  9. Logstash 安装及简单实用(同步MySql数据到Elasticsearch)(Linux)

    1.下载logstash wget https://artifacts.elastic.co/downloads/logstash/logstash-6.6.0.tar.gz 2. 解压logstas ...

  10. html获得当前日期

    <html> <head> <title> </title> </head> <body> <!-- 获得当前日期(年月日 ...