您可以通过范围阈值获得比目前更好的结果。此外,尝试使用morphological operations,例如在阈值处理后打开和关闭以删除虚假位并添加您不想删除的任何部分。
这些是我能够通过使用cv2.inRange() 进行阈值设置并使用cv2.morphologyEx() 应用打开和关闭的结果:
image 1 yellow、image 1 blue、image 2 yellow、image 2 blue
这是我第一张图片的代码:
import cv2
import numpy as np
img = cv2.imread('0.jpg')
# crop out the top of the image where the scores are
h, w = img.shape[:2]
score_h = int(h/8)
img = img[score_h:h, :]
h, w = img.shape[:2]
# blur for better thresholding
blur = cv2.GaussianBlur(img, (5,5), 1)
# threshold in HSV space
hsv = cv2.cvtColor(blur, cv2.COLOR_BGR2HSV)
# threshold for yellow
lb_y = np.array([11, 0, 153])
ub_y = np.array([52, 255, 255])
bin_y = cv2.inRange(hsv, lb_y, ub_y)
# cv2.imshow("thresh yellow", bin_y)
# cv2.waitKey(0)
# open to remove spurious yellow bits
open_kern = np.ones((3,3), dtype=np.uint8)
bin_y = cv2.morphologyEx(bin_y, cv2.MORPH_OPEN, open_kern, iterations=2)
# cv2.imshow("opened yellow", bin_y)
# cv2.waitKey(0)
# threshold for blue
lb_b = np.array([113, 41, 191])
ub_b = np.array([119, 76, 232])
bin_b = cv2.inRange(hsv, lb_b, ub_b)
# cv2.imshow("thresh blue", bin_b)
# cv2.waitKey(0)
# open to remove spurious blue bits
kern = np.ones((3,3), dtype=np.uint8)
bin_b = cv2.morphologyEx(bin_b, cv2.MORPH_OPEN, kern, iterations=2)
# cv2.imshow("opened blue", bin_b)
# cv2.waitKey(0)
# combine to show yellow detection
rip_y = img.copy()
rip_y[bin_y==0] = 0
mark_y = cv2.addWeighted(img, .4, rip_y, .6, 1)
cv2.imshow("marked yellow", mark_y)
cv2.waitKey(0)
# cv2.imwrite('0-y.jpg',mark_y)
# combine to show blue detection
rip_b = img.copy()
rip_b[bin_b==0] = 0
mark_b = cv2.addWeighted(img, .4, rip_b, .6, 1)
cv2.imshow("marked blue", mark_b)
cv2.waitKey(0)
# cv2.imwrite('0-b.jpg',mark_b)
第二个:
import cv2
import numpy as np
img = cv2.imread('1.jpg')
# crop out the top of the image where the scores are
h, w = img.shape[:2]
score_h = int(h/10)
img = img[score_h:h, :]
h, w = img.shape[:2]
# blur for better thresholding
blur = cv2.GaussianBlur(img, (5,5), 1)
# threshold in HSV space
hsv = cv2.cvtColor(blur, cv2.COLOR_BGR2HSV)
# threshold for yellow
lb_y = np.array([14, 79, 140])
ub_y = np.array([25, 255, 217])
bin_y = cv2.inRange(hsv, lb_y, ub_y)
# cv2.imshow("thresh yellow", bin_y)
# cv2.waitKey(0)
# open to remove spurious yellow bits
open_kern = np.ones((3,3), dtype=np.uint8)
bin_y = cv2.morphologyEx(bin_y, cv2.MORPH_OPEN, open_kern, iterations=2)
# cv2.imshow("opened yellow", bin_y)
# cv2.waitKey(0)
# threshold for blue
lb_b = np.array([113, 50, 150])
ub_b = np.array([135, 255, 255])
bin_b = cv2.inRange(hsv, lb_b, ub_b)
# cv2.imshow("thresh blue", bin_b)
# cv2.waitKey(0)
# close to fill in blue lines
kern = np.ones((3,3), dtype=np.uint8)
bin_b = cv2.morphologyEx(bin_b, cv2.MORPH_CLOSE, kern, iterations=2)
# cv2.imshow("closed blue", bin_b)
# cv2.waitKey(0)
# open to remove spurious lines
bin_b = cv2.morphologyEx(bin_b, cv2.MORPH_OPEN, kern, iterations=2)
# cv2.imshow("opened blue", bin_b)
# cv2.waitKey(0)
# combine to show yellow detection
rip_y = img.copy()
rip_y[bin_y==0] = 0
mark_y = cv2.addWeighted(img, .4, rip_y, .6, 1)
cv2.imshow("marked yellow", mark_y)
cv2.waitKey(0)
cv2.imwrite('1-y.jpg',mark_y)
# combine to show blue detection
rip_b = img.copy()
rip_b[bin_b==0] = 0
mark_b = cv2.addWeighted(img, .4, rip_b, .6, 1)
cv2.imshow("marked blue", mark_b)
cv2.waitKey(0)
cv2.imwrite('1-b.jpg',mark_b)
除了阈值之外,第一张和第二张是相同的,第二张图像我正在对蓝色应用关闭操作(其他三个阈值未完成)以稍微关闭线条中的间隙。
目前尚不清楚您是希望自动还是手动为几张图片执行此操作。如果您希望自动执行此操作,我的第一个选择是创建一组阈值,这些阈值对所有图像都相对有效,并且对形态学操作要求苛刻。这可能会使线条变细一点,但是您可以使用 numpy 操作将曲线拟合到线条上,然后将其加宽以达到大致相同的线条。
如果您要手动执行此操作,那么最简单的方法是使用每个图像的阈值。我最近刚刚创建了一个工具,它为您提供了用于更改阈值范围和动态预览的滑块。如果您有兴趣尝试一下,请查看GitHub。它将输出二进制阈值图像、阈值颜色空间以及用于阈值的上下限。