Python opencv删除图像中的噪音

时间:2017-06-09 20:47:04

标签: python image opencv image-processing

我试图在一组曲棍球图像中隔离某些彩色线条(场线)。我已应用了Hue亮度饱和度(HLS)色彩空间滤镜,并设法传递原始图像中指定HLS范围内的所有组件。然而,图像的某些部分也正在通过,因为它们满足颜色范围,例如,人群的一部分和比赛场地的部分。但是,我想只隔离所需的行。我怎样才能做到这一点?

注意:我有蓝色和黄色的单独程序,因为它们需要不同的HLS范围。在某些图像中,有多行。另外,从我放置的第二张图片中可以看出,线条可能略微弯曲。在第二张图片中,如果我只能获得直线部分就足够了。

我尝试了各种图像转换和形态操作,没有运气。我已经对HLS系列做了很多实验,并设置了它们,以便它们在我拥有的一组图像上产生最佳效果,但我仍然没有得到满意的结果。

原始图片:

enter image description here enter image description here

代码:

import cv2
import numpy as np

frame = cv2.imread('hockey4.jpg')
width=900
height=600
frame = cv2.resize(frame,(width,height))
# Convert BGR to HLS
hls = cv2.cvtColor(frame, cv2.COLOR_BGR2HLS)

#HLS ranges for blue
#lower array defines the lower limit and upper array defines the upper limit of the range
#The mask is a binary image where the output is white if the corresponding pixel in the input image is between the range specified by upper and lower limits

#blue
lower = np.array([90,90,19])  #90,90,19
upper = np.array([130,190,100]) #130,190,100
mask = cv2.inRange(hls, lower, upper)

# Bitwise-AND mask and original image
res = cv2.bitwise_and(frame,frame, mask= mask)

1 个答案:

答案 0 :(得分:6)

您可以从范围阈值处理中获得比您当前获得的更好的结果。另外,尝试在阈值处理后使用morphological operations开启和关闭来删除虚假位并添加任何你不想删除的部分。

这些是我通过cv2.inRange()进行阈值处理并使用cv2.morphologyEx()打开和关闭的结果:  image 1 yellowimage 1 blueimage 2 yellowimage 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)

第一个和第二个是相同的,除了它们的阈值,第二个图像我在蓝色上应用关闭操作(没有为其他三个阈值完成)以稍微关闭线条中的间隙。 / p>

目前尚不清楚您是自动还是手动查看一些图片。如果您正在寻找自动执行此操作,我的第一个目标是创建一组阈值,这些阈值对于所有图像都相对较好,并且对形态操作要求很苛刻。这可能会使线条变得很薄,但是你可以使用numpy操作将曲线拟合到线条,然后加宽它以实现大致相同的线条。

如果您要手动完成,那么最简单的方法是使用每个图像的阈值。我刚刚创建了一个工具,可以让您通过滑块更改阈值范围并动态预览。如果您有兴趣尝试,请查看GitHub。它将输出二进制阈值图像,您要进行阈值处理的颜色空间,以及用于阈值处理的下限和上限。