OpenCV Decolorization

使用了很久OpenCV和Matlab中的图像灰度化操作,因为是非常基础的操作又很常见,也就没怎么思考过,直到这些灰度化遇到了一些问题:

Original Image Color2Gray
25_color 25_color
IM2-color IM2-color

OpenCV和Matlab中灰度化的方法都非常简单:

$ Y = 0.2989 \times R + 0.5870 \times G + 0.1140 \times B$

很明显,这种线性灰度化方法用于解决这一非线性问题,有些时候会导致图像对比度严重损失。

看到OpenCV3.x中集成了新的灰度化方法decolor

1
void decolor(InputArray src, OutputArray grayscale, OutputArray color_boost)

用法很简单:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
Mat src = imread("test.png");
Mat grayScale, color_boost;
decolor(src, grayScale, color_boost);
imshow("test", grayScale);
waitKey(0);
return 0;
}
25_color IM2-color

差异立竿见影!

找到原论文:Contrast Preserving Decolorization, ICCP 2012,方法也很简单,相比于简单的使用R/G/B线性组合,作者构造了更为复杂的多项式拟合,向量空间的基底为:$[r,g,b,rg,rb,gb,r^2,g^2,b^2]$,核心就是求取灰度化函数:

$$f(r,g,b;w)=\sum_i w_i m_i$$

其中$m_i$是向量空间的第$i$个基底,于是灰度化问题就转化为求解9个${w}$系数。作者的解法也挺巧妙,值得一看~