python - 剪切并保存通过颜色识别的对象
问题描述
所以我想制作一个可以通过颜色、位置和清晰度检测物体的程序。现在我可以通过颜色检测对象并绘制其轮廓和边界框。我的问题是,当程序识别出它的轮廓或边界框时,我真的不知道如何从图片中剪切出对象并将其保存为图片文件。
这是我的相机看到的 输入图片
我想在视频中剪掉绿色边界框内的内容与 fps 一样多,只要你能在视频中看到它。因此,如果视频是 30 fps 并且对象可见 10 秒,则需要拍摄 300 张照片。
这是代码:
我知道它看起来很糟糕,我只是想弄清楚用什么来让它工作
import cv2 as cv
import numpy as np
import os
import uuid
cap = cv.VideoCapture(1)
font = cv.FONT_HERSHEY_COMPLEX
path = os.getcwd()
print(path)
def createFolder(directory):
try:
if not os.path.exists(directory):
os.makedirs(directory)
except OSError:
print('Error: Creating directory. ' + directory)
createFolder("./data")
# folderName = '%s' % (str(uuid.uuid4()))
while cap.isOpened():
_, frame = cap.read()
hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
# blue is the chosen one for now
lower_color = np.array([82, 33, 39])
upper_color = np.array([135, 206, 194])
mask = cv.inRange(hsv, lower_color, upper_color)
kernel = np.ones((5, 5), np.uint8)
mask = cv.erode(mask, kernel)
contours, hierarchy = cv.findContours(mask, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
# find contour
for contour in contours:
area = cv.contourArea(contour)
x, y, h, w = cv.boundingRect(contour)
if area > 100:
# bounding box
# cv.rectangle(frame, (x - 40, y - 30), (x + h * 3, y + w * 3), (0, 255, 0), 1)
# cutting and saving
ext_left = tuple(contour[contour[:, :, 0].argmin()][0] - 20)
ext_right = tuple(contour[contour[:, :, 0].argmax()][0] + 20)
ext_top = tuple(contour[contour[:, :, 1].argmin()][0] - 20)
ext_bot = tuple(contour[contour[:, :, 1].argmax()][0] + 20)
outfile = '%s.jpg' % (str(uuid.uuid4()))
cropped_image = frame[ext_top[1]:ext_bot[1], ext_left[0]:ext_right[0]]
# write images to a specified folder
cv.imwrite(os.path.join(path, "/data/", outfile), cropped_image)
# outputs
cv.imshow("Frame", frame)
cv.imshow("Mask", mask)
key = cv.waitKey(1)
if key == 27:
break
cap.release()
cv.destroyAllWindows()
解决方案
专注于问题而忽略代码风格,我可以说你接近实现你的目标:)
对于裁剪对象,您可以使用 Mat copyTo 方法。这是官方 OpenCV 文档,这里是来自 OpenCV 论坛的示例。
现在,为了从轮廓创建遮罩,您可以使用已使用的相同 drawCountours 方法,但为厚度参数提供负值(例如,thickness=CV_FILLED)。您可以在此stackoverflow 帖子中查看代码片段,并在官方文档中查看详细信息。
要将图像保存到磁盘,您可以使用imwrite。
因此,简而言之,将填充轮廓绘制到蒙版并使用该蒙版仅将对象像素从视频帧复制到另一个可以保存磁盘的垫子。
我不会发布代码,而是将这个非常相似的问题与一个接受的答案分享,该答案可能包含您正在寻找的代码片段。
推荐阅读
- ios - 在启动时将内容附加到 Array
- javascript - MongoDB TTL 索引不会删除过期记录
- javascript - 带有javascript的本地文件名?
- r - 如何使用 R 包“gtsummary”在汇总表中生成效果大小 [90%CI]?表中新增ES包计算和定性指标
- php - 为什么我发送的邮件会在这个表单中命名?
- php - 安装失败,正在将 ./composer.json 和 ./composer.lock 还原为其原始内容
- windows - 如何将凭据添加到注册表并在 Powershell 脚本中使用它们
- npm - 无法发布 npm 包(E403:禁止)
- video-streaming - webrtc重新协商的向下兼容性
- python-3.x - 没有参数的 Depends 有什么作用?