【问题标题】:OpenCV trace contours tracing whole image as largest contour?OpenCV跟踪轮廓将整个图像跟踪为最大轮廓?
【发布时间】:2021-03-12 18:10:43
【问题描述】:

我正在尝试生成用于训练神经网络的数据集,这需要我在视频的多个帧中围绕移动对象(蜗牛)进行裁剪。

我已将视频分割成帧并使用 OpenCV 通过使用 HSV 阈值和轮廓跟踪来裁剪对象,如下所示:

import cv2 
import pandas as pd 
import matplotlib
import numpy as np
from PIL import Image
from matplotlib import pyplot as plt

img = cv2.imread("./pngs/04Feb21_1_crop/20000.png")
img_edit = cv2.imread("./pngs/04Feb21_1_crop/20000.png")

hsv_img = cv2.cvtColor(img_edit, cv2.COLOR_BGR2HSV)
plt.imshow(hsv_img) ## 1

low = np.array([99, 109, 77] )
high = np.array([115, 255, 255])
curr_mask = cv2.inRange(hsv_img, low, high)
hsv_img[curr_mask > 0] = ([84, 255, 200])

# converting the hsv image to gray in order to be able to apply
# contouring
RGB_again = cv2.cvtColor(hsv_img, cv2.COLOR_HSV2RGB)
gray = cv2.cvtColor(RGB_again, cv2.COLOR_RGB2GRAY)

ret, threshold = cv2.threshold(gray, 90, 255, 0)
plt.imshow(threshold, cmap="binary")

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11,11))
threshold = cv2.morphologyEx(threshold, cv2.MORPH_OPEN, kernel)
threshold = cv2.morphologyEx(threshold, cv2.MORPH_CLOSE, kernel)

contours, hierarchy =  cv2.findContours(threshold,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
img_edit = cv2.drawContours(img_edit, contours, -1, (0,255,0), 3)
plt.imshow(img_edit)

正如您在此处看到的,底部的绿线表示存在包含照片底部边缘的轮廓。因此,当我选择最大的轮廓并围绕它进行裁剪时,如下所示:

# find largest contour
areaArray = []
count = 1

for i, c in enumerate(contours):
    area = cv2.contourArea(c)
    areaArray.append(area)

#first sort the array by area
sorteddata = sorted(zip(areaArray, contours), key=lambda x: x[0], reverse=True)

#find the nth largest contour [n-1][1], in this case 2
largestcontour = sorteddata[0][1]

x,y,w,h = cv2.boundingRect(largestcontour)
crop = img[y:y+h, x:x+w]
plt.imshow(crop)

整个图像被裁剪,因为最大轮廓的边界矩形本质上就是图像的大小。

我一直在通过选择第二大轮廓来规避这个问题,但它不适用于我的所有框架。例如,在这个框架中,选择第二大轮廓,如下所示:

secondlargestcontour = sorteddata[1][1]

像以前一样裁剪会产生这个灰色区域:

我在 HSV 阈值方面做错了吗?是不是因为物体本身与水的阴影/反射不够清晰?

非常感谢任何和所有帮助。我是 Python 和 OpenCV 的新手,如果我遗漏了一些非常明显的东西,我提前道歉。

用于所有代码的原始图像在这里:

【问题讨论】:

    标签: python opencv


    【解决方案1】:

    我认为改变 HSV 的上下边界可以解决你的问题。

    我已将值更改为此

    low = np.array([0, 35, 0])
    high = np.array([253, 255, 255])
    

    测试代码

    import cv2
    import numpy as np
    
    image = cv2.imread("image.png")
    HSV = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    
    low = np.array([0, 35, 0])
    high = np.array([253, 255, 255])
    
    mask = cv2.inRange(HSV, low, high)
    cv2.imshow("mask", mask)
    
    result = cv2.bitwise_and(image, image, mask=mask)
    cv2.imshow("result", result)
    
    contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    sorted_contour = sorted(contours, key=lambda x: cv2.contourArea(x), reverse=True)
    
    largestcontour = sorted_contour[0]
    x, y, w, h = cv2.boundingRect(largestcontour)
    crop = image[y:y+h, x:x+w]
    
    cv2.imshow("crop", crop)
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    

    输出:

    mask image result image crop image

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-05
      • 2015-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-13
      • 2011-11-27
      • 1970-01-01
      相关资源
      最近更新 更多