Armadillo移植imagesc以保存矩阵

时间:2015-07-31 11:24:47

标签: c++ image matlab 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]); 

得到这个结果:

enter image description here

我使用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); 

enter image description here

更新2 :使用dbabs保存频谱图

  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);

结果:

enter image description here

2 个答案:

答案 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());` 

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

只需编写图像即可使用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进行绘图。