本文首发于“小白学视觉”微信公众号,欢迎关注公众号
本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究!
经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍《OpenCV 4开发详解》。为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通,提前在公众号上连载部分内容,请持续关注小白。
图像的边缘指的是图像中像素灰度值突然发生变化的区域,如果将图像的每一行像素和每一列像素都描述成一个关于灰度值的函数,那么图像的边缘对应在灰度值函数中是函数值突然变大的区域。函数值的变化趋势可以用函数的导数描述。当函数值突然变大时,导数也必然会变大,而函数值变化较为平缓区域,导数值也比较小,因此可以通过寻找导数值较大的区域去寻找函数中突然变化的区域,进而确定图像中的边缘位置。图5-27给出一张含有边缘的图像,图像每一行的像素灰度值变化可以用图中下方的曲线表示。
通过像素灰度值曲线可以看出图像边缘位于曲线变化最陡峭的区域,对灰度值曲线求取一阶导数可以得到图5-28中所示的曲线,通过曲线可以看出曲线的最大值区域就是图像中的边缘。
由于图像是离散的信号,我们可以用临近的两个像素差值来表示像素灰度值函数的导数,求导形式可以用式(5.12)来表示。
这种对X轴方向求导方式对应于滤波器为
改进的求导方式对应的滤波器在X方向和Y方向分别为
根据这种方式也可以用式(5.14)所示的滤波器计算45°方向的梯度,寻找不同方向的边缘。
图像的边缘有可能是由高像素值变为低像素值,也有可能是由低像素值变成高像素值,通过式(5.13)和式(5.14)得到的正数值表示需要像素值突然由低变高,得到的负数值表示像素值由高到低,这两种都是图像的边缘,因此为了在图像中同时表示出这两种边缘信息,需要将计算的结果求取绝对值。OpenCV 4中提供了convertScaleAbs()函数用计算矩阵中所有数据的绝对值,该函数的函数原型在代码清单5-22中给出。
代码清单
- src:输入矩阵。
- dst:计算绝对值后输入矩阵。
- alpha:缩放因子,默认参数为只求取绝对值不进行缩放。
- beta:在原始数据上添加的偏值,默认参数表示不增加偏值。
该函数可以求取矩阵中所有数据的绝对值。函数前两个参数分别为输入、输出矩阵,两个参数可以是相同的变量。函数第三个和第四个参数为对绝对值的缩放和原始数据上的偏移。函数的计算原理如式(5.15)所示。
图像的边缘包含X方向的边缘和Y方向的边缘,因此分别求取两个方向的边缘后,对两个方向的边缘求取并集就是整幅图像的边缘,即将图像两个方向边缘结果相加得到整幅图像的边缘信息。为了验证这种滤波方式对于图像边缘提取的效果,在代码清单5-23中给出了利用filter2D()函数实现图像边缘检测的算法,检测的结果在图5-29中给出。需要说明的是,由于求取边缘的结果可能会有复数,不在原始图像的CV_8U的数据类型内,因此滤波后的图像数据类型不要用“-1”,而应该改为CV_16S。
代码清单
经过几个月的努力,市面上第一本OpenCV 4入门书籍《OpenCV 4开发详解》将春节后由人民邮电出版社发行。如果小伙伴觉得内容有帮助,希望到时候多多支持!
关注小白的小伙伴可以提前看到书中的内容,我们创建了学习交流群,欢迎各位小伙伴添加小白微信加入交流群,添加小白时请备注“学习OpenCV 4”。
https://u.wechat.com/MJ-57nVtXgxUyL3dTwWd014 (二维码自动识别)