Golang图片处理:学习如何进行图片的边缘提取和形状检测
如果我们需要从一张图片中提取出物体的边缘或者对物体的形状进行检测,那么我们就需要进行图片的边缘提取和形状检测。在Golang中,我们可以使用OpenCV库来对图片进行处理。
1. 安装OpenCV库
在使用OpenCV之前,我们需要先进行安装。在Golang中,我们可以使用go-opencv这个库来进行安装。在安装go-opencv时,需要先安装OpenCV库。
在Ubuntu中,我们可以使用以下命令来安装OpenCV库:
sudo apt-get install libopencv-dev
在安装好OpenCV库后,我们可以使用以下命令来安装go-opencv库:
go get -u github.com/lazywei/go-opencv
2. 图片的边缘提取
对于一张图片,如果我们需要提取它的边缘,我们可以使用Canny算法。Canny算法是一种基于梯度的边缘检测算法,它可以将图片的边缘提取出来。
2.1 使用Canny算法进行边缘提取
下面是一个简单的使用Canny算法进行边缘提取的示例代码:
package main
import (
"fmt"
"github.com/lazywei/go-opencv/opencv"
)
func main() {
img := opencv.LoadImage("./test.jpg")
defer img.Release()
gray := img.Clone()
gray.CvtColor(opencv.CV_BGR2GRAY)
edges := gray.Clone()
edges.Canny(50, 200)
defer edges.Release()
window := opencv.NewWindow("edges")
defer window.Destroy()
window.ShowImage(edges)
opencv.WaitKey(0)
}
代码中首先加载了一张JPG格式的图片,然后进行了灰度化处理。接着使用Canny算法进行边缘提取。最后,我们将提取出来的边缘通过窗口显示出来。
2.2 Canny算法的参数
Canny算法有两个参数,分别为lowThreshold和highThreshold。lowThreshold指定边缘的最低强度值,如果图像的梯度低于这个值,它将不会被认为是边缘。highThreshold指定边缘的最高强度值,如果图像的梯度超过这个值,则将认为它是边缘。如果图像的梯度位于lowThreshold和highThreshold之间,则只有当它与一个高于highThreshold的像素相连时,才会被认为是边缘。
3. 图片的形状检测
在进行形状检测时,我们需要先将图片中的某些部分进行二值化。二值化后,我们可以使用findContours函数来查找物体的轮廓。
下面是一个简单的使用findContours函数进行形状检测的示例代码:
package main
import (
"fmt"
"github.com/lazywei/go-opencv/opencv"
)
func main() {
img := opencv.LoadImage("./test.jpg")
defer img.Release()
gray := img.Clone()
gray.CvtColor(opencv.CV_BGR2GRAY)
edges := gray.Clone()
edges.Canny(50, 200)
contours := opencv.FindContours(edges, opencv.CV_RETR_LIST, opencv.CV_CHAIN_APPROX_NONE)
defer contours.Release()
for i := 0; i < len(contours); i++ {
area := opencv.ContourArea(contours[i])
if area < 100 || area > 10000 {
continue
}
rect := opencv.BoundingRect(contours[i])
img.Rectangle(rect, opencv.Scalar(0, 255, 0, 0), 2)
}
window := opencv.NewWindow("contours")
defer window.Destroy()
window.ShowImage(img)
opencv.WaitKey(0)
}
3.1 二值化
我们首先将图片进行灰度化处理,使其变成单通道图片。然后,我们可以使用threshold函数将其二值化,如下所示:
gray := img.Clone()
gray.CvtColor(opencv.CV_BGR2GRAY)
th := gray.Clone()
th.Threshold(0, 255, opencv.CV_THRESH_BINARY|opencv.CV_THRESH_OTSU)
这里我们使用了OTSU算法来自动选择二值化的阈值。如果我们不使用OTSU算法,可以手动指定阈值。
3.2 findContours函数
findContours函数可以在二值化的图像中查找物体的轮廓。它返回一个包含轮廓点集的slice,类型为[][]opencv.Point。findContours函数有三个参数:
1. contourRetrievalMode:表示轮廓的检索模式。它可以取以下值:
- CV_RETR_EXTERNAL:只检索最外面的轮廓
- CV_RETR_LIST:检索所有的轮廓,并将其存储在一个列表中
- CV_RETR_CCOMP:检索所有轮廓并将其组成两级层次结构
- CV_RETR_TREE:检索所有轮廓并重构检测到的轮廓之间的完整嵌套状态
2. contourApproximationMode:表示轮廓的近似方法。它可以取以下值:
- CV_CHAIN_APPROX_NONE:存储所有的轮廓点,不做任何近似
- CV_CHAIN_APPROX_SIMPLE:压缩水平、垂直和對角线方向上的像素,只保留终点
- CV_CHAIN_APPROX_TC89_L1、CV_CHAIN_APPROX_TC89_KCOS:应用Teh-Chin链逼近算法(TC89)
3. hierarchy:可选属性,在实现两级或多级轮廓检索时需要使用
在上面的示例代码中,我们使用了CV_RETR_LIST和CV_CHAIN_APPROX_NONE两个参数。
3.3 BoundingRect函数
BoundingBox函数可以获取轮廓的矩形边界框。它可以帮助我们进一步限制需要检测的物体的范围,如下所示:
rect := opencv.BoundingRect(contours[i])
img.Rectangle(rect, opencv.Scalar(0, 255, 0, 0), 2)
这里我们使用矩形画了一个框来圆点需要检测的物体的范围。
4. 总结
在Golang中,我们可以使用OpenCV库来进行图片的边缘提取和形状检测。对于边缘提取,我们可以使用Canny算法,它可以将图片的边缘提取出来。对于形状检测,我们可以使用二值化和findContours函数来查找物体的轮廓。
希望这篇文章能够帮助你学习Golang图片处理方面的知识,如果有疑问,欢迎在评论区留言。