Обработка изображений: проблема с измерением рыбы - PullRequest
0 голосов
/ 24 ноября 2018

У меня проблемы с контуром захвата живого видео.Я использую библиотеку OpenCV на Python

Моя цель состоит в том, чтобы измерить рыб тилапии, проходящих через трубу одну за другой, и получить ихприблизительные размеры, получая размеры прямоугольника. Здесь - образец прохождения 1 тилапии.

Здесь - еще один с подсветкой

Проблема означает, что вода также определяется как контур, и я не могу изолировать рыбу.Я пытался использовать сочетание методов размытия, расширения, эрозии, но, похоже, это не решило мою проблему.

Есть ли другие алгоритмы, которые я могу использовать?Или я должен переключиться на Обнаружение объекта?

Вот мой код:

#!/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()

Следующее добавлено Марком Сетчеллом ...если кто-то хочет увидеть отдельные кадры, я извлекаю со скоростью 10 кадров в секунду и монтирую кадры следующим образом:

enter image description here

Используемые команды:

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

1 Ответ

0 голосов
/ 28 ноября 2018

Я бы попробовал несколько вещей, включая:

  1. Различные способы удаления фона - Я вижу, вы использовали cv2.createBackgroundSubtractorMOG2 () , но прощеметоды могут дать лучшие результаты.Попробуйте взять среднее из нескольких десятков кадров, когда в кадре нет рыбы, а затем вычтите этот средний фон из всех кадров.Примерно так: background = (A + B + C) / 3, где A, B и C - фоновые кадры / матрицы без рыбы.Теперь вы можете просто удалить фон из всех кадров с вычитанием.Кроме того, вы можете попытаться вычесть предыдущие 1 (или несколько) кадров из текущего кадра, чтобы выделить изменения между кадрами (фактически производная по времени).Это может быть сделано в цикле.
  2. Сумма по строкам и столбцам - проекции по столбцам и строкам являются очень простым способом выделения областей с высокой контрастностью на изображении.Предположительно (если темные значения> светлые значения) столбец, суммирующий изображение, где рыба была в середине изображения, дал бы гауссово выглядящий вектор с индексом пика, соответствующим среднему столбцу изображения (см. Рисунок ниже).Это также даст вам возможность оценить размер рыбы, отметив ширину гауссовского вектора.

enter image description here

Обратите внимание, что начальные высокие значения для вектора суммы столбцов являются результатом условий освещения и будут исправлены путем удаления фона (см. шаг 1).

Из пакета numpy в python вы можете выполнять сумму столбцов с чем-то вроде:

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

Где M - текущее изображение / матрица / интересующий кадр.

...