【发布时间】: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 的新手,如果我遗漏了一些非常明显的东西,我提前道歉。
【问题讨论】: