提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
笔者本科时候有幸接触了OpenCV3.2.0版本的学习,后因考研压力不得不暂时停下学习的脚步,现在考研任务结束了,未来的导师也是从事的该方向,笔者又开始了新一轮的学习。回来发现OpenCV已经出到了4.5.5版本,遂重新下载新版本并决定记录这一学习历程。由于笔者水平有限,可能有错误之处还请诸位大佬多多包涵并烦请指出,让我们一起学习,共同进步。
首先需要说明的是:我是按着毛星云前辈编写的OpenCV3编程入门进行学习的,我会尽力把星云前辈的程序转成符合OpenCV4.5.5版本的。毛星云前辈于2021年12月11日不幸过世,他是我非常敬仰的一位业内大佬,我也是看他的书才开始接触OpenCV。
一、图像显示imread()与imshow()
这一段与星云前辈的OpenCV3的代码如出一辙,可以不做任何修改
使用imread函数载入到新版本的图像储存数据结构Mat类中,然后用imshow函数显示该图像。
注意:图片需要放到项目文件夹内,否则必须具体指出图片的路径。
// 引入OpenCV头文件
#include<opencv2/opencv.hpp>
// 使用OpenCV命名空间cv
using namespace cv;
int main()
{
// 【1】读入一张图片,载入图像
Mat srcImage = imread("1.jpg");
// 【2】显示载入的图片
imshow("【原始图】", srcImage);
// 【3】等待任意按键按下
waitKey(0);
}
输出结果:
二、图像腐蚀erode()
图像腐蚀使用的是erode函数,此处贴上官网上OpenCV4.5.5手册给出的说明:
void cv::erode (
InputArray src,
OutputArray dst,
InputArray kernel,
Point anchor = Point(-1,-1),
int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar & borderValue = morphologyDefaultBorderValue()
)
Python:
cv.erode( src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]] ) -> dst
第三个参数是核,即用于腐蚀的结构元素;第四个参数是锚点在元素中的位置;默认值 (-1, -1) 表示锚点位于元素中心;第五个参数是迭代次数,如果不为1将自动重复调用多次这个函数;第五个是边框类型。
原理简单来说是将目标图像中的像素值设为卷积核覆盖区域内的最小值。即:
代码如下(示例):
//-----------------------------------【头文件包含部分】---------------------------------------
// 描述:包含程序所依赖的头文件
//----------------------------------------------------------------------------------------------
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
//-----------------------------------【命名空间声明部分】---------------------------------------
// 描述:包含程序所使用的命名空间
//-----------------------------------------------------------------------------------------------
using namespace cv;
//-----------------------------------【main( )函数】--------------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始
//-----------------------------------------------------------------------------------------------
int main( )
{
//载入原图
Mat srcImage = imread("1.jpg");
//显示原图
imshow("【原图】腐蚀操作", srcImage);
//进行腐蚀操作
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
Mat dstImage;
erode(srcImage, dstImage, element);
//显示效果图
imshow("【效果图】腐蚀操作", dstImage);
waitKey(0);
return 0;
}
结果:
图像腐蚀通常用于消除图中斑点一样的噪声,原理是斑点经过腐蚀后会消失而大色块不被影响
三、图像模糊blur()
图像模糊使用的是blur函数,此处贴上官网上OpenCV4.5.5手册给出的说明:
void cv::blur ( InputArray src,
OutputArray dst,
Size ksize,
Point anchor = Point(-1,-1),
int borderType = BORDER_DEFAULT
)
Python:
cv.blur( src, ksize[, dst[, anchor[, borderType]]] ) -> dst
原理是目标图像中的每一个值都是原图像中相应位置一个窗口(核)的像素平均值
代码如下(示例):
// 引入OpenCV头文件
#include<opencv2/opencv.hpp>
// 使用OpenCV命名空间cv
using namespace cv;
//---------------------------------【头文件、命名空间包含部分】---------------------------
// 描述:包含程序所使用的头文件和命名空间
//-----------------------------------------------------------------------------------------------
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
//-----------------------------------【main( )函数】--------------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始
//-----------------------------------------------------------------------------------------------
int main()
{
//【1】载入原始图
Mat srcImage = imread("1.jpg");
//【2】显示原始图
imshow("均值滤波【原图】", srcImage);
//【3】进行均值滤波操作
Mat dstImage;
blur(srcImage, dstImage, Size(7, 7));
//【4】显示效果图
imshow("均值滤波【效果图】", dstImage);
waitKey(0);
}
结果:
四、边缘检测canny()
边缘检测使用的是blur函数,此处贴上官网上OpenCV4.5.5手册给出的说明:
void cv::Canny ( InputArray image,
OutputArray edges,
double threshold1,
double threshold2,
int apertureSize = 3,
bool L2gradient = false
)
Python:
cv.Canny( image, threshold1, threshold2[, edges[, apertureSize[, L2gradient]]] ) -> edges
cv.Canny( dx, dy, threshold1, threshold2[, edges[, L2gradient]] ) -> edges
还有另外一种:它是一个重载的成员函数,是为了方便而提供的。它与上述函数的不同之处仅在于它接受的参数
void cv::Canny ( InputArray dx,
InputArray dy,
OutputArray edges,
double threshold1,
double threshold2,
bool L2gradient = false
)
Python:
cv.Canny( image, threshold1, threshold2[, edges[, apertureSize[, L2gradient]]] ) -> edges
cv.Canny( dx, dy, threshold1, threshold2[, edges[, L2gradient]] ) -> edges
如果L2gradient取true采用根号下(dI/dx)2+(dI/dy)2,否则采用|dI/dx|+|dI/dy|
代码如下(示例):
//---------------------------------【头文件、命名空间包含部分】----------------------------
// 描述:包含程序所使用的头文件和命名空间
//-------------------------------------------------------------------------------------------------
#include <opencv2/opencv.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
//-----------------------------------【main( )函数】--------------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始
//-------------------------------------------------------------------------------------------------
int main()
{
//【0】载入原始图
Mat srcImage = imread("1.jpg"); //工程目录下应该有一张名为1.jpg的素材图
imshow("【原始图】Canny边缘检测", srcImage); //显示原始图
Mat dstImage, edge, grayImage; //参数定义
//【1】创建与src同类型和大小的矩阵(dst)
dstImage.create(srcImage.size(), srcImage.type());
//【2】将原图像转换为灰度图像
//此句代码的OpenCV2版为:
//cvtColor( srcImage, grayImage, CV_BGR2GRAY );
//此句代码的OpenCV3版为:
cvtColor(srcImage, grayImage, COLOR_BGR2GRAY);
//【3】先用使用 3x3内核来降噪
blur(grayImage, edge, Size(3, 3));
//【4】运行Canny算子
Canny(edge, edge, 3, 9, 3);
//【5】显示效果图
imshow("【效果图】Canny边缘检测", edge);
waitKey(0);
return 0;
}
结果:
总结
此次按着星云前辈给出的例程,实现了图像显示、图像腐蚀、图像模糊和边缘检测的基础功能,让我对于OpenCV有了初步的认识。