Armadillo移植imagesc以从矩阵中保存图像位图

R4j*_*R4j 6 c++ matlab image image-processing armadillo

我有这个matlab代码来做超级频谱图后显示图像对象(stft,couple 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]); 
Run Code Online (Sandbox Code Playgroud)

得到这个结果:

在此输入图像描述

我使用Armadillo lib 成功移植到C++ 并获得mat结果:

mat f,t,spec_t;
Run Code Online (Sandbox Code Playgroud)

问题是我不知道如何在matlab中转换像imagesc这样的位图.

我搜索并找到了这个答案,但似乎它在我的情况下不起作用,因为:

  • 我使用双矩阵代替整数矩阵,它不能标记为位图颜色
  • imagesc方法采用4个参数,其具有向量x和y的界限
  • imagesc方法还支持规模(我实际上不知道它是如何工作的)


有没有人有任何建议?

更新:这是save犰狳方法的结果.它看起来不像上面的频谱图.我错过了什么吗?

spec_t.save("spec_t.png", pgm_binary); 
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

更新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);
Run Code Online (Sandbox Code Playgroud)

结果如下:

在此输入图像描述

all*_*ije 3

Armadillo 是一个线性代数包,据我所知它不提供图形例程。如果你使用像 opencv 这样的东西,那么这真的很简单。

请参阅有关 opencv 的链接imshow(),以及有关如何在程序中使用它的链接。

请注意,opencv(与大多数其他库一样)使用行主索引(x,y),而犰狳使用列主索引(行,列),如此处所述

对于缩放,最安全的方法是自行转换为 unsigned char。在犰狳中,会是这样的:

arma::Mat<unsigned char> mat2=255*(mat-mat.min())/(mat.max()-mat.min());
Run Code Online (Sandbox Code Playgroud)

和变量用于设置轴,它们不是位图的一部分tf

如果只是写图像,您可以使用犰狳。这里介绍如何编写便携式灰度图(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)
Run Code Online (Sandbox Code Playgroud)

这是图像的第三维。

您的矩阵是二维图像,因此显示它的最自然的方式是灰度级(正如您的光谱所发生的那样)。

x=mean(x,3);
imagesc(x);
Run Code Online (Sandbox Code Playgroud)

这意味着 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);
Run Code Online (Sandbox Code Playgroud)

现在,对于增加图像值,红色强度减小(从最大级别开始),绿色强度快速增加然后减小,蓝色值从最小增加到最大。

由于PPM出现(我不知道格式)不支持颜色图,因此您需要在3D数组中指定R,G,B值。对于与您类似的颜色顺序,z您需要制作 a Cube<unsigned char> c(ysize, xsize, 3),然后对于y, x中的每个像素mat2,执行以下操作:

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)
Run Code Online (Sandbox Code Playgroud)

或者非常相似的东西。