Bob's Blog

Web开发、测试框架、自动化平台、APP开发、机器学习等

返回上页首页

OpenCV边界检测并获取物体边缘坐标范围



目前在用YOLO识别物体,遇到一个场景是有多个同样的物体,但要通过另一个参照物来区分。而参照物的位置和特征并不相同,于是考虑到了使用边界检测,只要在同一区域内,便可方便灵活地标识出唯一物体。

比如我用当前网站的首页来做个例子:

这里对于人眼来说,是能看到明显的区域的概念。比如我实际想找的是'继续阅读'的按钮,但是如果用标题和距离来限定,很容易将一个按钮和下面的标题混合起来,如果要找的东西又在中间,则上下都可能混合。因此可以划分边界,从区域内去匹配。

比如常用的有Laplacian, 这里先做高斯滤波降噪,然后用拉普拉斯算子检测边缘,用numpy取出了非0的即为边缘点:

img = cv2.imread('./home.png', cv2.IMREAD_GRAYSCALE)
gaussian = cv2.GaussianBlur(img, (3, 3), 0)
dst = cv2.Laplacian(gaussian, cv2.CV_16S, ksize=3)
cv_img = cv2.convertScaleAbs(dst)
indices = np.where(cv_img != [0])
coordinates = zip(indices[0], indices[1])
for c in coordinates:
    print(c)

另外Canny也是常见的:

img = cv2.imread('./home.png', cv2.IMREAD_GRAYSCALE)
gaussian_blur = cv2.GaussianBlur(img, (3, 3), 0)
cv_Canny = cv2.Canny(gaussian_blur, 100, 200)

效果可以用imwrite或imshow能看到。

边缘倒是大致勾勒出来了,但是需要的是一个坐标范围,这样才能计算参照物和目标物体。

于是改成如下的:

import cv2
import numpy as np

image = cv2.imread('./home.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Sharpen the image
kernel = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, 0]], np.float32)
dst = cv2.filter2D(gray, -1, kernel)
# Canny Edge detection
canny = cv2.Canny(dst, 30, 200, 1)
# Find contours
cnts = cv2.findContours(canny, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2:]
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
# Iterate thorugh contours and draw rectangles around contours
cnts.reverse()
for c in cnts:
    x, y, w, h = cv2.boundingRect(c)
    cv2.rectangle(image, (x, y), (x + w, y + h), (255, 0, 255), 1)
cv2.imwrite('./home-edge.png', image)

在这里保存的图像能看到在原图上勾勒出的边缘,其中x / y / w / h便是范围了。如下图:

在这里也能看到一个问题,就是边缘太多了,而且有的是因为文字非常细,并不是需要的。

那么加一个判断即可

if w > 100 and h > 100:
    cv2.rectangle(image, (x, y), (x + w, y + h), (255, 0, 255), 1)

如下图:

此时便可归纳参照物和目标物体了。

 

参考链接:

https://stackoverflow.com/questions/52193545/python-opencv-get-coordinates-of-borders-of-elements-inside-an-image

https://www.zhihu.com/collection/463404887

下一篇:  Mac M1重装环境问题汇总
上一篇:  注册美区apple id和使用tiktok

共有0条评论

添加评论

暂无评论