视频编码

YUV信号

RGB信号不利于压缩,所以引入YUV信号。Y表示明亮度(Luminance),也就是灰阶值。U和V表示色度(Chrominance),作用是描述影像色彩及饱和度,用于指定像素的颜色。
在一个YUV图像中,每个像素点占3位(8bit),分别对应YUV3个分量。人眼对亮度信息Y更敏感,因此对色度分量U,V可以采用采样。采样可以减少传输带宽,用 X:X:X 格式表示,其中第一数字表示亮度采样的数目,用作参考,往往设定为“4”,第二和第三个数字表示色度采样的数目,与Y的数目有关。
举例:4:1:1
四个像素为:[Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3]
存放的码流为:Y0 U0 Y1 Y2 V2 Y3
映射出像素点为:[Y0 U0 V2] [Y1 U0 V2] [Y2 U0 V2] [Y3 U0 V2]

熵编码

熵编码即编码过程中按熵原理不丢失任何信息的编码。

光流(Optical Flow)

光流是空间运动物体在观察成像平面上的像素运动的瞬时速度,是利用图像序列中像素在时间域上的变化以及相邻帧之间的相关性来找到上一帧和当前帧之间存在的对应关系,从而计算出相邻帧之间物体的运动信息的一种方法。
说人话:你看到的东西动了

Code(Tested):

#!/usr/bin/python

import numpy as np
import cv2

# opencv-3.1.0/samples/data/768x576.avi
cap = cv2.VideoCapture('768x576.avi')

# params for ShiTomasi corner detection
feature_params = dict( maxCorners = 100,
                       qualityLevel = 0.3,
                       minDistance = 7,
                       blockSize = 7 )

# Parameters for lucas kanade optical flow
lk_params = dict( winSize  = (15,15),
                  maxLevel = 2,
                  criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))

# Create some random colors
color = np.random.randint(0,255,(100,3))

# Take first frame and find corners in it
ret, old_frame = cap.read()
old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY)
p0 = cv2.goodFeaturesToTrack(old_gray, mask = None, **feature_params)

# Create a mask image for drawing purposes
mask = np.zeros_like(old_frame)

while(1):
    ret,frame = cap.read()
    if ret is True:
        print(ret)
        frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        # calculate optical flow
        p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)

        # Select good points
        good_new = p1[st==1]
        good_old = p0[st==1]

        # draw the tracks
        for i,(new,old) in enumerate(zip(good_new,good_old)):
            a,b = new.ravel()
            c,d = old.ravel()
            mask = cv2.line(mask, (a,b),(c,d), color[i].tolist(), 2)
            frame = cv2.circle(frame,(a,b),5,color[i].tolist(),-1)
        img = cv2.add(frame,mask)

        cv2.imshow('frame',img)
        k = cv2.waitKey(30) & 0xff
        if k == 27:
            break

        # Now update the previous frame and previous points
        old_gray = frame_gray.copy()
        p0 = good_new.reshape(-1,1,2)
    else:
        break

cv2.destroyAllWindows()
cap.release()

峰值信噪比(Peak Signal to Noise Ratio, PSNR)

\[MSE=\frac{1}{H \times W}\sum_{i=1}^{H}\sum_{j=1}^{W}(X(i,j)-Y(i,j))^2 \\ PSNR=10log_{10}(\frac{(2^n-1)^2}{MSE}) \]

当前图像\(X\),参考图像\(Y\)\(n\)为每像素的比特数,一般取8,PSNR单位为dB,越大表示图像失真越小。

结构相似度(Structural Similarity, SSIM)

from paper: Image Quality Assessment: From Error Visibility to Structural Similarity

图像\(x,y\)的相似度按三个维度进行比较:

  1. 亮度(luminance) \(l(x,y)\)
    图像的平均亮度为:

\[\mu_x=\frac{1}{N}\sum_{i=1}^{N}x_i \]

衡量\(x\)\(y\)的亮度相似度:

\[l(x,y)=\frac{2\mu_x \mu_y+C_1}{\mu_x^2+\mu_y^2+C_1} \\ C_1=(K_1 L)^2 \]

\(K_1 \ll 1(K_1=0.01\) in code\()\), L是灰度的动态范围\((L=255)\)

  1. 对比度(contrast) \(c(x,y)\)
    图像的对比度(像素值的标准差)为:

\[\sigma_x=(\frac{1}{N-1}\sum_{i=1}^{N}(x_i-\mu_x)^2)^{1/2} \]

衡量\(x\)\(y\)的对比度相似度:

\[c(x,y)=\frac{2\sigma_x \sigma_y+C_2}{\sigma_x^2+\sigma_y^2+C_2} \\ C_2=(K_2 L)^2 \]

\(K_2=0.03\)

  1. 结构(structure) \(s(x,y)\)
    研究结构相似度时应排除亮度(均值)和对比度(标准差)的影响: 研究\(\frac{x-\mu_x}{\sigma_x}\)\(\frac{y-\mu_y}{\sigma_y}\)之间的关系,由于模长均为\(\sqrt{N-1}\)
    因此余弦相似度为:

\[s(x,y)=(\frac{1}{\sqrt{N-1}}\frac{x-\mu_x}{\sigma_x})(\frac{1}{\sqrt{N-1}}\frac{y-\mu_y}{\sigma_y}) \\ =\frac{1}{\sigma_x \sigma_y}(\frac{1}{N-1}\sum_{i=1}^{N}(x_i-\mu_x)(y_i-\mu_y)) \]

第二行括号即为协方差公式:

\[\sigma_{xy}=\frac{1}{\sigma_x \sigma_y}(\frac{1}{N-1}\sum_{i=1}^{N}(x_i-\mu_x)(y_i-\mu_y)) \]

为了防止分子为\(0\),分子分母同时加\(C_3\):

\[s(x,y)=\frac{\sigma_{xy}+C_3}{\sigma_x \sigma_y + C_3} \]

\(C_3=C_2/2\)

最终相似度公式为:

\[SSIM(x,y)=l(x,y)c(x,y)s(x,y) \\ =\frac{(2\mu_x \mu_y+C_1)(2\sigma_{xy}+C_2)}{(\mu_x^2+\mu_y^2+C_1)(\sigma_x^2+\sigma_y^2+C_2)} \]

posted @ 2020-06-22 16:40  timec  阅读(63)  评论(0)    收藏  举报