山东大学暑期实训(六)
由于最近要进行宿舍的搬迁工作,所以学习的进度不是很快,这里记录一下关于opencv的图像处理
1.Canny 边缘检测,参考资料[OpenCV-Python] OpenCV 中的图像处理 部分 IV (三)
1.1canny边缘检测是一种非常流行的边缘检测算法,在进行边缘检测之前,需要进行去噪处理(可以采用类似高斯滤波器).
1.2计算图像梯度:
对平滑后的图像使用 Sobel 算子计算水平方向和竖直方向的一阶导数(图像梯度)(Gx 和 Gy)。根据得到的这两幅梯度图(Gx 和 Gy)找到边界的梯度和方向
import cv2
import numpy as np
img = cv2.imread('F:/picture/desk/1.jpg')
def cv_imshow(img,name):
cv2.imshow(name,img)
cv2.waitKey()
cv2.destroyAllWindows()
sobelx=cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
# cv2.CV_64F能表示负数的形式,白-黑是正数,黑-白就是负数了,
# 所有的负数会被截断0,所以要取绝对值
# dx=1,dy=0 表示计算水平方向的,不计算竖直方向,谁为1,计算谁
cv_imshow(sobelx,'sobelx')
1.3非极大值抑制
在获得梯度的方向和大小之后,应该对整幅图像做一个扫描,去除那些非边界上的点。对每一个像素进行检查,看这个点的梯度是不是周围具有相同梯度方向的点中最大的。
1.4滞后阈值
要确定那些边界才是真正的边界。这时我们需要设置两个阈值:minVal 和 maxVal。当图像的灰度梯度高于 maxVal 时被认为是真的边界,那些低于 minVal 的边界会被抛弃。如果介于两者之间的话,就要看这个点是否与某个被确定为真正的边界点相连,如果是就认为它也是边界点,如果不是就抛弃。
2.OpenCV 中的 Canny 边界检测
2.1样例代码,opencv中只需要调用canny函数即可完成上述的步骤.
mport cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('messi5.jpg',0) # 图片路径
edges = cv2.Canny(img,100,200) # 这个函数的第一个参数是输入图像。第二和第三个分别是 minVal 和 maxVal。
plt.subplot(121),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])
plt.show()
2.2可以设置滑动条来调节阈值,来观察阈值对边界检测的影响
3.OpenCV 中的轮廓 link
3.1 什么是轮廓:
轮廓可以简单认为成将连续的点(连着边界)连在一起的曲线,具有相同、的颜色或者灰度。轮廓在形状分析和物体的检测和识别中很有用。
• 为了更加准确,要使用二值化图像。在寻找轮廓之前,要进行阈值化处理、或者 Canny 边界检测。
• 查找轮廓的函数会修改原始图像。如果你在找到轮廓之后还想使用原始图、像的话,你应该将原始图像存储到其他变量中。
• 在 OpenCV 中,查找轮廓就像在黑色背景中超白色物体,要找的物体应该是白色而背景应该是黑色。
import numpy as np
import cv2
im = cv2.imread('test.jpg')
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray,127,255,0)
image, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
# 绘制独立轮廓,如第四个轮廓:
img = cv2.drawContour(img, contours, -1, (0,255,0), 3)
# 但是大多数时候,下面的方法更有用:
img = cv2.drawContours(img, contours, 3, (0,255,0), 3)