gpt4 book ai didi

python - 检测和隔离绿色网球 table 板上的线条

转载 作者:太空狗 更新时间:2023-10-30 02:51:06 26 4
gpt4 key购买 nike

我正在尝试检测乒乓球板上的线,但在板(侧面)和板上也检测到一些“噪音”。

还有摆脱桌面上的品牌/措辞的问题。

基本上是想检测绿色表格上的白线。

我一直在看一些例子,但对 OpenCV 不熟悉并没有帮助:-)

Table Tennis Board Edges enter image description here

import cv2
import numpy as np

img = cv2.imread("table.jpg")
imgS = cv2.resize(img, (960, 1024))
#
# # Convert to grayscale first beforeget edges of the image

kernel_size = 5
gray = cv2.cvtColor(imgS, cv2.COLOR_BGR2GRAY)
blur_gray = cv2.GaussianBlur(gray,(kernel_size, kernel_size), 0)
# get edges of the image

edges = cv2.Canny(blur_gray, 75, 150)
lines = cv2.HoughLinesP(edges, 1, np.pi/180, 50, maxLineGap=100)


# print(lines)

# draw "lines"
for line in lines:
x1, y1, x2, y2 = line[0]
# print(line[0])
# Draw the line on original image (img) and set color to blue and thickness 2
cv2.line(imgS, (x1, y1), (x2, y2), (0, 255,0), 2)


cv2.imshow("Edges", edges)
cv2.imshow("img", imgS)
cv2.waitKey(0)
cv2.destroyAllWindows()

最佳答案

这里有一个方法

  • 将图像转换为灰度和高斯模糊
  • Canny 边缘检测
  • 创建蒙版以保持白线轮廓
  • 使用垂直内核执行形态转换以隔离垂直线
  • 使用水平内核执行形态变换以隔离水平线
  • 使用 cv2.HoughLinesP() 检测线条
  • 遍历蒙版并找到轮廓
  • 在原始图像上绘制轮廓

Canny边缘检测

接下来我们使用一个特殊的垂直内核使用 cv2.getStructuringElement()过滤掉水平线,只提取垂直线

vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,3))
remove_horizontal = cv2.morphologyEx(canny, cv2.MORPH_OPEN, vertical_kernel)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
dilate_vertical = cv2.morphologyEx(remove_horizontal, cv2.MORPH_CLOSE, kernel, iterations=5)

我们对水平内核做同样的事情,只提取水平线

horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,1))
remove_vertical = cv2.morphologyEx(canny, cv2.MORPH_OPEN, horizontal_kernel)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9,9))
dilate_horizontal = cv2.morphologyEx(remove_vertical, cv2.MORPH_CLOSE, kernel, iterations=3)

我们将两者结合起来得到最终的掩码

最后我们在蒙版上找到轮廓并将其绘制在原始图像上。这是结果

import cv2
import numpy as np

image = cv2.imread('1.jpg')
image = cv2.resize(image, (960, 1024))
mask = np.zeros(image.shape, np.uint8)
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3,3), 0)
canny = cv2.Canny(blur, 150, 255, 1)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))

# Find Vertical Lines
# ------
vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,3))
remove_horizontal = cv2.morphologyEx(canny, cv2.MORPH_OPEN, vertical_kernel)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
dilate_vertical = cv2.morphologyEx(remove_horizontal, cv2.MORPH_CLOSE, kernel, iterations=5)

minLineLength = 10
maxLineGap = 150
lines = cv2.HoughLinesP(dilate_vertical,1,np.pi/180,100,minLineLength,maxLineGap)
for line in lines:
for x1,y1,x2,y2 in line:
cv2.line(mask,(x1,y1),(x2,y2),(255,255,255),3)
cv2.imwrite('vertical_mask.png', mask)
# ------

# Find Horizontal Lines
# ------
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,1))
remove_vertical = cv2.morphologyEx(canny, cv2.MORPH_OPEN, horizontal_kernel)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9,9))
dilate_horizontal = cv2.morphologyEx(remove_vertical, cv2.MORPH_CLOSE, kernel, iterations=3)

minLineLength = 10
maxLineGap = 300
horizontal_mask = np.zeros(image.shape, np.uint8)
lines = cv2.HoughLinesP(dilate_horizontal,1,np.pi/180,100,minLineLength,maxLineGap)
for line in lines:
for x1,y1,x2,y2 in line:
cv2.line(mask,(x1,y1),(x2,y2),(255,255,255),3)
cv2.line(horizontal_mask,(x1,y1),(x2,y2),(255,255,255),3)
cv2.imwrite('horizontal_mask.png', horizontal_mask)
# ------

mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
cnts = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
cv2.drawContours(image, [c], -1, (36,255,12), 2)

cv2.imwrite('remove_vertical.png', remove_vertical)
cv2.imwrite('remove_horizontal.png', remove_horizontal)
cv2.imwrite('dilate_horizontal.png', dilate_horizontal)
cv2.imwrite('mask.png', mask)
cv2.imwrite('image.png', image)
cv2.waitKey()

笔记:其他可能的策略和想法

  • 使用颜色阈值和 cv2.inRange() 来隔离白线。
  • 要过滤掉网络,您可以使用上述方法的修改版本,但不使用 cv2.HoughLinesP(),而是使用 Numpy 切片仅提取上半部分/下半部分并仅搜索对于使用图像顶部 1/4 和底部 1/4 的行。也许是这样的
top_half = remove_vertical[0:int(image.shape[0] * .25), 0:image.shape[1]]
bottom_half = remove_vertical[int(image.shape[0] * .75):image.shape[0], 0:image.shape[1]]

只隔离中线的策略

  • 将图像转换为灰度和高斯模糊
  • Canny 边缘检测
  • 使用垂直内核执行形态转换
  • 扩张以增强轮廓
  • 使用轮廓区域查找轮廓并进行过滤

Canny边缘检测

接下来我们使用一个特殊的垂直内核使用 cv2.getStructuringElement()过滤掉水平线,只提取垂直线

vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,9))
remove_horizontal = cv2.morphologyEx(canny, cv2.MORPH_OPEN, vertical_kernel)

最后,我们扩张以增强轮廓并使用最小阈值区域进行过滤。这是结果

import cv2

image = cv2.imread('1.jpg')
image = cv2.resize(image, (960, 1024))
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (7,7), 0)
canny = cv2.Canny(blur, 120, 255, 1)

vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,9))
remove_horizontal = cv2.morphologyEx(canny, cv2.MORPH_OPEN, vertical_kernel)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
dilate = cv2.morphologyEx(remove_horizontal, cv2.MORPH_CLOSE, kernel)

cnts = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

for c in cnts:
area = cv2.contourArea(c)
if area > 50:
cv2.drawContours(image, [c], -1, (36,255,12), 3)

cv2.imwrite('result.png', image)
cv2.imwrite('canny.png', canny)
cv2.imwrite('remove_horizontal.png', remove_horizontal)
cv2.waitKey()

关于python - 检测和隔离绿色网球 table 板上的线条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57149788/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com