изменение изображений для получения четких, нешумных функций для оптической стабилизации потока / изображения - PullRequest
2 голосов
/ 07 марта 2019

Я пытаюсь разработать конвейер для стабилизации изображений эксперимента с использованием opencv в Python. Вот пример необработанного изображения (фактический размер: 1920x1460)

Этот конвейер должен иметь возможность стабилизировать как низкочастотный дрейф, так и высокочастотный «джиттер», который иногда возникает при открытии клапанов/ закрыто во время эксперимента.Мой текущий подход, , следуя приведенному здесь примеру , заключается в применении двустороннего фильтра с последующей адаптивной настройкой порога для выделения каналов в изображении.Затем я использую goodFeaturesToTrack, чтобы найти углы в пороговом изображении.Однако в изображении присутствует значительный уровень шума из-за низкой контрастности некоторых оптических эффектов в углах изображения.Хотя я могу найти углы канала, , как показано здесь , они перемещаются совсем немного от кадра к кадру, видно здесь .Я отследил величину сдвига пикселей x и y в каждом кадре относительно первого кадра, рассчитанного из calcOpticalFlowPyrLK, и вычислил жесткое преобразование с использованием оценкиRigidTransform , показанного здесь .На этом графике я вижу низкочастотный дрейф от кадров 0: 200 и резкий скачок вокруг кадра ~ 225.Эти прыжки соответствуют тому, что наблюдается на видео.Однако существенный шум (с амплитудой ~ 5-10 пикселей) не соответствует тому, что наблюдается в видео.Если я применяю эти преобразования к моему стеку изображений, вместо этого я получаю увеличенный джиттер, который не стабилизирует изображение.Более того, если я попытаюсь вычислить преобразование для одного кадра в следующий (а не для всех кадров в первый), после обработки нескольких кадров я получу None возврат для жесткой матрицы преобразования, возможно, потому, что шум предотвращаетжесткое преобразование из расчета.

Вот пример того, как я вычисляю преобразование:

# Load required libraries
import numpy as np
from skimage.external import tifffile as tif
import os
import cv2
import matplotlib.pyplot as plt
from sklearn.externals._pilutil import bytescale

#Read in file and convert to 8-bit so it can be processed
os.chdir(r"C:\Path\to\my\processingfolder\inputstack")
inputfilename = "mytestfile.tif"
input_image = tif.imread(inputfilename)
input_image_8 = bytescale(input_image)
n_frames, vid_height, vid_width = np.shape(input_image_8)


transforms = np.zeros((n_frames-1,3),np.float32)
prev_image = starting_image
prev_f = cv2.bilateralFilter(prev_image,9,75,75)
prev_t = cv2.adaptiveThreshold(prev_f,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,49,2)
prev_pts = cv2.goodFeaturesToTrack(prev_t,maxCorners=100,qualityLevel=0.5,minDistance=10,blockSize=25,mask=None)

for i in range(1,n_frames-2):

    curr_image = input_image_8[i]
    curr_f = cv2.bilateralFilter(curr_image,9,75,75)
    curr_t = cv2.adaptiveThreshold(curr_f,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,49,2)

    #Detect features through optical flow:
    curr_pts, status, err = cv2.calcOpticalFlowPyrLK(prev_t,curr_t,prev_pts,None)

    #Sanity check 
    assert len(prev_pts) == len(curr_pts)
    #Filter to only the valid points
    idx = np.where(status==1)[0]
    prev_pts = prev_pts[idx]
    curr_pts = curr_pts[idx]

    #Find transformation matrix
    m = cv2.estimateRigidTransform(prev_pts,curr_pts, fullAffine=False) #will only work with OpenCV-3 or less

    # Extract translation
    dx = m[0,2]
    dy = m[1,2]

    # Extract rotation angle
    da = np.arctan2(m[1,0], m[0,0])

    # Store transformation
    transforms[i] = [dx,dy,da]

    print("Frame: " + str(i) +  "/" + str(n_frames) + " -  Tracked points : " + str(len(prev_pts)))

Как я могу обрабатывать свои изображения по-другому, так что я выбираю линии этих каналовбез шума в обнаружении углов?Эта стабилизация / выравнивание не должна происходить на лету, она может быть применена ко всему стеку после факта.

...