问题定义
在现实中,经常遇到一张图片中包含了多个物体,那么如何高亮展示出物体的线条轮廓。
解决方案
opencv中提供了一个函数叫做Canny,他可以高亮展示灰度图片中的线条轮廓。通过Imgproc类中的cvtCorolr函数可以让图片改变颜色。
原理探索
假如有一张图片需要高亮显示边缘线条轮廓。
1、首先使用Imread()方法加载到Mat中。
2、再使用Imgproc中的cvtColor()方法进行改变颜色,通过使用COLOR_RGB2GRAY常量来设置矩阵变成黑白色(二极法)。
3、把黑白色的矩阵带入Canny()中
//Canny介绍:
Canny(Mat image, Mat edges, double threshold1, double threshold2, int apertureSize, boolean L2gradient)
image: 源矩阵
edges: 目标矩阵
threshold1: 低阈值,本文采用150.0
threshold2: 高阈值,通常是低阈值的2倍或者3倍
apertureSize: Sobel 算子内核大小 , 3~7之间的一个奇数,本文使用3.光圈值越大,被检测到的轮廓越多。(~~ 有地方把apertureSize 翻译为光圈,他们的理解为光圈越大,通光越多,被检测的轮廓就越多 ~~ )
L2梯度: 本文设置为true
/*
对每一个像素,Canny使用一个卷积矩阵包含一个核心像素和它的邻居像素,得到一个梯度值。
如果梯度值大于高阈值,那么它就会被检测到是一个边界。
如果梯度值在高阈值和低阈值之间,并且有个高度阈值和它连接,那么它就会被保留。
*/
开始编写代码:
/**
* 高亮显示图片中的物体
* 有个函数 Canny 边缘算法
*/
public void test12(){
Mat tools = Imgcodecs.imread(inPath+"tools.jpg");
//图片置灰
Mat grayTools = new Mat();
Imgproc.cvtColor(tools,grayTools,Imgproc.COLOR_RGB2GRAY);
//高亮识别
Mat cannyTools=new Mat();
Imgproc.Canny(grayTools,cannyTools,150.0,300.0,3,true);
HighGui.imshow("原始图片",tools);
HighGui.imshow("置灰后的图片",grayTools);
HighGui.imshow("高亮后的图片",cannyTools);
HighGui.waitKey(0);
}
在现实场景中,假如为了节省打印机油墨等资源,把矩阵中的白色变黑色、黑色变白色,可以通过Imgproc中的方法bitwise_not(Mat src , Mat edges)来实现