Example: 02-Image-Processing/01-Image-Filters/color_correction.py

# 本作品采用MIT许可证授权。
# 版权所有 (c) 2013-2024 OpenMV LLC。保留所有权利。
# https://github.com/openmv/openmv/blob/master/LICENSE
#
# 色彩校正示例
#
# 此示例展示了如何使用色彩校正矩阵乘法
# 方法对图像应用通用矩阵乘法。
#
# 在下面的示例中,我们将:
#     1. Convert the image to YUV from RGB.
#     2. Apply a rotation matrix to the UV components to cause a Hue Shift.
#     3. Apply a scaling value to the UV components to cause a Saturation Shift.
#     4. Convert the image back from YUV to RGB.
#
# 然而,我们不必依次对图像应用这4个步骤,而是可以
# 预先将它们相互结合,生成一个适合输入到
# 色彩校正矩阵方法的3x3矩阵。
#
# 通过转换色彩空间至YUV,可将像素"值"从
# their "hue" and "saturation". The "hue" then is just the rotation angle given
# the U/V components and the "saturation" is their magnitude.
#
# |Y|   |    0.299,     0.587,     0.114|   |R|
# |U| = |-0.168736, -0.331264,       0.5| * |G|
# |V|   |      0.5, -0.418688, -0.081312|   |B|
#
# |Y_rot|   |1,           0,            0|   |Y|
# |U_rot| = |0, math.cos(a), -math.sin(a)| * |U|
# |V_rot|   |0, math.sin(a),  math.cos(a)|   |V|
#
# |Y_rot_scaled|   |1, 0,  0|   |Y|
# |U_rot_scaled| = |0, s,  0| * |U|
# |V_rot_scaled|   |0, 0,  s|   |V|
#
# |R_rot_scaled|          |    0.299,     0.587,     0.114|   |Y_rot_scaled|
# |R_rot_scaled| = 逆矩阵|-0.168736, -0.331264,       0.5| * |U_rot_scaled|
# |R_rot_scaled|          |      0.5, -0.418688, -0.081312|   |V_rot_scaled|
#
# 注意:ccm()方法可以接受3x3和3x4矩阵。3x4矩阵用于
# 需要应用偏移量的情况。此时公式如下:
#
# |Y|   |    0.299,     0.587,     0.114,  y_offset|   |R|
# |U| = |-0.168736, -0.331264,       0.5,  u_offset| * |G|
# |V|   |      0.5, -0.418688, -0.081312,  v_offset|   |B|
#                                                      |1|
#
# 请记住,CCM方法只是执行以下操作:
#
# |R'|                |R|      |R'|                |R|
# |G'| = 3x3 矩阵 * |G|  或  |G'| = 3x4 矩阵 * |G|
# |B'|                |B|      |B'|                |B|
#                                                  |1|
#
# If you are creating intermediate values using matrix math you need to end
# up back at RGB values for the final matrix you pass to CCM().
#
# Finally, you are free to do the matrix formation using 4x4 matrices. The last
# row will be ignored if you pass a 4x4 matrix (e.g. it will be treated as 3x4).

from ulab import numpy as np
import sensor
import time
import math

# Set to 0 for a grayscale image. Set above 1.0 to pump-up the saturation.
UV_SCALE = 1.0

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time=2000)

# These are the standard coefficents for converting RGB to YUV.
rgb2yuv = np.array([[    0.299,     0.587,     0.114], # noqa
                    [-0.168736, -0.331264,       0.5], # noqa
                    [      0.5, -0.418688, -0.081312]], dtype=np.float) # noqa

# Now get the inverse so we can get back to RGB from YUV.
yuv2rgb = np.linalg.inv(rgb2yuv)

clock = time.clock()

# r will be the angle by which we rotate the colors on the UV plane by.
r = 0

while True:
    clock.tick()

    # Increment in a loop.
    r = (r + 1) % 360
    a = math.radians(r)

    # This is a rotation matrix which we will apply on the UV components of YUV values.
    # https://en.wikipedia.org/wiki/Rotation_matrix
    rot = np.array([[1,           0,            0], # noqa
                    [0, math.cos(a), -math.sin(a)], # noqa
                    [0, math.sin(a),  math.cos(a)]], dtype=np.float) # noqa

    # This is the scale matrix
    scale = np.array([[1,        0, 0], # noqa
                      [0, UV_SCALE, 0], # noqa
                      [0,        0, UV_SCALE]], dtype=np.float) # noqa

    # Now compute the final matrix using matrix multiplication.
    m = np.dot(yuv2rgb, np.dot(scale, np.dot(rot, rgb2yuv)))

    # Apply the color transformation (m.flatten().tolist() also works)
    img = sensor.snapshot().ccm(m.tolist())

    print(clock.fps())

results matching ""

    No results matching ""