我有这个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]);
得到这个结果:
我使用Armadillo lib成功移植到C ++并得到了mat结果:
mat f,t,spec_t;
问题在于我不知道在matlab中转换像imagesc这样的位图。
我搜索并找到this answer,但似乎它在我的情况下不起作用,因为:
imagesc
方法采用4个参数,其中包含向量x和y imagesc
方法也支持扩展(我实际上不知道它是如何工作的)
有没有人有任何建议?
更新:以下是Armadillo中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);
结果:
答案 0 :(得分:3)
Armadillo是一个线性代数包,AFAIK它不提供图形例程。如果你使用类似opencv的东西那么它就非常简单。
请参阅this link有关opencv的imshow()
和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)
这是图像的第三维。
你的矩阵是一个二维图像,所以显示它的最自然的方式是灰度级(就像你的光谱一样)。
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)
,然后对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)
或类似的东西。
答案 1 :(得分:3)
您可以使用SigPack,一个位于犰狳顶部的信号处理库。它具有频谱图支持,您可以将绘图保存为许多不同的格式(png,ps,eps,tex,pdf,svg,emf,gif)。 SigPack使用Gnuplot进行绘图。