【问题标题】:How to extract green objects in an image?如何在图像的多个矩形边界框中应用阈值?
【发布时间】:2019-12-26 09:32:02
【问题描述】:

我的问题是: 我有图像中对象周围的边界框的 ROI。 ROI 由 Faster R-CNN 获得。现在我想要的是应用阈值来使对象准确地包含在边界框中。该图像的 ROI 由 Faster RCNN 获得。

所以,在获得 ROI 后,我只从图像中选择 ROI 并粘贴到相同大小和尺寸的黑色图像上,结果如下图。假设

正如您所见,盒子是矩形的,因此在某些地方它会覆盖一些背景区域以及尖峰。那么,如何应用阈值处理来仅使尖峰和其他像素变为黑色?

编辑: 我已将链接添加到问题中第一张图像的 ROI 文本文件

ROI file for first image

【问题讨论】:

  • 能否也分享各个 ROI 的图像文件?如果您分别看待每张图像,应该更容易进行阈值处理
  • 好吧,因为我们有每个 ROI 的坐标。因此,您从整个图像中提取 roi 并执行处理。但它有什么帮助呢?
  • 我知道这是可能的,我要求你分享它们。评估阈值的结果会更容易,标记它们会更容易,等等。
  • 好的,我尝试编辑问题,为问题中的第一张图像提供 ROI
  • 我已经编辑了这个问题,并为有问题的第一张图像添加了一个指向 ROI 文件的链接。如果你能帮忙,那就太好了。谢谢

标签: python image opencv image-processing computer-vision


【解决方案1】:

在您的 TensorFlow 检测中,您在运行预测后获得的输出字典有一个字段“detection_scores”。

output_dict = sess.run(tensor_dict,feed_dict={image_tensor: image})

为此设置一个阈值,

 indexes=np.where(output_dict['detection_scores']>0.5)

仅在您在上一步中过滤的那些特定索引上使用这些框,即 output_dict['detection_boxes']。

[编辑] 在cmets讨论后添加更多代码

#convert the image to hsv
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
#tune the numbers below accordingly
lower_green = np.array([60, 100, 50])
upper_green = np.array([60 , 255, 255])

mask = cv2.inRange(hsv, lower_green, upper_green)
res = cv2.bitwise_and(frame,frame, mask= mask)
#res has the output masked image

[编辑] 使用问题中给出的实际图像进行编辑

img=cv2.imread("idJyc.jpg")
lower_green = np.array([0, 10, 0])
upper_green = np.array([255 , 100, 255])
mask = cv2.inRange(img, lower_green, upper_green)
mask = np.abs(255-mask)
res = cv2.bitwise_and(img,img, mask=mask)
cv2.imshow("a",res)
cv2.waitKey(0)

添加输出图像供您参考。

【讨论】:

  • 是的,我做到了。但正如您在生成的图像(第二张)中看到的那样,我们有矩形框。我想要在这些框中应用阈值以准确地获取边界框内的对象和其他像素变为黑色。
  • 我想你错过了理解我的问题。我已经有了 ROI,基于这些 ROI,我在黑色图像上粘贴了尖峰区域,但现在我想进行分割,这样我就可以准确地得到对象,剩余的像素应该变成黑色。
  • 那你一定要试试mask RCNN。既然你用盒子训练,你就会得到盒子,如果你能用像素级掩码训练,掩码 RCNN 会给你这样的结果。
  • 编辑了答案。请现在检查。我没有转换成hsv。而是我用 RGB 本身掩盖了。
  • 好的,谢谢.. 我现在正在投票,等待其他人是否也可以回答.. 否则我会将您的回答标记为已接受
【解决方案2】:

使用cv2.inRange() 的颜色阈值应该在这里工作。我假设你想隔离绿色区域

主要思路

  • 将图像转换为 HSV 格式,因为它比 RBG 更容易表示颜色
  • 使用下限/上限阈值执行颜色分割

你也可以在获得蒙版后执行morphological operations来平滑或去除噪声


import numpy as np
import cv2

image = cv2.imread('1.jpg')
result = image.copy()
image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower = np.array([18, 0, 0])
upper = np.array([179, 255, 255])
mask = cv2.inRange(image, lower, upper)
result = cv2.bitwise_and(result,result, mask=mask)
cv2.imshow('result', result)
cv2.imwrite('result.png', result)
cv2.waitKey()

您可以使用 HSV 颜色阈值脚本来隔离所需的颜色范围

import cv2
import sys
import numpy as np

def nothing(x):
    pass

# Create a window
cv2.namedWindow('image')

# create trackbars for color change
cv2.createTrackbar('HMin','image',0,179,nothing) # Hue is from 0-179 for Opencv
cv2.createTrackbar('SMin','image',0,255,nothing)
cv2.createTrackbar('VMin','image',0,255,nothing)
cv2.createTrackbar('HMax','image',0,179,nothing)
cv2.createTrackbar('SMax','image',0,255,nothing)
cv2.createTrackbar('VMax','image',0,255,nothing)

# Set default value for MAX HSV trackbars.
cv2.setTrackbarPos('HMax', 'image', 179)
cv2.setTrackbarPos('SMax', 'image', 255)
cv2.setTrackbarPos('VMax', 'image', 255)

# Initialize to check if HSV min/max value changes
hMin = sMin = vMin = hMax = sMax = vMax = 0
phMin = psMin = pvMin = phMax = psMax = pvMax = 0

img = cv2.imread('1.jpg')
output = img
waitTime = 33

while(1):

    # get current positions of all trackbars
    hMin = cv2.getTrackbarPos('HMin','image')
    sMin = cv2.getTrackbarPos('SMin','image')
    vMin = cv2.getTrackbarPos('VMin','image')

    hMax = cv2.getTrackbarPos('HMax','image')
    sMax = cv2.getTrackbarPos('SMax','image')
    vMax = cv2.getTrackbarPos('VMax','image')

    # Set minimum and max HSV values to display
    lower = np.array([hMin, sMin, vMin])
    upper = np.array([hMax, sMax, vMax])

    # Create HSV Image and threshold into a range.
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    mask = cv2.inRange(hsv, lower, upper)
    output = cv2.bitwise_and(img,img, mask= mask)

    # Print if there is a change in HSV value
    if( (phMin != hMin) | (psMin != sMin) | (pvMin != vMin) | (phMax != hMax) | (psMax != sMax) | (pvMax != vMax) ):
        print("(hMin = %d , sMin = %d, vMin = %d), (hMax = %d , sMax = %d, vMax = %d)" % (hMin , sMin , vMin, hMax, sMax , vMax))
        phMin = hMin
        psMin = sMin
        pvMin = vMin
        phMax = hMax
        psMax = sMax
        pvMax = vMax

    # Display output image
    cv2.imshow('image',output)

    # Wait longer to prevent freeze for videos.
    if cv2.waitKey(waitTime) & 0xFF == ord('q'):
        break

cv2.destroyAllWindows()

这是原始图像上的结果

【讨论】:

  • 如果您跳过 CNN 并直接对输入图像进行阈值处理,您可能会得到更好的结果。 ;)
  • @nathancy 是的,我已经看到了不同的形态学操作,如腐蚀和膨胀等,但无法得到更好的结果。您能否提供一些适用于我的案例的示例代码。感谢您的帮助
  • @FaizanKhan,对于这种情况,我认为不需要进行形态学操作,因为您没有尝试提取任何特征或轮廓。使用这些操作需要权衡取舍。例如,腐蚀会去除噪音但也会去除细节,而膨胀会增强特征但会去除细节
  • 但我只需要尖峰区域。应用基于颜色的分割只是去除背景,但我只想有尖峰。
  • 我已接受您的回答。如果您有其他可以进一步改进我的解决方案的想法,请告诉我并感谢您的时间和帮助。如果您发现我的问题有用且有效,请点赞
【解决方案3】:

如果您熟悉应用神经网络并且您正在 足够的数据。这个任务非常适合分割。

我推荐U-Net,因为它可以使用少量标记数据进行训练。对于此任务,它也快速,操作很少,复杂度相对较低。 并在各种任务中表现出良好的表现。

我还找到了full code pipeline,在这种情况下用于斑马鱼的心脏分割,但在我看来,他们在解释如何准备数据(提出标记工具等)和训练模型方面做得很好。

同样退后一步,您还可以从一开始就将您的任务解释为分段任务。特别是对于 U-Net,在同一张图像中分割多个实例应该不是问题。

【讨论】:

  • 这对我的情况有帮助吗?因为我已经为我的图像获得了投资回报率。那么,这可以用作下一步吗,或者我必须从头开始做所有事情,即为对象检测 + 分割准备数据集
  • 这绝对是一个解决方案。我会争论比任何手工制作的阈值更好的结果。如前所述,您可以使用 ROI 并在其上训练分割网络。此外,我会争辩说,您不一定首先需要对象检测器,但这当然取决于您和您的任务要求。
  • 好吧,您的解决方案如何帮助我找到更好的解决方案。获得 ROI 后,如何使用它们来获得我想要的解决方案。
  • 您是否阅读了我在此聊天上方的回答?我链接的完整代码管道基本上可以完成您想做的事情,只是在另一个数据集上。
猜你喜欢
  • 2013-02-24
  • 2015-02-13
  • 1970-01-01
  • 2020-07-11
  • 2023-01-21
  • 2020-11-23
  • 2014-09-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多