0%

YUV、RGB、HSV

YUV:亮度信息 即灰度值。UV:色彩信息 定义了颜色的两个方面-色调与饱和度,分别用Cr和CB来表示。其中,Cr反映了RGB输入信号红色部分与RGB信号亮度值之间的差异。而CB反映的是RGB输入信号蓝色部分与RGB信号亮度值之同的差异。通过运算,YUV三分量可以还原出R(红),G(绿),B(蓝)。

HSV: 色调(H),饱和度(S),明度(V)

相互转换

ARGB -> RGB

1
2
3
4
5
6
7
8
//unsigned char *data 存的是ARGB的裸数据;

cv::Mat argbImg;
cv::Mat rgbImg(cy, cx,CV_8UC3);
yuvImg.create(cy, cx, CV_8UC4);
memcpy(argbImg.data, data, len);
cv::cvtColor(argbImg, rgbImg, CV_RGBA2RGB);
flip(rgbImg, rgbImg, 0); //垂直翻转

YUV -> RGB

1
2
3
4
5
6
7
//unsigned char *data 存的是YUYV的裸数据;

cv::Mat yuvImg;
cv::Mat rgbImg(cy, cx,CV_8UC3);
yuvImg.create(cy , cx, CV_8UC2);
memcpy(yuvImg.data, data, len);
cv::cvtColor(yuvImg, rgbImg, CV_YUV2BGR_YUYV);

I420 -> RGB

1
2
3
4
5
6
7
//unsigned char *data 存的是I420的裸数据;

cv::Mat yuvImg;
cv::Mat rgbImg(cy, cx,CV_8UC3);
yuvImg.create(cy * 3/2, cx, CV_8UC1);
memcpy(yuvImg.data, data, len);
cv::cvtColor(yuvImg, rgbImg, CV_YUV2BGR_I420);

OpenCV提供的转换函数实现YUV到RGB的转换:

1
2
3
4
5
6
7
8
9
bool YV12ToBGR24_OpenCV(unsigned char* pYUV,unsigned char* pBGR24,int width,int height) 
{
if (width < 1 || height < 1 || pYUV == NULL || pBGR24 == NULL)
return false;
Mat dst(height,width,CV_8UC3,pBGR24);
Mat src(height + height/2,width,CV_8UC1,pYUV);
cvtColor(src,dst,CV_YUV2BGR_YV12);
return true;
}

RGB -> HSV

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# -*- coding:utf-8 -*-

import cv2

"""
功能:读取一张图片,显示出来,并转化为HSV色彩空间
"""
image = cv2.imread('images/my_wife2.jpg') # 根据路径读取一张图片
cv2.imshow("BGR", image) # 显示图片


# 转化图片到HSV色彩空间
dst = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
cv2.imshow("HSV", dst) # 显示图片
cv2.waitKey(0) # 等待键盘触发事件,释放窗口

White Balance

概念

相机的白平衡控制,是为了让实际环境中白色的物体在你拍摄的画面中也呈现出“真正”的白色。不同性质的光源会在画面中产生不同的色彩倾向,比如说,蜡烛的光线会使画面偏橘黄色,而黄昏过后的光线则会为景物披上一层蓝色的冷调。而我们的视觉系统会自动对不同的光线作出补偿,所以无论在暖调还是冷调的光线环境下,我们看一张白纸永远还是白色的。但相机则不然,它只会直接记录呈现在它面前的色彩,这就会导致画面色彩偏暖或偏冷。

实现

开暖光灯:YUV -> RGB -> SV ,全图SV值S需在0~0.1之间,V需在90~255之间。

Read more »

TensorFlow2.0简化的模型开发流程

  • 使用tf.data加载数据
  • 使用tf.keras构建模型,也可以使用premade estimator来验证模型(使用tesorflow hub进行迁移学习)
  • 使用eager mode进行运行和调试
  • 使用分发策略来进行分布式训练
  • 导出到SavedModel
  • 使用TesorFlow Serve、TensorFlow Lite、TensorFlow.js部署模型
Read more »

同步,异步,阻塞,非阻塞?

同步: 多个任务之间有先后顺序执行,一个执行完下个才能执行。

异步: 多个任务之间没有先后顺序,可以同时执行,有时候一个任务可能要在必要的时候获取另一个同时执行的任务的结果,这个就叫回调!

阻塞: 如果卡住了调用者,调用者不能继续往下执行,就是说调用者阻塞了。

非阻塞: 如果不会卡住,可以继续执行,就是说非阻塞的。

同步异步相对于多任务而言,阻塞非阻塞相对于代码执行而言。

Read more »

*args 和 **Kwargs

  • *args 是用来发送一个非键值对的可变数量的参数列表给一个函数
  • kwargs 允许你将不定长度的键值对, 作为参数传递给一个函数。 如果你想要在一个函 数里处理带名字的参数, 你应该使用kwargs。
1
2
3
4
def test_args_kwargs(arg1, arg2, arg3):
print("arg1:", arg1)
print("arg2:", arg2)
print("arg3:", arg3)
1
2
3
4
5
6
7
# Test *args
args = ("two", 3, 5)
test_args_kwargs(*args)

arg1: two
arg2: 3
arg3: 5
1
2
3
4
5
6
# Test **kwargs
kwargs = {"arg3": 3, "arg2": "two", "arg1": 5}
test_args_kwargs(**kwargs)
arg1: 5
arg2: two
arg3: 3
Read more »