Размышляя над прикладной задачей «как прочитать мерцающую строку с номером электробуса» с помощью обычной камеры можно прийти к совершенно неожиданным результатам. Например, получить футуристические снимки окружающего ландшафта и вещей. Решение данной задачи с помощью python, а также несколько инопланетных изображений далее в статье.


Короткий ролик демонстрирует, как выглядит номер электробуса при съемке с помощью камеры raspberry pi:


ссылка на rutube

Заметно, что присутствует мерцание. Данный эффект не позволяет сделать качественный снимок, на котором будет присутствовать номер транспортного средства.
На снимке будет либо видна часть номера, либо он вовсе будет отсутствовать. Как повезет.

Как прочитать номер для дальнейшего распознавания?
Первое, что приходит на ум — это попытаться рассинхронизировать камеру с частотой обновления изображения на номерном знаке электробуса. Но что, если эта частота у каждого транспортного средства своя. Да и как это сделать на примере с picamera (предполагается использование одноплатника raspberry pi)?

Оказывается, есть еще один вариант решения задачи. Данный подход, как выяснилось, активно используется в астрономии при «фотографировании» звезд. Чтобы изображение звезды получилось качественнее, в некоторых случаях производится «сложение» снимков.

Продемонстрируем данный эффект на базе raspberry pi и python:

import time
import picamera
import cv2,os
import numpy as np
import glob
from datetime import datetime

frames = 3

def filenames():
    frame = 0
    while frame < frames:
        yield 'photos/image%02d.jpg' % frame
        frame += 1

with picamera.PiCamera(resolution='720p', framerate=30) as camera:
    camera.start_preview(fullscreen=False, window = (100, 20, 640, 480))
    #camera.vflip = True
    camera.rotation = 270
    # Give the camera some warm-up time
    time.sleep(2)
    start = time.time()
    camera.capture_sequence(filenames(), use_video_port=True)
    finish = time.time()
print('Captured %d frames at %.2ffps' % (
    frames,
    frames / (finish - start)))

os.chdir('photos/')

files=[]
for file in glob.glob('*.jpg'):
        #print(file)        
        files.append(file)

x=0

def glue(img1,img2):    
    return cv2.addWeighted(img1, 0.5, img2, 0.5, 0)

for f in range(len(files)-1):
    img1 = cv2.imread(files[x])
    img2 = cv2.imread(files[x+1])
    dst = glue(img1,img2)
    dst+=dst          
    x+=1

cv2.imwrite(f'{str(datetime.now()).split(" ")[1]}.png',dst)
#cv2.imshow('Blended Image',dst)  
#cv2.waitKey(0)
#cv2.destroyAllWindows()

for file in glob.glob('image*.jpg'):
        os.remove(file)       


Как несложно догадаться, основная «магия» происходит в функции glue, объединяющей снимки в нечто новое.


С помощью такого нехитрого подхода можно получать совершенно необычные снимки:


Но и в том числе решить прикладную задачу:


p.s. Возможно, классические методы cv не будут открытием для кого-то. Однако, об их (методах) существовании порой забываешь и начинаешь закапываться в дебри реализации.

Комментарии (4)


  1. engine9
    18.09.2024 09:38
    +3

    Похожая техника, очень необычный результат.


  1. xpbim3_xpbim3
    18.09.2024 09:38
    +2

    Странно что цветовые каналы выщелкнуло в переполнение.

    Вообще говоря cv тут нафик не нужна, это и в контексте numpy отлично сработает:

    result = (img1*0.5 + img2*0.5)

    result_clipped = np.clip(result, 0, 255).astype(np.uint8)

    Причем я бы кастанул в грейскейл и это сработает даже со стэком n изображений в тензорной форме, например положим что img_stack.shape == (n, 1, y, x) типа np.uint8

    то можно дать:

    result = np.sum(img_stack.astype(int), axis = 0) / n


  1. Zara6502
    18.09.2024 09:38
    +1

    мне кажется можно воспользоваться контролем времени затухания "люминофора" которого нет

    то есть например второй кадр суммируется с первым, у которого понижена яркость например на 25%, третий из 1-2-3 кадров так же -25% и -50%. Таким образом яркие участки будут уходить в белое, а "моргающие" точки в серое.


  1. DimPal
    18.09.2024 09:38

    А если не суммировать, а взять максимум яркости от двух соседних кадров?