python - 如何量化 cartToPolar 输出以估计连续帧之间的流量 Python OpenCV?

标签 python image opencv image-processing computer-vision

如何量化 cartToPolar 的输出来估计连续帧之间的流量?

为了简单起见,这里输出两帧

import cv2

img_1 = cv2.imread('0.png')
img_2 = cv2.imread('1.png')

frame_1 = cv2.cvtColor(img_1, cv2.COLOR_BGR2GRAY)
frame_2 = cv2.cvtColor(img_2, cv2.COLOR_BGR2GRAY)

flow = cv2.calcOpticalFlowFarneback(frame_1, frame_2, None, 0.5, 3, 21, 3, 7, 1.2, 0)

magnitude, angle = cv2.cartToPolar(flow[..., 0], flow[..., 1])

print(magnitude)

[[0.0001812  0.00021884 0.00027348 ... 0.00620058 0.0056933  0.00466164]
 [0.00022236 0.00027613 0.00034918 ... 0.00769999 0.0070625  0.00579038]
 [0.00027409 0.00034347 0.00043545 ... 0.00825442 0.00754972 0.00617364]
 ...
 [0.02791223 0.03603577 0.04387245 ... 0.00049675 0.00026466 0.00018964]
 [0.01995636 0.02411344 0.0282621  ... 0.00040552 0.00023594 0.00017011]
 [0.01731196 0.02069538 0.0240274  ... 0.00033382 0.00022241 0.00016816]]

根据文档

magnitude – output array of magnitudes of the same size and type as x.

如何量化此输出,以便估计连续帧之间的流量?

最佳答案

我有一个从 .bsq 帧获取像素幅度转换的示例。您可以修改代码以输入视频文件。您可能对 get_translation() 函数最感兴趣。示例:

enter image description here

显示帧与帧之间像素转换的图表

enter image description here

代码

import numpy as np
import argparse
import os
import cv2
from matplotlib import pyplot as plt
from matplotlib import cm
import time
import random

# Usage: python translate_analyzer.py -p <filename.bsq>

# Automatic brightness and contrast optimization with optional histogram clipping
def automatic_brightness_and_contrast(image, clip_hist_percent=25):
    if len(image.shape) == 3:
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    else:
        gray = image

    # Calculate grayscale histogram
    hist = cv2.calcHist([gray],[0],None,[256],[0,256])
    hist_size = len(hist)

    # Calculate cumulative distribution from the histogram
    accumulator = []
    accumulator.append(float(hist[0]))
    for index in range(1, hist_size):
        accumulator.append(accumulator[index -1] + float(hist[index]))

    # Locate points to clip
    maximum = accumulator[-1]
    clip_hist_percent *= (maximum/100.0)
    clip_hist_percent /= 2.0

    # Locate left cut
    minimum_gray = 0
    while accumulator[minimum_gray] < clip_hist_percent:
        minimum_gray += 1

    # Locate right cut
    maximum_gray = hist_size -1
    while accumulator[maximum_gray] >= (maximum - clip_hist_percent):
        maximum_gray -= 1

    # Calculate alpha and beta values
    alpha = 255 / (maximum_gray - minimum_gray)
    beta = -minimum_gray * alpha

    auto_result = cv2.convertScaleAbs(image, alpha=alpha, beta=beta)
    return (auto_result, alpha, beta)

# Draw flow
def draw_flow(img, flow, step=30):
    h, w = img.shape[:2]
    y, x = np.mgrid[step/2:h:step, step/2:w:step].reshape(2,-1).astype(int)
    fx, fy = flow[y,x].T
    lines = np.vstack([x, y, x+fx, y+fy]).T.reshape(-1, 2, 2)
    lines = np.int32(lines + 0.5)
    vis = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
    cv2.polylines(vis, lines, 1, (36, 255, 12))
    for (x1, y1), (_x2, _y2) in lines:
        cv2.circle(vis, (x1, y1), 2, (36, 255, 12), -1)
    return vis

# Return translation value
def get_translation(img, flow, step=30):
    return (np.median(flow[:,:,0].T), flow[:, :, 0].T)

# Get file path
ap = argparse.ArgumentParser()
ap.add_argument("-p", "--path", help="Path to the directory")
args = vars(ap.parse_args())

if not args['path']:
    print('Usage: python translate_analyzer.py -p <directory>')
    exit(1)

# Extract file name
bsq_fname = os.path.split(args['path'])[-1]

if '.bsq' not in bsq_fname:
    print('ERROR: Invalid bsq file. Select correct file.')
    exit(1)

width = 640
height = 512
frame_count = int(os.path.getsize(bsq_fname)/(2*height*width))
x,y,w,h = 0,0,100,512

# Simulates calibrated frames to display on video frame
data_file = np.fromfile(bsq_fname, dtype=np.uint16, count=-1)
data_file = data_file.reshape((width, height, frame_count), order='F')
data_file = np.rot90(data_file)

print(bsq_fname)
fname = bsq_fname.split()[0]
prev = data_file[:,:,0].copy()
prev //= 64
prev = automatic_brightness_and_contrast(prev)[0]
prev = prev[y:y+h, x:x+w]

translation_data = []
frame_direction = []
start = time.time()
for index in range(1, frame_count):
    data = data_file[:,:,index].copy()
    data //= 64
    data = automatic_brightness_and_contrast(data)[0]
    data = data[y:y+h, x:x+w]

    flow = cv2.calcOpticalFlowFarneback(prev=prev, next=data, flow=None, pyr_scale=0.5, levels=2, winsize=80, iterations=2, poly_n=7, poly_sigma=4.5, flags=0)
    translation, pixel_direction = get_translation(data, flow)
    prev = data

    cv2.imshow('flow', draw_flow(data, flow))
    cv2.waitKey(1)

    translation_data.append(translation)
    frame_direction = pixel_direction

    index = (index+1) % frame_count

end = time.time()
print('Time:', end - start)

plt.figure()
plt.title(bsq_fname)
plt.xlabel("Frames")
plt.ylabel("Magnitude")
plt.plot(translation_data)

plt.figure()
plt.title("Pixel Direction")
plt.xlabel("Width")
plt.ylabel("Height")
plt.imshow(frame_direction.T)
plt.colorbar(orientation='vertical')
plt.show()

关于python - 如何量化 cartToPolar 输出以估计连续帧之间的流量 Python OpenCV?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60745576/

相关文章:

python - 这是 Python 的引用传递行为吗?

Python 在 Selenium Web 浏览器中选择最后一个下拉选项

wpf - 如何在 WPF 的 ListView 中有图像和按钮列

python - 使用 PIL `Image.fromarray` 创建图像会导致 AttributeError : 'list' object has no attribute '__array_interface__'

c# - 从列表中删除图像 C#

python - 属性错误 : module 'torch' has no attribute 'rfft' with PyTorch

java - FrameGrabber 空指针异常

android - 为什么在 Android 上,OpenCV 摄像头在捕获视频时比 Android 摄像头更快

python - 使用 Python 的只读二进制平面文件存储选项

python - 修改具有日期偏移量的数据框