Armadillo 移植 imagesc 从矩阵保存图像位图
Armadillo porting imagesc to save image bitmap from matrix
我有这个 matlab 代码可以在做完超谱图后显示图像对象(stft,耦合 plca...)
t = z2 *stft_options.hop/stft_options.sr;
f = stft_options.sr*[0:size(spec_t,1)-1]/stft_options.N/1000;
max_val = max(max(db(abs(spec_t))));
imagesc(t, f, db(abs(spec_t)),[max_val-60 max_val]);
得到这个结果:
我通过使用 Armadillo lib 成功地移植到 C++ 并获得了 mat 结果:
mat f,t,spec_t;
问题是我不知道如何在 matlab 中像 imagesc 那样转换位图。
我搜索并找到了 this answer,但它似乎不适用于我的情况,因为:
- 我用的是双精度矩阵而不是整型矩阵,不能标记为位图颜色
imagesc
方法采用 4 个参数,其边界为向量 x 和 y
imagesc
方法也支持缩放(其实我也不知道怎么用)
有人有什么建议吗?
更新:这是犰狳中save
方法的结果。它看起来不像上面的频谱图图像。我错过了什么吗?
spec_t.save("spec_t.png", pgm_binary);
更新 2:使用 db
和 abs
保存频谱图
mat spec_t_mag = db(abs(spec_t)); // where db method: m = 10 * log10(m);
mag_spec_t.save("mag_spec_t.png", pgm_binary);
结果:
Armadillo 是一个线性代数包,据我所知它不提供图形例程。如果你对那些使用像 opencv 这样的东西那么它真的很简单。
请参阅 this link about opencv's imshow()
, and this link 了解如何在程序中使用它。
请注意,opencv(与大多数其他库一样)使用行优先索引 (x,y),而 Armadillo 使用列优先(行、列)索引,如 here 所述。
对于缩放,最安全的方法是自己转换为 unsigned char。在犰狳中会是这样的:
arma::Mat<unsigned char> mat2=255*(mat-mat.min())/(mat.max()-mat.min());
t
和f
变量用于设置轴,它们不是位图的一部分。
如果只是写一张图片,你可以使用 Armadillo。 Here是关于如何编写便携式灰度图(PGM)和便携式像素图(PPM)图像的说明。 PGM 导出仅适用于 2D 矩阵,PPM 导出仅适用于 3D 矩阵,其中第 3 维(尺寸 3)是红色、绿色和蓝色的通道。
你的 matlab 图看起来更漂亮的原因是因为它有一个颜色映射:每个值 0..255 到向量 [R, G, B] 的映射,指定了红色、绿色和蓝色的相对强度。一张照片在每一点都有一个RGB值:
colormap(gray);
x=imread('onion.png');
imagesc(x);
size(x)
这是图像的第 3 个维度。
您的矩阵是二维图像,因此最自然的显示方式是灰度级(就像您的光谱那样)。
x=mean(x,3);
imagesc(x);
这意味着 R、G 和 B 强度随着 mat
中的值共同增加。您可以将不同 R、G、B 组合的颜色映射放在一个变量中,然后使用它来代替,即 y=colormap('hot');colormap(y);
。变量 y
显示(重新缩放的)图像值的 R、G、B 组合。
也可以制作您自己的颜色图(在 matlab 中您可以指定 64 个 R、G 和 B 组合,值介于 0 和 1 之间):
z[63:-1:0; 1:2:63 63:-2:0; 0:63]'/63
colormap(z);
现在,随着图像值的增加,红色强度会降低(从最高级别开始),绿色强度会迅速增加然后降低,蓝色值会从最小值增加到最大值。
因为PPM出现(不知格式)不支持色图,需要在3D数组中指定R,G,B值。对于类似于 z
的颜色顺序,您需要制作一个 Cube<unsigned char> c(ysize, xsize, 3)
,然后对于 mat2
中的每个像素 y, x
,执行:
c(y,x,0) = 255-mat2(y,x);
c(y,x,1) = 255-abs(255-2*mat2(y,x));
x(y,x,2) = mat2(y,x)
或非常相似的东西。
您可以使用 SigPack,一个基于 Armadillo 的信号处理库。它支持频谱图,您可以将绘图保存为多种不同的格式(png、ps、eps、tex、pdf、svg、emf、gif)。 SigPack 使用 Gnuplot 进行绘图。
我有这个 matlab 代码可以在做完超谱图后显示图像对象(stft,耦合 plca...)
t = z2 *stft_options.hop/stft_options.sr;
f = stft_options.sr*[0:size(spec_t,1)-1]/stft_options.N/1000;
max_val = max(max(db(abs(spec_t))));
imagesc(t, f, db(abs(spec_t)),[max_val-60 max_val]);
得到这个结果:
我通过使用 Armadillo lib 成功地移植到 C++ 并获得了 mat 结果:
mat f,t,spec_t;
问题是我不知道如何在 matlab 中像 imagesc 那样转换位图。
我搜索并找到了 this answer,但它似乎不适用于我的情况,因为:
- 我用的是双精度矩阵而不是整型矩阵,不能标记为位图颜色
imagesc
方法采用 4 个参数,其边界为向量 x 和 yimagesc
方法也支持缩放(其实我也不知道怎么用)
有人有什么建议吗?
更新:这是犰狳中save
方法的结果。它看起来不像上面的频谱图图像。我错过了什么吗?
spec_t.save("spec_t.png", pgm_binary);
更新 2:使用 db
和 abs
mat spec_t_mag = db(abs(spec_t)); // where db method: m = 10 * log10(m);
mag_spec_t.save("mag_spec_t.png", pgm_binary);
结果:
Armadillo 是一个线性代数包,据我所知它不提供图形例程。如果你对那些使用像 opencv 这样的东西那么它真的很简单。
请参阅 this link about opencv's imshow()
, and this link 了解如何在程序中使用它。
请注意,opencv(与大多数其他库一样)使用行优先索引 (x,y),而 Armadillo 使用列优先(行、列)索引,如 here 所述。
对于缩放,最安全的方法是自己转换为 unsigned char。在犰狳中会是这样的:
arma::Mat<unsigned char> mat2=255*(mat-mat.min())/(mat.max()-mat.min());
t
和f
变量用于设置轴,它们不是位图的一部分。
如果只是写一张图片,你可以使用 Armadillo。 Here是关于如何编写便携式灰度图(PGM)和便携式像素图(PPM)图像的说明。 PGM 导出仅适用于 2D 矩阵,PPM 导出仅适用于 3D 矩阵,其中第 3 维(尺寸 3)是红色、绿色和蓝色的通道。
你的 matlab 图看起来更漂亮的原因是因为它有一个颜色映射:每个值 0..255 到向量 [R, G, B] 的映射,指定了红色、绿色和蓝色的相对强度。一张照片在每一点都有一个RGB值:
colormap(gray);
x=imread('onion.png');
imagesc(x);
size(x)
这是图像的第 3 个维度。
您的矩阵是二维图像,因此最自然的显示方式是灰度级(就像您的光谱那样)。
x=mean(x,3);
imagesc(x);
这意味着 R、G 和 B 强度随着 mat
中的值共同增加。您可以将不同 R、G、B 组合的颜色映射放在一个变量中,然后使用它来代替,即 y=colormap('hot');colormap(y);
。变量 y
显示(重新缩放的)图像值的 R、G、B 组合。
也可以制作您自己的颜色图(在 matlab 中您可以指定 64 个 R、G 和 B 组合,值介于 0 和 1 之间):
z[63:-1:0; 1:2:63 63:-2:0; 0:63]'/63
colormap(z);
现在,随着图像值的增加,红色强度会降低(从最高级别开始),绿色强度会迅速增加然后降低,蓝色值会从最小值增加到最大值。
因为PPM出现(不知格式)不支持色图,需要在3D数组中指定R,G,B值。对于类似于 z
的颜色顺序,您需要制作一个 Cube<unsigned char> c(ysize, xsize, 3)
,然后对于 mat2
中的每个像素 y, x
,执行:
c(y,x,0) = 255-mat2(y,x);
c(y,x,1) = 255-abs(255-2*mat2(y,x));
x(y,x,2) = mat2(y,x)
或非常相似的东西。
您可以使用 SigPack,一个基于 Armadillo 的信号处理库。它支持频谱图,您可以将绘图保存为多种不同的格式(png、ps、eps、tex、pdf、svg、emf、gif)。 SigPack 使用 Gnuplot 进行绘图。