Как я могу управлять общей памятью в пользовательском типе данных кольцевого буфера?Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Как я могу управлять общей памятью в пользовательском типе данных кольцевого буфера?

Сообщение Anonymous »

Я пишу программу для следующей задачи
Задача состоит в том, чтобы написать программу, которая создает два процесса:
a) ' Процесс производителя считывает изображение видеокадра непосредственно в кольцевой буфер общей памяти (т. е. буфер общей памяти, который может вместить N изображений кадров для настраиваемого N - это можно сохранить как параметр командной строки).
б) Потребительский процесс считывает изображения кадров из кольцевой буфер отображает каждый кадр в течение настраиваемого промежутка времени (например, 500 мс - а также параметр командной строки программы)
c) Производитель и потребитель должны синхронизироваться, чтобы
i) Потребитель отображает изображение только после того, как оно было полностью создано (т. е. весь кадр был сгенерирован)
ii) Потребитель ждет производителя если следующее изображение, которое будет использовано, еще не было полностью создано.\
iii) Производитель ожидает потребителя, в кольцевом буфере нет места для создания следующего изображения (т. е. потребитель не полностью израсходовал ни одно из изображений). текущие изображения в кольцевом буфере)
ниже мой код:

Код: Выделить всё

from multiprocessing import Process, Lock, Value
from multiprocessing.shared_memory import SharedMemory

import sys
import numpy as np
import cv2
import time

class RingBufferFullException(Exception):
pass

class RingBufferEmptyException(Exception):
pass

class RingBuffer:

def __init__(self, max_size, single_frame):
self.max_size = Value('i', max_size)
self.shm = SharedMemory(create=True, size=max_size*single_frame.nbytes)
self.queue = np.ndarray(shape=(max_size, *single_frame.shape), dtype=single_frame.dtype, buffer=self.shm.buf)
self.tail = Value('i', -1)
self.head = Value('i', 0)
self.size = Value('i', 0)
self.lock = Lock()

def enqueue(self, item):
with self.lock:
if self.size.value == self.max_size.value:
raise RingBufferFullException('Error: Queue is full')

else:
self.tail.value = (self.tail.value + 1) % self.max_size.value
self.queue[self.tail.value] = item
self.size.value += 1

def dequeue(self):
with self.lock:
if self.size.value == 0:
raise RingBufferEmptyException('Error: Queue is empty')

tmp = self.queue[self.head.value]
self.head.value = (self.head.value + 1) % self.max_size.value
self.size.value -= 1

return tmp

def isFull(self):
return self.size.value == self.max_size.value

def isEmpty(self):
return self.size.value == 0

def display(self):
if self.size.value == 0:
print('Queue is empty')

else:
idx = self.head.value
print('---------------------------------------')
for i in range(self.size.value):
print(self.queue[idx])
idx = (idx + 1) % self.max_size.value
print('---------------------------------------')

def clean(self):
self.shm.close()
self.shm.unlink()

def producer(buf):
cap = cv2.VideoCapture(0)
print(cap.isOpened())

while True:
buf.display()
success, frame = cap.read()

if not success:
print('Failed to capture frame')
continue

try:
buf.enqueue(frame)

except RingBufferFullException:
time.sleep(0.5)

def consumer(buf):
while True:
try:
frame = buf.dequeue()
cv2.imshow('Frame', frame)
cv2.waitKey(100)

except RingBufferEmptyException:
time.sleep(0.2)

cv2.destroyAllWindows()

if __name__ == '__main__':
test = cv2.VideoCapture(0)
if not test.isOpened():
print('Error: Could not open camera.')
sys.exit(1)

success, single_frame = test.read()
if not success:
print('Error: Could not capture initial frame.')
sys.exit(1)

test.release()
buf = RingBuffer(10, single_frame)
test.release()

produce = Process(target=producer, args=(buf,))
consume = Process(target=consumer, args=(buf,))

try:
produce.start()
consume.start()

produce.join()
consume.join()

finally:
buf.clean()

Сначала я подумал, что можно сделать сам экземпляр кольцевого буфера общей памятью. Я искал в сети и ничего не нашел. ChatGPT заявил, что создание сложного пользовательского объекта в общей памяти невозможно в Python. А потом я подумал, что могу поместить экземпляр в общую память, и ChatGPT сказал, что это тоже невозможно.
Затем я сделал метаданные кольцевого буфера общей памятью. теперь он отлично ставит и удаляет кадры из очереди, но показывает только черные изображения.
Основная проблема заключается в том, что окно cv2 показывает только черный цвет. Все изображения черные. когда я печатаю кадр, выведенный из очереди, это просто матрица со всеми нулями. Если я печатаю буфер внутри функции производителя или функции потребителя, он печатает матрицу np с разными значениями. Но в окне cv2 просто черные изображения.
Что я делаю не так? Любая помощь приветствуется. Ребята, заранее спасибо.

Подробнее здесь: https://stackoverflow.com/questions/793 ... -data-type
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»