Есть ли способ уменьшить значение при подсчете объектов с помощью Pi-камеры?

#java #android #python

#java #Android #python

Вопрос:

В настоящее время я выполняю проект колледжа по подсчету объектов с использованием камеры на Pi. При обнаружении объекта мне нужно уменьшать количество 100 на 1 при каждом обнаружении объекта. Я использую open CV, но мне не требуется запись с камеры. Когда объект выбран, мне нужно, чтобы значение qtty_of_count было уменьшено на единицу, и это значение затем отправляется в базу данных firebase. qtty_of_count - 1 Находится в неправильном месте? Пожалуйста, помогите.

 import datetime
import math
import cv2
import numpy as np

import firebase
##from firebase import firebase



# global variables
from firebase.firebase import FirebaseApplication

width = 0
height = 0
EntranceCounter = 0
ExitCounter = 0
min_area = 3000  # Adjust ths value according to your usage
_threshold = 70  # Adjust ths value according to your usage
OffsetRefLines = 150  # Adjust ths value according to your usage


# Check if an object in entering in monitored zone
def check_entrance_line_crossing(y, coor_y_entrance, coor_y_exit):
    abs_distance = abs(y - coor_y_entrance)

    if ((abs_distance <= 2) and (y < coor_y_exit)):
        return 1
    else:
        return 0


# Check if an object in exitting from monitored zone
def check_exit_line_crossing(y, coor_y_entrance, coor_y_exit):
    abs_distance = abs(y - coor_y_exit)

    if ((abs_distance <= 2) and (y > coor_y_entrance)):
        return 1
    else:
        return 0


camera = cv2.VideoCapture(0)

# force 640x480 webcam resolution
camera.set(3, 640)
camera.set(4, 480)

ReferenceFrame = None

# Frames may discard while adjusting to light
for i in range(0, 20):
    (grabbed, Frame) = camera.read()

while True:
    (grabbed, Frame) = camera.read()
    height = np.size(Frame, 0)
    width = np.size(Frame, 1)

    # if cannot grab a frame, this program ends here.
    if not grabbed:
        break

    # gray-scale and Gaussian blur filter applying
    GrayFrame = cv2.cvtColor(Frame, cv2.COLOR_BGR2GRAY)
    GrayFrame = cv2.GaussianBlur(GrayFrame, (21, 21), 0)

    if ReferenceFrame is None:
        ReferenceFrame = GrayFrame
        continue

    # Background subtraction and image manipulation
    FrameDelta = cv2.absdiff(ReferenceFrame, GrayFrame)
    FrameThresh = cv2.threshold(FrameDelta, _threshold, 255, cv2.THRESH_BINARY)[1]

    # Dilate image and find all the contours
    FrameThresh = cv2.dilate(FrameThresh, None, iterations=2)
    cnts, _ = cv2.findContours(FrameThresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    qtty_of_count =100

    # plot reference lines (entrance and exit lines)
    coor_y_entrance = (height // 2) - OffsetRefLines
    coor_y_exit = (height // 2)   OffsetRefLines
    cv2.line(Frame, (0, coor_y_entrance), (width, coor_y_entrance), (255, 0, 0), 2)
    cv2.line(Frame, (0, coor_y_exit), (width, coor_y_exit), (0, 0, 255), 2)

    # check all found count
    for c in cnts:
        # if a contour has small area, it'll be ignored
        if cv2.contourArea(c) < min_area:
            continue

        qtty_of_count = qtty_of_count - 1
        app = FirebaseApplication('https://appproject-d5d51.firebaseio.com/', None)
        update = app.put('/car', "spaces", qtty_of_count)
        print("Updated value in FB value: "   str(update))
        (x, y, w, h) = cv2.boundingRect(c)
        cv2.rectangle(Frame, (x, y), (x   w, y   h), (0, 255, 0), 2)

        # find object's centroid
        coor_x_centroid = (x   x   w) // 2
        coor_y_centroid = (y   y   h) // 2
        ObjectCentroid = (coor_x_centroid, coor_y_centroid)
        cv2.circle(Frame, ObjectCentroid, 1, (0, 0, 0), 5)

        if (check_entrance_line_crossing(coor_y_centroid, coor_y_entrance, coor_y_exit)):
            EntranceCounter  = 1

        if (check_exit_line_crossing(coor_y_centroid, coor_y_entrance, coor_y_exit)):
            ExitCounter  = 1

print("Total countours found: "   str(qtty_of_count))

# Write entrance and exit counter values on frame and shows it
cv2.putText(Frame, "Entrances: {}".format(str(EntranceCounter)), (10, 50),
            cv2.FONT_HERSHEY_SIMPLEX, 0.5, (250, 0, 1), 2)
cv2.putText(Frame, "Exits: {}".format(str(ExitCounter)), (10, 70),
            cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
cv2.imshow("Original Frame", Frame)
cv2.waitKey(1)

# cleanup the camera and close any open windows
camera.release()
cv2.destroyAllWindows()
  

Мне нужно qtty_of_count уменьшаться на единицу при каждом обнаружении объекта. Спасибо.

Комментарии:

1. qtty_of_count = qtty_of_count - 1 действительно ли это допустимый способ уменьшения qtty_of_count на единицу. Что заставляет вас думать, что оно не уменьшается?

2. В имеющемся у меня коде оно уменьшается, только если камера получает более одного объекта, поэтому, если один распознан, он становится 99, но если другой проходит мимо, он остается на 99? Затем, если два хода, оно уменьшается до 98. У меня полностью неправильный код? У меня очень мало опыта работы с Python.

3. Я не знаком с библиотеками компьютерного зрения, поэтому я не совсем понимаю логику вашей программы… Но вот мое случайное предположение: попробуйте перейти qtty_of_count =100 к строке чуть выше while True: .

4. Хорошо, что сработало, теперь оно уменьшается по одному за раз, но теперь вместо уменьшения по мере обнаружения объекта, как только он появляется, он просто постоянно отсчитывает. от 100-0

Ответ №1:

Помимо проблемы, указанной @Kevin, ваш код выполняет оценку изображения для каждого захваченного вами кадра. Если ваш объект остается там в течение 100 кадров, ваш счет будет равен нулю.

Чтобы преодолеть это, вы должны пометить каждый объект на изображении и просто посчитать новые объекты. Это можно было бы сделать несколькими способами (см. Отслеживание фильтра Калмана), но при отсутствии ситуации с закрытием одним простым решением может быть сохранение положения объекта по x, y и установление максимального отклонения положения, чтобы сохранить метку для этого объекта.

Комментарии:

1. В настоящее время я запускаю программу на PyCharm, а веб-камера моего ноутбука работает как камера, я не получаю никакой визуальной обратной связи от считываемого изображения, поэтому я не уверен, как помечать распознанные объекты и т.д. Есть ли более простой способ сделать это? Мне не нужен прямой эфир, просто объект, который нужно распознать. Логика, лежащая в основе этого, заключается в том, что программа предполагает, что движение — это автомобиль, поскольку проект является лишь подтверждением концепции? Спасибо.

2. Итак, когда вы идентифицируете объект в первый раз: возьмите x, y позицию объекта, дайте ему имя, сохраните его (например, в словаре python). В следующих кадрах, когда вы снова его идентифицируете: проверьте, сохранена ли позиция x, y, и просто посчитайте, если нет.

3. Есть ли способ обойти сохранение? При любом обнаруженном движении я делаю предположение, что это значение, которое мне нужно подсчитать. Код работает в минуту, считая один объект, но иногда код постоянно удаляет его, когда на самом деле ничего не движется. Как я уже сказал, это доказательство концепции того, как это ДОЛЖНО работать, если выполнять с более длительным периодом времени и расширенными знаниями в Python. Моя ошибка в значительной степени исправлена. Мне просто интересно, не упустил ли я чего-то, что может позволить коду работать более эффективно.

4. В этом случае вам необходимо обновить свой ReferenceFrame. Ваш код идентифицирует один и тот же объект при каждом взаимодействии. Когда вы идентифицируете объект, обновите свой ReferenceFrame. Но я бы начал работать с другими методами вычитания фона из того же пакета opencv. Многие из них уже выполняют автоматическое обновление ReferencFrame ( docs.opencv.org/3.4/d7/df6/classcv_1_1BackgroundSubtractor.html )