cv::applyColorMap()能够实现预定义的伪彩色,这个是众所周知的事情。
并且和matlab提供的很相近
除了这些预置的变换,如果我想实现新的变换,需要做LUT变换
cv
:
:Mat image_gray_3c;
//单通道的灰度图,转换成R、G、B三通道值均相等的三通道图
cv
:
:cvtColor(image_gray, image_gray_3c, cv
:
:COLOR_GRAY2RGB);
//opencv默认的颜色排列顺序是BGR,而这里自定义的colormap的顺序是RGB
cv
:
:cvtColor(golden_map, golden_map, cv
:
:COLOR_BGR2RGB);
cv
:
:Mat image_color;
cv
:
:LUT(image_gray_3c, golden_map, image_color);
但是,这段代码只是给出了方法,而没有给出具体的image_color。如果我对现有的colormap不满意,那么如何具体来做?
重要的参考,就是OpenCV自己的代码:
colormap.cpp
比如
class Ocean
:
public ColorMap {
public
:
Ocean()
: ColorMap() {
init(
256);
}
Ocean(
int n)
: ColorMap() {
init(n);
}
void init(
int n) {
static
const
float r[]
= {
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0.
04761904761904762f,
0.
09523809523809523f,
0.
1428571428571428f,
0.
1904761904761905f,
0.
2380952380952381f,
0.
2857142857142857f,
0.
3333333333333333f,
0.
3809523809523809f,
0.
4285714285714285f,
0.
4761904761904762f,
0.
5238095238095238f,
0.
5714285714285714f,
0.
6190476190476191f,
0.
6666666666666666f,
0.
7142857142857143f,
0.
7619047619047619f,
0.
8095238095238095f,
0.
8571428571428571f,
0.
9047619047619048f,
0.
9523809523809523f,
1};
static
const
float g[]
= {
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0.
02380952380952381f,
0.
04761904761904762f,
0.
07142857142857142f,
0.
09523809523809523f,
0.
119047619047619f,
0.
1428571428571428f,
0.
1666666666666667f,
0.
1904761904761905f,
0.
2142857142857143f,
0.
2380952380952381f,
0.
2619047619047619f,
0.
2857142857142857f,
0.
3095238095238095f,
0.
3333333333333333f,
0.
3571428571428572f,
0.
3809523809523809f,
0.
4047619047619048f,
0.
4285714285714285f,
0.
4523809523809524f,
0.
4761904761904762f,
0.
5f,
0.
5238095238095238f,
0.
5476190476190477f,
0.
5714285714285714f,
0.
5952380952380952f,
0.
6190476190476191f,
0.
6428571428571429f,
0.
6666666666666666f,
0.
6904761904761905f,
0.
7142857142857143f,
0.
7380952380952381f,
0.
7619047619047619f,
0.
7857142857142857f,
0.
8095238095238095f,
0.
8333333333333334f,
0.
8571428571428571f,
0.
8809523809523809f,
0.
9047619047619048f,
0.
9285714285714286f,
0.
9523809523809523f,
0.
9761904761904762f,
1};
static
const
float b[]
= {
0,
0.
01587301587301587f,
0.
03174603174603174f,
0.
04761904761904762f,
0.
06349206349206349f,
0.
07936507936507936f,
0.
09523809523809523f,
0.
1111111111111111f,
0.
126984126984127f,
0.
1428571428571428f,
0.
1587301587301587f,
0.
1746031746031746f,
0.
1904761904761905f,
0.
2063492063492063f,
0.
2222222222222222f,
0.
2380952380952381f,
0.
253968253968254f,
0.
2698412698412698f,
0.
2857142857142857f,
0.
3015873015873016f,
0.
3174603174603174f,
0.
3333333333333333f,
0.
3492063492063492f,
0.
3650793650793651f,
0.
3809523809523809f,
0.
3968253968253968f,
0.
4126984126984127f,
0.
4285714285714285f,
0.
4444444444444444f,
0.
4603174603174603f,
0.
4761904761904762f,
0.
492063492063492f,
0.
5079365079365079f,
0.
5238095238095238f,
0.
5396825396825397f,
0.
5555555555555556f,
0.
5714285714285714f,
0.
5873015873015873f,
0.
6031746031746031f,
0.
6190476190476191f,
0.
6349206349206349f,
0.
6507936507936508f,
0.
6666666666666666f,
0.
6825396825396826f,
0.
6984126984126984f,
0.
7142857142857143f,
0.
7301587301587301f,
0.
746031746031746f,
0.
7619047619047619f,
0.
7777777777777778f,
0.
7936507936507936f,
0.
8095238095238095f,
0.
8253968253968254f,
0.
8412698412698413f,
0.
8571428571428571f,
0.
873015873015873f,
0.
8888888888888888f,
0.
9047619047619048f,
0.
9206349206349206f,
0.
9365079365079365f,
0.
9523809523809523f,
0.
9682539682539683f,
0.
9841269841269841f,
1};
Mat X
= linspace(
0,
1,
64);
this
-
>_lut
= ColorMap
:
:linear_colormap(X,
Mat(
64,
1, CV_32FC1, (
void
*)r).clone(),
// red
Mat(
64,
1, CV_32FC1, (
void
*)g).clone(),
// green
Mat(
64,
1, CV_32FC1, (
void
*)b).clone(),
// blue
n);
// number of sample points
}
};
明显这个colormap中最主要的成分就是rgb的大矩阵,它返回的结果是LUT。关键问题是这样的矩阵如何获得?或者,如何修改?
其实,如果我们深入研究的话,就可以发现这里OpenCV实现的不仅仅是LUT,还有其它很多东西。比如3通道,比如插值等。为了实现这些功能,它添加了很多函数,如果想把这些函数集成过来,可能会花费较多精力。因此,最好的方法,就是修改现有的OpenCV代码,重新生成dll文件。
最终,我们套用ocean的色彩对summer进行修改,修改前
修改后
从而将绿色的成分更多的凸显出来。效果很好。
最后,还有一个小tip:
配置项目属性的时候,选择刚刚生成的bin目录
这样会优先使用修改后的dll,从而不会影响通用的OpenCV.dll。
感谢阅读至此,希望有所收获。
cv
:
:Mat image_gray_3c;
//单通道的灰度图,转换成R、G、B三通道值均相等的三通道图
cv
:
:cvtColor(image_gray, image_gray_3c, cv
:
:COLOR_GRAY2RGB);
//opencv默认的颜色排列顺序是BGR,而这里自定义的colormap的顺序是RGB
cv
:
:cvtColor(golden_map, golden_map, cv
:
:COLOR_BGR2RGB);
cv
:
:Mat image_color;
cv
:
:LUT(image_gray_3c, golden_map, image_color);
class Ocean
:
public ColorMap {
public
:
Ocean()
: ColorMap() {
init(
256);
}
Ocean(
int n)
: ColorMap() {
init(n);
}
void init(
int n) {
static
const
float r[]
= {
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0.
04761904761904762f,
0.
09523809523809523f,
0.
1428571428571428f,
0.
1904761904761905f,
0.
2380952380952381f,
0.
2857142857142857f,
0.
3333333333333333f,
0.
3809523809523809f,
0.
4285714285714285f,
0.
4761904761904762f,
0.
5238095238095238f,
0.
5714285714285714f,
0.
6190476190476191f,
0.
6666666666666666f,
0.
7142857142857143f,
0.
7619047619047619f,
0.
8095238095238095f,
0.
8571428571428571f,
0.
9047619047619048f,
0.
9523809523809523f,
1};
static
const
float g[]
= {
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0.
02380952380952381f,
0.
04761904761904762f,
0.
07142857142857142f,
0.
09523809523809523f,
0.
119047619047619f,
0.
1428571428571428f,
0.
1666666666666667f,
0.
1904761904761905f,
0.
2142857142857143f,
0.
2380952380952381f,
0.
2619047619047619f,
0.
2857142857142857f,
0.
3095238095238095f,
0.
3333333333333333f,
0.
3571428571428572f,
0.
3809523809523809f,
0.
4047619047619048f,
0.
4285714285714285f,
0.
4523809523809524f,
0.
4761904761904762f,
0.
5f,
0.
5238095238095238f,
0.
5476190476190477f,
0.
5714285714285714f,
0.
5952380952380952f,
0.
6190476190476191f,
0.
6428571428571429f,
0.
6666666666666666f,
0.
6904761904761905f,
0.
7142857142857143f,
0.
7380952380952381f,
0.
7619047619047619f,
0.
7857142857142857f,
0.
8095238095238095f,
0.
8333333333333334f,
0.
8571428571428571f,
0.
8809523809523809f,
0.
9047619047619048f,
0.
9285714285714286f,
0.
9523809523809523f,
0.
9761904761904762f,
1};
static
const
float b[]
= {
0,
0.
01587301587301587f,
0.
03174603174603174f,
0.
04761904761904762f,
0.
06349206349206349f,
0.
07936507936507936f,
0.
09523809523809523f,
0.
1111111111111111f,
0.
126984126984127f,
0.
1428571428571428f,
0.
1587301587301587f,
0.
1746031746031746f,
0.
1904761904761905f,
0.
2063492063492063f,
0.
2222222222222222f,
0.
2380952380952381f,
0.
253968253968254f,
0.
2698412698412698f,
0.
2857142857142857f,
0.
3015873015873016f,
0.
3174603174603174f,
0.
3333333333333333f,
0.
3492063492063492f,
0.
3650793650793651f,
0.
3809523809523809f,
0.
3968253968253968f,
0.
4126984126984127f,
0.
4285714285714285f,
0.
4444444444444444f,
0.
4603174603174603f,
0.
4761904761904762f,
0.
492063492063492f,
0.
5079365079365079f,
0.
5238095238095238f,
0.
5396825396825397f,
0.
5555555555555556f,
0.
5714285714285714f,
0.
5873015873015873f,
0.
6031746031746031f,
0.
6190476190476191f,
0.
6349206349206349f,
0.
6507936507936508f,
0.
6666666666666666f,
0.
6825396825396826f,
0.
6984126984126984f,
0.
7142857142857143f,
0.
7301587301587301f,
0.
746031746031746f,
0.
7619047619047619f,
0.
7777777777777778f,
0.
7936507936507936f,
0.
8095238095238095f,
0.
8253968253968254f,
0.
8412698412698413f,
0.
8571428571428571f,
0.
873015873015873f,
0.
8888888888888888f,
0.
9047619047619048f,
0.
9206349206349206f,
0.
9365079365079365f,
0.
9523809523809523f,
0.
9682539682539683f,
0.
9841269841269841f,
1};
Mat X
= linspace(
0,
1,
64);
this
-
>_lut
= ColorMap
:
:linear_colormap(X,
Mat(
64,
1, CV_32FC1, (
void
*)r).clone(),
// red
Mat(
64,
1, CV_32FC1, (
void
*)g).clone(),
// green
Mat(
64,
1, CV_32FC1, (
void
*)b).clone(),
// blue
n);
// number of sample points
}
};