【问题标题】:Python opencv remove noise in imagePython opencv 去除图像中的噪声
【发布时间】:2017-06-09 20:47:04
【问题描述】:

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

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

我尝试了各种图像转换和形态学操作,但都没有成功。我还对 HLS 范围进行了很多实验,并对其进行了设置,以便它们在我拥有的一组图像上产生最佳结果,但我仍然没有得到令人满意的结果。

原图:

代码:

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)

【问题讨论】:

  • 向我们展示代码
  • 已添加代码
  • 预期输出是什么?您提到了isolate certain colored lines(the field lines),但您没有显示原始图像或您想要的内容
  • 它不允许我添加两个以上的图像。我现在已经添加了它们。我的意思是场线。第一张图是浅蓝色粗线,第二张图是黄线。
  • 您可以在输出图像中运行 CCA 并按区域过滤。

标签: python image opencv image-processing


【解决方案1】:

您可以通过范围阈值获得比目前更好的结果。此外,尝试使用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)

除了阈值之外,第一张和第二张是相同的,第二张图像我正在对蓝色应用关闭操作(其他三个阈值未完成)以稍微关闭线条中的间隙。


目前尚不清楚您是希望自动还是手动为几张图片执行此操作。如果您希望自动执行此操作,我的第一个选择是创建一组阈值,这些阈值对所有图像都相对有效,并且对形态学操作要求苛刻。这可能会使线条变细一点,但是您可以使用 numpy 操作将曲线拟合到线条上,然后将其加宽以达到大致相同的线条。

如果您要手动执行此操作,那么最简单的方法是使用每个图像的阈值。我最近刚刚创建了一个工具,它为您提供了用于更改阈值范围和动态预览的滑块。如果您有兴趣尝试一下,请查看GitHub。它将输出二进制阈值图像、阈值颜色空间以及用于阈值的上下限。

【讨论】:

  • 非常好的答案。我有一个类似的question,但还没有得到答案。你介意检查一下吗?
  • @JohnSmith 抱歉,我从来没有玩过 OCR,所以无法帮助你。祝你好运!
猜你喜欢
  • 2017-07-05
  • 1970-01-01
  • 2014-05-22
  • 2017-06-23
  • 1970-01-01
  • 2015-08-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多