Вопрос или проблема
Я получаю значения uint16 (RGB565) из последовательного порта. Массив содержит 76800 значений uint16 из изображения 320×240. Прямо сейчас я просто отправляю тестовое изображение с полосой, и получаю это изображение:
которое, похоже, генерируется несколько раз с помощью скрипта python, который выглядит так:
def TakePicture():
xdim = 320
ydim = 240
i=0
RGB_list.pop(0)
im = Image.new("RGB",(xdim,ydim))
for k in range(76800):
value1=int(RGB_list[k])
RGB_values.append(value1)
for y in range(ydim):
for x in range(xdim):
px = RGB_values[i]
i = i+1
im.putpixel((x,y),((px&0xF800) >> 8, (px&0x07E0) >> 3, (px&0x001F) << 3))
im.save('image.png')
im.show()
def main():
try:
serialPort=serial.Serial(port="/dev/ttyUSB1", baudrate=115200,bytesize=8,parity=serial.PARITY_NONE,stopbits=1,timeout=0)
except:
print("невозможно открыть порт")
while(1):
if(serialPort.in_waiting>0):
incoming=serialPort.readline().decode('ascii','ignore')
incoming=incoming.rstrip()
if('ET' not in incoming):
if(not incoming):
incoming='0'
print(incoming)
RGB_list.append(incoming)
else:
with open('serial_python.txt','w',newline="",encoding='utf-8') as txtfile:
writer=csv.writer(txtfile)
for i in RGB_list:
writer.writerow([i])
TakePicture()
Я использую PIL, чтобы взять каждое значение из массива и сгенерировать пиксель, но почему это не работает? Я получаю эти значения через последовательный порт и преобразую эти значения в целые числа, заполняя другой массив, чтобы впоследствии сгенерировать каждый пиксель.
Сначала я думал, что это связано с кодировкой, но потом понял, что, похоже, это связано с тем, как генерируется изображение. Я нашел что-то по этому поводу на форуме, и многие использовали np массивы.
Ответ или решение
Для решения вашей проблемы отображения изображения, получаемого из массива uint16 через последовательный порт, важно внимательно рассмотреть вашу текущую реализацию и выделить возможные проблемы. Давайте рассмотрим шаги, необходимые для правильного извлечения RGB значений из формата RGB565 и построения изображения.
Проблема и её решение
Ваш массив имеет размеры 320×240 пикселей, что означает, что он содержит 76800 значений uint16. Каждый элемент массива представляет собой цвет пикселя в формате RGB565, который использует 16 бит для кодирования цвета: 5 бит для красного, 6 бит для зелёного и 5 бит для синего.
Ваша текущая реализация в функции TakePicture()
производит преобразование некорректно. Давайте разберёмся, как это исправить.
Поправка кода
Ваш исходный код использует метод putpixel
из библиотеки Pillow, однако сам алгоритм преобразования из RGB565 в RGB888 имеет некоторые проблемы. Давайте внесем изменения для корректного преобразования значений.
from PIL import Image
import serial
import csv
RGB_list = [] # Список для хранения значений из последовательного порта
def TakePicture():
xdim = 320
ydim = 240
im = Image.new("RGB", (xdim, ydim))
i = 0
for y in range(ydim):
for x in range(xdim):
# Чтение значения из RGB_list и преобразование
px = int(RGB_list[i])
i += 1
# Преобразование RGB565 в RGB888
r = (px & 0xF800) >> 8
g = (px & 0x07E0) >> 3
b = (px & 0x001F) << 3
# Убедимся, что значения RGB находятся в диапазоне [0, 255]
im.putpixel((x, y), (r, g, b))
im.save('image.png')
im.show()
def main():
try:
serialPort = serial.Serial(port="/dev/ttyUSB1", baudrate=115200, bytesize=8, parity=serial.PARITY_NONE, stopbits=1, timeout=0)
except Exception as e:
print("Не удалось открыть порт:", e)
while True:
if serialPort.in_waiting > 0:
incoming = serialPort.readline().decode('ascii', 'ignore').rstrip()
if 'ET' not in incoming and incoming:
RGB_list.append(incoming)
elif 'ET' in incoming:
# Запись в файл
with open('serial_python.txt', 'w', newline="", encoding='utf-8') as txtfile:
writer = csv.writer(txtfile)
for i in RGB_list:
writer.writerow([i])
TakePicture() # Генерация изображения
if __name__ == "__main__":
main()
Объяснение изменений
-
Преобразование из RGB565 в RGB888: Ваша первоначальная логика, применяемая для формирования RGB-пикселей, использовала неверные операции и битовые сдвиги. Я уточнил данный процесс, чтобы он соответствовал стандартному алгоритму преобразования RGB565 в RGB888.
-
Проверка значений пикселей: Важно убедиться, что значения RGB находятся в диапазоне от 0 до 255. Ваши значения r, g и b должны быть корректно обработаны, чтобы избежать цветовых искажений.
-
Упрощение логики: Код был оптимизирован для повышения читаемости и устранения лишних операций, что улучшит производительность.
Заключение
Использование данного обновления улучшит качество генерируемого изображения. Убедитесь, что в процессе передачи данных по последовательному порту корректно обрабатываются любые потенциальные ошибки и что данные поступают в ожидаемом формате.
Если после этих изменений изображение по-прежнему отображается некорректно, рекомендуется проверить исходные данные, передаваемые через последовательный порт, на наличие возможных ошибок.