【问题标题】:Image Processing: Problem with Fish measuring图像处理:鱼测量的问题
【发布时间】:2019-04-26 17:08:40
【问题描述】:

我在绘制实时视频捕获轮廓时遇到问题。我在 Python

上使用 OpenCV

我的目标是逐个测量通过管子的罗非鱼,并通过获取矩形尺寸来获得它们的大致尺寸。 Here 是 1 条罗非鱼经过的样本。

Here 是另外一个带有背光

问题是水也被检测为轮廓,我似乎无法隔离鱼。我尝试过混合使用模糊技术、膨胀、腐蚀,但它似乎无法解决我的问题。

我可以使用其他算法吗?还是应该切换到物体检测?

这是我的代码:

#!/usr/bin/env python3
import numpy as np
import cv2
import time

kernel = np.ones((5,5),np.uint8)

cap = cv2.VideoCapture('white.mp4')

foreground_background = cv2.createBackgroundSubtractorMOG2()
while True:
    ret, frame = cap.read()

    if(type(frame) == type(None)):
        break
    gray                 = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    #gray                = cv2.GaussianBlur(gray, (21, 21), 0)
    #gray                = cv2.medianBlur(gray,11)
    gray                 = cv2.bilateralFilter(gray,9,75,75)
    ret,thresh           = cv2.threshold(gray, 127, 255 , cv2.THRESH_BINARY_INV)
    thresh               = cv2.erode(thresh, kernel, iterations=3)
    thresh               = cv2.dilate(thresh, kernel, iterations=3)
    im2, cnts, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, 
    cv2.CHAIN_APPROX_SIMPLE)
    c=None
    for c in cnts:

         (x, y, w, h) = cv2.boundingRect(c)
         cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 255, 0), 2)         

    cv2.imshow('Output', thresh)
    cv2.waitKey(2)

cap.release()
cv2.destroyAllWindows()

根据 Mark Setchell 添加的...

使用的命令:

ffmpeg -i a.mov  -r 10 frame_%05d.png
montage -tile 6x frame_*png -geometry +10+10  result.png

【问题讨论】:

  • 多年前我曾研究过类似的问题。通过改进图像采集来简化图像分析任务总是最好的。在这种情况下,我设置了一个系统,其中光学触发器使高分辨率相机在鱼通过镜头时拍摄一张照片。您正在使用带有大量压缩伪像的低分辨率相机,这绝不是一个好的开始。
  • 你能告诉我你的过程的最终轮廓吗?如果鱼大到可以区分,也许我可以帮你隔离。
  • 我希望您不介意我编辑您的问题,只需单击edit,如果您反对,请删除我添加的内容。我只是想展示各个帧,以便人们可以看到他们正在处理的内容,也许您更有可能得到答案。
  • 不,我一点也不介意!谢谢。
  • 我又添加了 1 个带背光的鱼通过的示例。

标签: python opencv image-processing object-detection opencv-contour


【解决方案1】:

我会尝试几件事,包括:

  1. 去除背景的各种方法 -- 我看到您使用了 cv2.createBackgroundSubtractorMOG2(),但更简单的方法可能会产生更好的结果。尝试在帧中没有鱼时取几十帧的平均值,然后从所有帧中减去该平均背景。像这样: background = (A+B+C)/3 其中 A、B 和 C 是没有鱼的背景帧/矩阵。现在您可以通过减法简单地从所有帧中删除背景。此外,您可以尝试从当前帧中减去前 1 个(或几个)帧,以突出显示帧之间的变化(实际上是时间导数)。这可以在一个循环中完成。
  2. 沿行和列求和 -- 列和行投影是突出图像中高对比度区域的一种非常简单的方法。据推测(如果暗值 > 亮值)列将鱼在图像中间的图像求和会产生一个高斯向量,其峰值索引对应于图像的中间列(见下图)。这也可以让您通过注意高斯向量的宽度来估计鱼的大小。

请注意,列和向量上的初始高值是光照条件的结果,可以通过背景移除来解决(参见步骤 1)。

从 python 中的 numpy 包中,您可以执行列求和,例如:

 import numpy as np
 np.sum(M,axis=1)

其中 M 是当前感兴趣的图像/矩阵/帧。

【讨论】:

  • 如何平均没有鱼的帧?我明白你在说什么,但我不知道如何将它翻译成代码。谢谢。
  • 我还添加了 1 条鱼通过背光的示例
  • 我在原始帖子中添加了一个如何平均 3 帧的示例。基本上,您将 N 个背景帧(没有鱼)加在一起,然后将该总和除以 N。然后,每当您读入一个帧时,第一步就是从当前帧/图像/矩阵中删除该平均(背景)矩阵。
猜你喜欢
  • 2017-12-08
  • 1970-01-01
  • 2016-08-11
  • 2016-08-04
  • 1970-01-01
  • 2021-01-23
  • 2019-01-20
  • 1970-01-01
  • 2015-11-25
相关资源
最近更新 更多