0

I finally solved my problem here with lennon310. I have a picture of thousands of thin peaks in Time-Frequency picture. I cannot see all the same time in one picture. Depending on the physical width of my time window, some windows appear and some come visible.

Pictures of my data which I plot by imagesc

enter image description here

enter image description here

enter image description here

All pictures are from the same data points T, F, B.

How can you plot all peaks at once in a picture in Matlab?

Community
  • 1
  • 1
Léo Léopold Hertz 준영
  • 134,464
  • 179
  • 445
  • 697
  • Masi, I don't quite get the reason why you cannot imagesc all the columns of B in one figure? Can you please let me know how did you plot the three figures above? – lennon310 Dec 31 '13 at 17:47
  • @lennon310 The resolution of the display is not enough. We need a different filter kernel for display, because the resolution is lower. Please, see BenVoigt's answers below. These pictures are taken by resizing the width of the Matlab's window horizontally when the picture is already ready. This shows that the resolution is not enough, since some peaks are shown at some Matlab window selection. Example data here https://dl.dropboxusercontent.com/u/62073194/wv-resolution%20not%20enough%20for%20display.fig – Léo Léopold Hertz 준영 Jan 01 '14 at 13:13
  • @lennon310 Picture is uploaded. I think I have mistakes in my computation. I cannot keep the pixel native so picture not native. I have to develop the kernel filter for the distribution. Do you have any ideas how to do it? The sampling frequency is 360Hz. My sample is about 13.892 seconds length. The kernel is normalised Sinc(vu) function. – Léo Léopold Hertz 준영 Jan 01 '14 at 16:47

7 Answers7

1

You need to resize the image using resampling to prevent the aliasing effect (that craigim described as unavoidable).

For example, the MATLAB imresize function can perform anti-aliasing. Don't use the "nearest" resize method, that's what you have now.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • Is this what you mean below? I have to now implement the convolution and kernel filter. I have peaks in y- and x-axis. **Should I implement this **filter2** function on the X- and Y-axis?** I think with complex exponential function in the Y-direction because of the Discrete Fourier Transform taken before. – Léo Léopold Hertz 준영 Dec 31 '13 at 18:41
  • Once the image has been created using `imagesc`, the information with the peaks has already been aliased out and lost. Resizing it using `imresize` will not bring it back. – craigim Dec 31 '13 at 22:13
  • Then pass larger dimensions to imagesc, then resize with imresize. The focus of imagesc seems to be on the range of color, not geometric scale. – Ben Voigt Dec 31 '13 at 22:32
  • @BenVoigt Please, see my extension to your answer below. **Do you mean that by kernel filter?** I only passed the data values through the kernel. I did apply any filter. I have not yet used anywhere convolution so I think the kernel filter is not ready yet. – Léo Léopold Hertz 준영 Jan 01 '14 at 18:28
0

Extension to @BenVoigt's answer

My try

B = abs(B);
F1 = filter2(B,T); % you need a different filter kernel because resolution is lower    
T = filter2(B,F);
F = F1;
image1 = imagesc(B);
display1 = imresize(image1, [600 600], 'bilinear');   
imshow(T*t, F*fs, display1); 

where are some problems.

I get again picture where the resolution is not enough

enter image description here

Léo Léopold Hertz 준영
  • 134,464
  • 179
  • 445
  • 697
  • 1
    You didn't provide a new size to `imresize`, so it didn't do anything. Call `display1 = imresize(image1, [width height], 'bilinear');` where `width` and `height` are the size of the plot (in pixels). – Ben Voigt Dec 31 '13 at 18:51
  • 1
    Or you can change your analysis kernel to analyze a smaller number of frequency bands that will fit within your screen resolution. It depends on whether you will do other processing on the data besides display it. If only display, process fewer wider frequency bands. If you do other processing, then filter using the original kernel, and use `imresize` when you want to display it. – Ben Voigt Dec 31 '13 at 18:52
  • I applied equispaced sampling taking every 100th point. The resolution is still not enough. I think the problem is in the use of the function **imresize**. – Léo Léopold Hertz 준영 Dec 31 '13 at 19:03
  • 1
    Now you're just throwing away data, don't do that. The point of resampling is to preserve the low frequency content of all the data, not just a few samples. – Ben Voigt Dec 31 '13 at 19:05
  • Let's go back to your additional data processing, and change nothing except that `imshow(image1);` becomes `display1 = imresize(image1, [600 600], 'bicubic'); imshow(display1);` – Ben Voigt Dec 31 '13 at 19:06
  • @BenVoigt I did now some changes. Is the order of operations right now? The resolution is still a problem. – Léo Léopold Hertz 준영 Dec 31 '13 at 19:18
  • Unlike your original pictures, I now see all your peaks, but several are faint. Do you agree? Perhaps the next thing is to increase brightness/contrast. – Ben Voigt Dec 31 '13 at 19:28
  • For contrast adjustment, see http://www.mathworks.com/products/image/examples.html?file=/products/demos/shipping/images/ipexcontrast.html – Ben Voigt Dec 31 '13 at 19:30
0

2nd Extension to BenVoigt's answer

My suggestion for one kernel filter is with convolution of relative random error

data(find(data ~= 0)) = sin(pi .* data(find(data ~= 0))) ./ (pi*data(find(data ~= 0)));        
data(find(data == 0)) = 1; % removing lastly the discontinuity
data1 = data + 0.0000001 * mean(abs(data(:))) * randn(size(data));
data = conv(data, data1);

Is this what BenVoigt means by the kernel filter for distribution?

This gives results like

enter image description here

where the resolution is still a problem. The central peaks tend to multiply easily if I resize the window.

I had old code active in the above picture but it did not change the result. The above code is still not enough for the kernel filter of the display. Probably, some filter functions has to be applied to the time and frequency axis separately still, something like:

F1 = filter2(B,T); % you need a different kernel filter because resolution is lower    
T = filter2(B,F);
F = F1;

These filters mess up the values on the both axis. I need to understand them better to fix this. But first to understand if they are the right way to go.

The figure has be resized still. The size of the data was 5001x1 double and those of F and T 13635x1 double. So I think I should resize lastly after setting axis, labels and title by

imresize(image, [13635 13635], 'bilinear');   

since the distirbution is bilinear.

Léo Léopold Hertz 준영
  • 134,464
  • 179
  • 445
  • 697
0

3rd Extension to BenVoigt's answer

I plot the picture now by

imagesc([0 numel(T)], [0 numel(F)], B);              

I have a big aliasing problem in my pictures. Probably, something like this should be to manipulate the Time-Frequency Representation

T = filter2(B,t); % you need a different filter kernel because resolution is lower    
F = filter2(B,fs);
Léo Léopold Hertz 준영
  • 134,464
  • 179
  • 445
  • 697
0

4th extension to BenVoigt's answer and comment

I remove the filters and addition of random relative errors. I set the size of T,F,B, and run

imagesc([0 numel(T)], [0 numel(F)], B, [0 numel(B)])

I get still with significant aliasing but different picture

enter image description here

Léo Léopold Hertz 준영
  • 134,464
  • 179
  • 445
  • 697
-1

This isn't being flippant, but I think the only way is to get a wider monitor with a higher pixel density. MATLAB and your video card can only show so many pixels on the screen, and must decide which to show and which to leave out. The data is still there, it just isn't getting displayed. Since you have a lot of very narrow lines, some of them are going to get skipped when decisions are made as to which pixels to light up. Changing the time window size changes which lines get aliased away and which ones get lucky enough to show up on the screen.

My suggestions are, in no particular order: convolute your lines with a Gaussian along the time axis to broaden them, thus increasing the likelihood that part of the peak will appear on the screen. Print them out on a 600 dpi printer and see if they appear. Make several plots, each zooming in on a separate time window.

craigim
  • 3,884
  • 1
  • 22
  • 42
  • This is not possible solution. I cannot window along time axis only. I have to do it along frequency axis also. The final picture will have peaks in both axis. So probably, I should run what you suggests along both axis but taking into account the Complex Exponential in the Frequency axis because of Discrete Fourier Transform. – Léo Léopold Hertz 준영 Dec 31 '13 at 17:37
  • When I say zoom in on different time windows, I'm not talking about actual math, but just issuing a command like `set(gca,'XLim',[0 4])` to display the time from 0 to 4 seconds. Rinse, repeat. – craigim Dec 31 '13 at 17:47
  • 1
    Leaving columns out is not the only way to display an image in a smaller viewport. There are downscaling methods that include some form of resampling, and even GDI provides [mechanisms that combine columns with AND or OR bitwise operations instead of decimating](http://msdn.microsoft.com/en-us/library/windows/desktop/dd145089.aspx). – Ben Voigt Dec 31 '13 at 18:18
  • The only part of this answer I consider worthwhile is the convolution suggestion (whether the kernel is Gaussian or some other lowpass filter) which is one of the usual steps in image resampling. – Ben Voigt Dec 31 '13 at 18:21
  • @BenVoigt The kernel is Normalised Sinc function, like in Wigner-Ville distribution. – Léo Léopold Hertz 준영 Dec 31 '13 at 18:24
  • @Masi: That's nice, but you will need a different filter kernel for display, because the resolution is lower. – Ben Voigt Dec 31 '13 at 18:26
  • @BenVoigt Leaving columns out is not the only way, but I believe it is the way that `imscale` does it. – craigim Dec 31 '13 at 22:10
  • I don't know why you talk about the video card leaving out pixels when actually imagesc removed them. – Ben Voigt Jan 01 '14 at 19:26
  • @BenVoigt Thank you for pointing that out! **Which function should I use in Matlab not to leave out pixels?** I have not found any function that takes three parameters like imagesc. – Léo Léopold Hertz 준영 Jan 01 '14 at 22:43
  • 1
    @Masi: If you tell imagesc how big to make the image, instead of letting it use the monitor size, then I assume it won't throw away data. The result will be too big, so then you'll use `imresize`, where you can control the resampling. – Ben Voigt Jan 01 '14 at 22:45
  • @BenVoigt I added there extension to your answer as an answer. How can you tell **imagesc** how big to make the image? Directly as list argument to **imagesc** or to **imresize**? – Léo Léopold Hertz 준영 Jan 02 '14 at 11:19
  • 1
    @Masi: Are you reading the documentation for these functions? It's right there: "`imagesc(x,y,C)` displays `C` as an image and specifies the bounds of the x- and y-axis with vectors `x` and `y`. If `x(1) > x(2)` or `y(1) > y(2)`, the image is flipped left-right or up-down, respectively." So, call `imagesc([0 numel(t)], [0 numel(f)], f_t_data)` – Ben Voigt Jan 02 '14 at 16:48
  • @BenVoigt Thank you for letting me understand this! I have very big problem with aliasing of the picture which has confused me a lot. My current command is **imagesc([0 numel(T)/1000], [0 numel(F)/68], B);** where is much aliasing but the values on the axis are correct. – Léo Léopold Hertz 준영 Jan 02 '14 at 17:09
  • @Masi: If you want to reduce the size by 1000 and by 68, do that in a separate imresize call. `image1 = imagesc([0 numel(T)], [0 numel(F)], B); image1 = imresize(image1, [numel(T)/1000 numel(F)/68]);` So no aliasing, and the result is the desired size. – Ben Voigt Jan 02 '14 at 17:10
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/44343/discussion-between-ben-voigt-and-masi) – Ben Voigt Jan 02 '14 at 17:13
  • I know the frequency *fs* and time step *t* for the axis. The problem is to apply this to the picture. Probably, filter2 should be used as in my 3rd extension to your answer. – Léo Léopold Hertz 준영 Jan 02 '14 at 17:13
  • Well I don't know. The `image` documentation makes clear what `imagesc` doesn't... that the x and y ranges only affect the labels, not the size of the image. So that is a dead end. Maybe `imresize` should actually be used *before* `imagesc`. – Ben Voigt Jan 02 '14 at 17:13
  • `imagesc(imresize(B, [numel(T)/1000 numel(F)/68]));` – Ben Voigt Jan 02 '14 at 17:14
  • @Masi: What is `size(B)`? – Ben Voigt Jan 02 '14 at 17:17
  • size(B) gives ans = 101 13635. – Léo Léopold Hertz 준영 Jan 02 '14 at 17:18
  • The distribution is bilinear so probably something like **imagesc(imresize(B, [numel(T) numel(F)]), 'bilinear'); **. I get the error **Either scale or output size must be specified.** I am not sure how the **imagesc** should take the output of **imresize**. – Léo Léopold Hertz 준영 Jan 02 '14 at 17:24
-1

3rd Extension to BenVoigt's answer

My attempt to tell imagesc how big to make the image, instead of letting to use the monitor size, so it won't away data.

imagesc(T*t, F*fs, B, [50 50]);           
% imagesc(T*t, F*fs, B');

% This must be last
imresize(image, 'bilinear', [64 30],);   

I am not sure where I should specify the amount of pixels in x-axis and y-axis, either in the command imagesc or imresize.

What is the correct way of resizing the image here?

Léo Léopold Hertz 준영
  • 134,464
  • 179
  • 445
  • 697