【问题标题】:How to find contours around these objects in the colored images如何在彩色图像中找到这些对象周围的轮廓
【发布时间】:2021-11-26 17:03:26
【问题描述】:

我有一个问题,我需要找到彩色图像周围的轮廓。目前,我能够为某些图像获得良好的结果,但对于带有阴影的图像,我无法获得良好的预测。该算法有时也会遗漏图像中的一些对象。我需要一个强大的算法来帮助我以正确的方式检测不同图像的轮廓。

这是另一个例子-

import cv2
import numpy as np
import numpy as np
import cv2

from utils import getMaxContour, getFilteredLabelIndex

def get_image_dimensions(img):
    height, width, channels = img.shape
    return height,width

def create_blank_white_image(height, width):
    temp_img = np.zeros((width,height,3), np.uint8) 
    temp_img.fill(255)
    return temp_img

# Read image
inputImage = cv2.imread("new_test/images/5.png")
inputImage = cv2.resize(inputImage, (800, 800))
h,w,chn = inputImage.shape
ratio = inputImage.shape[0] / 800.0

# Create deep copy for results:
inputImageCopy = inputImage.copy()

width, height = get_image_dimensions(inputImage)
temp_img = create_blank_white_image(height, width) 

# Convert to float and divide by 255:
imgFloat = inputImage.astype(np.float) / 255.

# Calculate channel K:
kChannel = 1 - np.max(imgFloat, axis=2)

# Convert back to uint 8:
kChannel = (255*kChannel).astype(np.uint8)

_, binaryImage = cv2.threshold(kChannel, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

# Use a little bit of morphology to clean the mask:
# Set kernel (structuring element) size:
kernelSize = 5
# Set morph operation iterations:
opIterations = 2
# Get the structuring element:
morphKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (kernelSize, kernelSize))
# Perform closing:
binaryImage = cv2.morphologyEx(binaryImage, cv2.MORPH_CLOSE, morphKernel, None, None, opIterations, cv2.BORDER_REFLECT101)
cv2.imshow("binaryImage", binaryImage)

h_threshold,w_threshold = binaryImage.shape
area = h_threshold*w_threshold

(numLabels, labels, stats, centroids) = cv2.connectedComponentsWithStats(
    binaryImage, 4, cv2.CV_32S)
print("No of contours",len(stats))
filteredIdx = getFilteredLabelIndex(stats, areaHighLimit=area/2, heightUpperLimit=h_threshold*0.9, widthUpperLimit=w_threshold*0.9) # here we have to ensure that the height and the weight of the rectangle is neither to big or too small.

for i in filteredIdx:
  
    componentMask = (labels == i).astype("uint8") * 255
    cv2.waitKey(0)

    cv2.imshow("componentMask", componentMask)

    opIterations = 3
   
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
    #componentMask = cv2.dilate(componentMask, kernel, iterations=3)
    componentMask = cv2.morphologyEx(componentMask, cv2.MORPH_CLOSE, kernel, None, None, opIterations, cv2.BORDER_REFLECT101)

    cv2.imshow("componentMask", componentMask)

    cntrs = getMaxContour(componentMask)
    cv2.drawContours(inputImage, [cntrs], -1, (255, 0, 255), 4)
    cv2.imshow("contour", inputImage)     

    line_width = 4
    if int(temp_img.shape[0]/250)>line_width:
        line_width = int(temp_img.shape[0]/250)
    cv2.drawContours(temp_img, [cntrs], -1, (255,0,0),line_width )
    cv2.imshow("contour2", temp_img)

cv2.imshow("original contour", temp_img)
cv2.imwrite("new_test/my_algo_results/output/5.jpg", temp_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

【问题讨论】:

  • “算法有时也会漏掉一些对象”,哪个算法?你能提供一个minimal working example
  • 我已经提供了
  • 如果可以请提供算法不能很好地处理它的图像(在处理之前),所以我可以用它做测试。还有一点是:为什么不直接使用YOLO
  • 我已经提供了照片,我不需要边界框所以我没有使用 yolo

标签: opencv image-processing computer-vision


【解决方案1】:

正如 Bilal 所说,最好更具体地说明您正在实施的算法,但有多种方法可以解决此类问题。

  • 如果您因为阴影而无法检测边框,您可以尝试先应用Gaussian Filter 以使图像细节松散,从而更容易区分感兴趣的区域。

  • 如果你想使用新的算法,我个人喜欢Canny Edge Detection,因为它非常灵活地基于梯度方向绘制图像边缘并通过最大和最小阈值设置你需要的细节

【讨论】:

    猜你喜欢
    • 2021-02-17
    • 1970-01-01
    • 1970-01-01
    • 2016-02-16
    • 1970-01-01
    • 2016-02-21
    • 1970-01-01
    • 1970-01-01
    • 2010-10-23
    相关资源
    最近更新 更多