这篇文章我们先来认识一下DeltaCV中CPU上做的相关优化工作,使用SSE指令集优化RGB转YCrCb颜色空间过程,并进行阈值分割。
OpenCV中的函数
在OpenCV中完成RGB图像在YCrCb空间的阈值分割,需要用到两个函数,cv::cvtColor(颜色空间转换)及cv::inRange(阈值处理).
函数原型
1 |
|
DeltaCV中的优化
函数原型
1 |
|
加载变量
1 |
|
- 刚开始我们进行了阈值的通道检查(因为这个函数输入的数据必须是RGB图像).
- 紧接着,再将高低两个阈值加载进SSE变量中.
- 下面是重点,RGB转ycrcb的公式里面是每个系数都是0-1之间的浮点型,而我们前面取到的像素是以8位无符号整形保存在SSE变量中,所以我们需要将系数左移15位,既保证了精度,又满足了计算要求(没有超过16位,正好两个8位).
计算主体
1 |
|
- 这里我们同样先从输入图像中加载待处理的数据.
- 接着我们将B G R B G R B G R这样的数据拆分成B 0 G 0 B 0 G 0 和R 0 half 0 R 0 half 0这样的形式,为了后面使用
_mm_madd_epi16
将像素与各自的权重相乘再相加. - Y_C_WT, Cr_C_WT, Cb_C_WT这三个变量是干什么?
我们来看一下rgb转ycrcb的公式:[参考Imageshop])(https://www.cnblogs.com/Imageshop/p/8405517.html)
1
2
3Y = (Y_B_WT * Blue + Y_G_WT * Green + Y_R_WT * Red + HalfV) >> Shift; Cr = ((Cr_B_WT * Blue + Cr_G_WT * Green + Cr_R_WT * Red + HalfV) >> Shift) + 128; Cb = ((Cb_B_WT * Blue + Cb_G_WT * Green + Cb_R_WT * Red + HalfV) >> Shift) + 128;
经过变形成为:
1
2
3
4Y = (Y_B_WT * Blue + Y_G_WT * Green + Y_R_WT * Red + 1 * HalfV) >> Shift; Cr = (U_B_WT * Blue + U_G_WT * Green + U_R_WT * Red + 257 * HalfV) >> Shift; Cb = (V_B_WT * Blue + V_G_WT * Green + V_R_WT * Red + 257 * HalfV) >> Shift; 这就是Y_C_WT=1,Cr_C_WT=257,Cb_C_WT=257的由来
- 虽然上面代码量看着较多,但是都是基本运算,而且比OpenCV的函数快了7-8倍.
性能对比
处理1000次取平均值
Image Size: 1024 x 1280(H x W)
opencv函数耗时: 6.68 - 6.75 ms
DeltaCV函数耗时: 0.88 - 0.90 ms
加速比: 7.4 - 7.6