前言
上篇基础篇已经实现opencv环境开发的配置以及图像加载和显示,下面这篇是基于图像边缘检测实践,这里同样使用C++语言,其实我个人更擅长python,使用python实现会更加简洁,话不多说了,直接上代码。。。
opencv实现边缘检测demo
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <iostream>
#include <string>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
String imageName("1.png"); // 图片路径
Mat src,src_blur, src_gray;
src = imread(imageName); // 读取文件
if (src.empty()) {
return -1;
}
imshow("原图", src);
GaussianBlur(src, src_blur,Size(15,15),0);//高斯滤波,降噪
cvtColor(src_blur, src_gray, COLOR_BGR2GRAY);//图像转换为灰度
Mat bw;
adaptiveThreshold(~src_gray, bw, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 15, -2);
//imshow("bw", bw);
Mat horizontal = bw.clone();
Mat vertical = bw.clone();
//在水平轴上指定大小
int horizontalsize = horizontal.cols / 30;
//创建结构元素,用于通过形态运算提取水平线
Mat horizontalStructure = getStructuringElement(MORPH_RECT, Size(horizontalsize, 1));
erode(horizontal, horizontal, horizontalStructure, Point(-1, -1));
dilate(horizontal, horizontal, horizontalStructure, Point(-1, -1));
imshow("horizontal", horizontal);
//在垂直轴上指定大小
int verticalsize = vertical.rows / 30;
Mat verticalStructure = getStructuringElement(MORPH_RECT, Size(1, verticalsize));
erode(vertical, vertical, verticalStructure, Point(-1, -1));
dilate(vertical, vertical, verticalStructure, Point(-1, -1));
imshow("vertical",vertical);
//获取反向垂直图像
bitwise_not(vertical, vertical);
//imshow("vertical_bit",vertical);
//根据逻辑提取边缘和平滑图像处理
// Step 1 提取边缘
Mat edges;
adaptiveThreshold(bw, edges, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 3, -2);
imshow("edges", edges);
// Step 2 扩张
Mat kernel = Mat::ones(3, 3, CV_8UC1);
dilate(edges, edges, kernel);
//imshow("dilate", edges);
// Step 3 模糊
Mat smooth;
vertical.copyTo(smooth);
// Step 4 模糊平滑图片
blur(smooth, smooth, Size(5, 5));
smooth.copyTo(vertical, edges);
//imshow("smooth", vertical);
waitKey(0);
return 0;
}
程序运行效果如下:
检测识别效果还算可以,还有待改进,使用OpenCV函数 Canny来实现的话效果更好一些。