added spectrogram plot

git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-analysis/EcologicalEngine@92654 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Gianpaolo Coro 2014-03-04 19:02:18 +00:00
parent ef44fa2376
commit a9579a12af
5 changed files with 381 additions and 5 deletions

View File

@ -0,0 +1,110 @@
package org.gcube.contentmanagement.graphtools.plotting.graphs;
/*
* Copyright 1999-2004 Carnegie Mellon University.
* Portions Copyright 2002-2004 Sun Microsystems, Inc.
* Portions Copyright 2002-2004 Mitsubishi Electric Research Laboratories.
* All Rights Reserved. Use is subject to license terms.
*
* See the file "README" for information on usage and
* redistribution of this file, and for a DISCLAIMER OF ALL
* WARRANTIES.
*
*/
import java.util.Arrays;
import java.awt.Color;
public class ColorMap
{
public int size;
public byte r[];
public byte g[];
public byte b[];
public Color table[];
public static ColorMap getJet()
{
return getJet(64);
}
public static ColorMap getJet(int n)
{
byte r[] = new byte[n];
byte g[] = new byte[n];
byte b[] = new byte[n];
int maxval = 255;
//Arrays.fill(g, 0, 8, (byte)0);
Arrays.fill(g, 0, n/8, (byte)0);
//for(int x = 0; x < 16; x++)
// g[x+8] = (byte)(maxval*x/16);
for(int x = 0; x < n/4; x++)
g[x+n/8] = (byte)(maxval*x*4/n);
//Arrays.fill(g, 24, 40, (byte)maxval);
Arrays.fill(g, n*3/8, n*5/8, (byte)maxval);
//for(int x = 0; x < 16; x++)
// g[x+40] = (byte)(maxval-(maxval*x/16));
for(int x = 0; x < n/4; x++)
g[x+n*5/8] = (byte)(maxval-(maxval*x*4/n));
//Arrays.fill(g, 56, 64, (byte)0);
Arrays.fill(g, n*7/8, n, (byte)0);
//for(int x = 0; x < g.length; x++)
// b[x] = g[(x+16) % g.length];
for(int x = 0; x < g.length; x++)
b[x] = g[(x+n/4) % g.length];
//Arrays.fill(b, 56, 64, (byte)0);
Arrays.fill(b, n*7/8, n, (byte)0);
//Arrays.fill(g, 0, 8, (byte)0);
Arrays.fill(g, 0, n/8, (byte)0);
//for(int x = 8; x < g.length; x++)
// r[x] = g[(x+48) % g.length];
for(int x = n/8; x < g.length; x++)
r[x] = g[(x+n*6/8) % g.length];
ColorMap cm = new ColorMap();
cm.size = n;
cm.r = r;
cm.g = g;
cm.b = b;
cm.table = new Color[n];
for(int x = 0; x < n; x++)
//cm.table[x] = new Color((int)r[x]+maxval/2+1,
//(int)g[x]+maxval/2+1, (int)b[x]+maxval/2+1);
cm.table[x] = new Color(cm.getColor(x));
return cm;
}
public int getColor(int idx)
{
int pixel = ((r[idx] << 16) & 0xff0000)
| ((g[idx] << 8) & 0xff00)
| (b[idx] & 0xff);
return pixel;
}
public String toString()
{
StringBuffer s = new StringBuffer(500);
for(int x = 0; x < size; x++)
{
s.append(x+": {"+r[x]+",\t"+g[x]+",\t"+b[x]+"}\t");
if(x%3 == 2)
s.append("\n");
}
return s.toString();
}
public static void main(String[] args)
{
ColorMap jet = getJet();
ColorMap jet128 = getJet(128);
System.out.println("Jet:\n"+jet+"\n\nJet128:\n"+jet128);
}
}

View File

@ -0,0 +1,191 @@
package org.gcube.contentmanagement.graphtools.plotting.graphs;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.awt.image.ImageObserver;
import java.awt.image.ReplicateScaleFilter;
import javax.swing.JPanel;
public class SpectrumPlot2 extends JPanel {
private BufferedImage spectrogram = null;
private Image scaledSpectrogram = null;
private float zoom = 1.0f;
private float vzoom = 1.0f;
private double offsetFactor;
private double[][] data;
public int width;
public int height;
private ColorMap cmap = ColorMap.getJet(64);
// private static float minZoom = .1f;
private double minVal;
private double maxVal;
public SpectrumPlot2(double[][] dat) {
data = dat;
width = dat.length;
height = dat[0].length;
// audio.addChangeListener(new ChangeListener() {
// public void stateChanged(ChangeEvent event) {
// computeSpectrogram();
// }
// });
computeSpectrogram();
}
private void computeSpectrogram() {
try {
// prepare the data:
maxVal = 0;
minVal = Integer.MAX_VALUE;
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
if (data[x][y] > maxVal)
maxVal = data[x][y];
if (data[x][y] < minVal)
minVal = data[x][y];
}
}
double minIntensity = Math.abs(minVal);
double maxIntensity = maxVal + minIntensity;
int maxYIndex = height - 1;
Dimension d = new Dimension(width, height);
setMinimumSize(d);
setMaximumSize(d);
setPreferredSize(d);
/*
* Create the image for displaying the data.
*/
spectrogram = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
/*
* Set scaleFactor so that the maximum value, after removing the
* offset, will be 0xff.
*/
double scaleFactor = ((0x3f + offsetFactor) / maxIntensity);
for (int i = 0; i < width; i++) {
for (int j = maxYIndex; j >= 0; j--) {
/*
* Adjust the grey value to make a value of 0 to mean white
* and a value of 0xff to mean black.
*/
int grey = (int) ((data[i][j] + minIntensity) * scaleFactor - offsetFactor);
// System.out.println(grey);
// use grey as an index into the colormap;
spectrogram.setRGB(i, maxYIndex - j, cmap.getColor(grey));
}
}
ImageFilter scaleFilter = new ReplicateScaleFilter((int) (zoom * width), (int) (vzoom * height));
scaledSpectrogram = createImage(new FilteredImageSource(spectrogram.getSource(), scaleFilter));
Dimension sz = getSize();
repaint(0, 0, 0, sz.width - 1, sz.height - 1);
// ImageIO.write(ImageTools.toBufferedImage(scaledSpectrogram), "png", new File("saved.png"));
} catch (Exception e) {
e.printStackTrace();
}
}
public void setOffsetFactor(double offsetFactor) {
this.offsetFactor = offsetFactor;
computeSpectrogram();
}
public void vzoomSet(float vzoom) {
this.vzoom = vzoom;
zoom();
}
public void hzoomSet(float zoom) {
zoomSet(zoom);
}
protected void zoomSet(float zoom) {
this.zoom = zoom;
zoom();
}
public void zoom() {
if (spectrogram != null) {
int width = spectrogram.getWidth();
int height = spectrogram.getHeight();
// do the zooming
width = (int) (zoom * width);
height = (int) (vzoom * height);
ImageFilter scaleFilter = new ReplicateScaleFilter(width, height);
scaledSpectrogram = createImage(new FilteredImageSource(spectrogram.getSource(), scaleFilter));
// so ScrollPane gets notified of the new size:
setPreferredSize(new Dimension(width, height));
revalidate();
repaint();
}
}
public float getVZoom() {
return vzoom;
}
public float getHZoom() {
return zoom;
}
public SpectrumPlot2 getColorBar() {
int barWidth = 20;
double[][] cb = new double[barWidth][cmap.size];
for (int x = 0; x < cb.length; x++)
for (int y = 0; y < cb[x].length; y++)
cb[x][y] = y;
return new SpectrumPlot2(cb);
}
public double getData(int x, int y) {
return data[x][y];
}
public int getDataWidth() {
return width;
}
public int getDataHeight() {
return height;
}
public void paint(Graphics g) {
Dimension sz = getSize();
g.setColor(Color.WHITE);
g.fillRect(0, 0, sz.width - 1, sz.height - 1);
if (spectrogram != null) {
g.drawImage(scaledSpectrogram, 0, 0, (ImageObserver) null);
}
}
}

View File

@ -24,6 +24,11 @@ public class PeriodicityDetector {
static float defaultSNratio = 0;
static float defaultFreqError = 1f;
public int currentSamplingRate;
public int currentWindowShiftSamples;
public int currentWindowAnalysisSamples;
public double[][] currentspectrum;
public double meanF=0;
public double lowermeanF=0;
public double uppermeanF=0;
@ -38,6 +43,8 @@ public class PeriodicityDetector {
public double endPeriodSampleIndex=0;
public double periodicityStrength=0;
public double minFrequency;
public double maxFrequency;
public String getPeriodicityStregthInterpretation(){
if (periodicityStrength>0.6)
@ -91,6 +98,7 @@ public class PeriodicityDetector {
return detectFrequency(signal, false);
}
public double detectFrequency(double[] signal, int samplingRate, float minPossibleFreq, float maxPossibleFreq, float wantedFreqError, boolean display) throws Exception {
// estimate the best samples based on the error we want
@ -119,12 +127,18 @@ public class PeriodicityDetector {
if (minPossibleFreq==0)
minPossibleFreq = 0.1f;
minFrequency=minPossibleFreq;
maxFrequency=maxPossibleFreq;
// display the signal
if (display)
SignalProcessing.displaySignalWithGenericTime(signal, 0, 1, "signal");
this.currentSamplingRate = samplingRate;
this.currentWindowShiftSamples = windowShiftSamples;
this.currentWindowAnalysisSamples = windowAnalysisSamples;
// trace spectrum
double[][] spectrum = SignalConverter.spectrogram("spectogram", signal, samplingRate, windowShiftSamples, windowAnalysisSamples, false);
double[][] spectrum = SignalConverter.spectrogram("spectrogram", signal, samplingRate, windowShiftSamples, windowAnalysisSamples, false);
if (display)
SignalConverter.displaySpectrogram(spectrum, signal, "complete spectrogram", samplingRate, windowShiftSamples, windowAnalysisSamples);
// apply the bandpass filter
@ -136,7 +150,7 @@ public class PeriodicityDetector {
SignalConverter signalMaximumAnalyzer = new SignalConverter();
double[] maxfrequencies = signalMaximumAnalyzer.takeMaxFrequenciesInSpectrogram(spectrum, samplingRate, windowAnalysisSamples, minPossibleFreq);
double[] powers = signalMaximumAnalyzer.averagepower;
currentspectrum=spectrum;
// display the maximum freqs
AnalysisLogger.getLogger().debug("Number of frequency peaks " + maxfrequencies.length);
// take the longest stable sequence of frequencies

View File

@ -83,10 +83,10 @@ public class SignalConverter {
return cepc;
}
public static BufferedImage createImage(JPanel panel) {
public static BufferedImage createImage(JPanel panel, int w, int h) {
int w = panel.getWidth();
int h = panel.getHeight();
// int w = panel.getWidth();
// int h = panel.getHeight();
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
panel.paint(g);
@ -277,6 +277,7 @@ public class SignalConverter {
* File(name+".png"));
*/
// Thread.sleep(2000);
// createImage(spec);
}
return spectrum;
}

View File

@ -1,5 +1,7 @@
package org.gcube.dataanalysis.ecoengine.signals;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
@ -8,12 +10,18 @@ import java.util.Arrays;
import java.util.Date;
import java.util.List;
import marytts.signalproc.display.SpectrogramCustom;
import marytts.signalproc.window.Window;
import org.gcube.contentmanagement.graphtools.data.BigSamplesTable;
import org.gcube.contentmanagement.graphtools.data.conversions.ImageTools;
import org.gcube.contentmanagement.graphtools.plotting.graphs.NumericSeriesGraph;
import org.gcube.contentmanagement.graphtools.plotting.graphs.SpectrumPlot2;
import org.gcube.contentmanagement.graphtools.plotting.graphs.TimeSeriesGraph;
import org.gcube.contentmanagement.lexicalmatcher.utils.AnalysisLogger;
import org.gcube.contentmanagement.lexicalmatcher.utils.MathFunctions;
import org.gcube.dataanalysis.ecoengine.configuration.AlgorithmConfiguration;
import org.jfree.chart.JFreeChart;
import org.jfree.data.time.FixedMillisecond;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYSeriesCollection;
@ -110,6 +118,58 @@ public class SignalProcessing {
nsg.render(collection);
}
public static Image renderSignalWithGenericTime(double[] signal, float t0, float timeshift, String name) {
org.jfree.data.xy.XYSeries xyseries = new org.jfree.data.xy.XYSeries(name);
float time = t0;
for (int i = 0; i < signal.length; i++) {
xyseries.add(time, signal[i]);
time = time + timeshift;
}
XYSeriesCollection collection = new XYSeriesCollection(xyseries);
JFreeChart chart = NumericSeriesGraph.createStaticChart(collection);
Image image = ImageTools.toImage(chart.createBufferedImage(680, 420));
return image;
}
public static Image renderSignalWithGenericTime(double[] signal, double [] timeline, String name) {
org.jfree.data.xy.XYSeries xyseries = new org.jfree.data.xy.XYSeries(name);
for (int i = 0; i < signal.length; i++) {
xyseries.add(timeline[i], signal[i]);
}
XYSeriesCollection collection = new XYSeriesCollection(xyseries);
JFreeChart chart = NumericSeriesGraph.createStaticChart(collection);
Image image = ImageTools.toImage(chart.createBufferedImage(680, 420));
return image;
}
public static Image renderSignalSpectrogram(double[] signal, double [] timeline, int samplingRate, int frameslength, int windowshift) {
SpectrogramCustom spec = new SpectrogramCustom(signal, samplingRate, Window.get(Window.HAMMING, frameslength), windowshift, frameslength, 640, 480);
double[][] spectrum = spec.spectra.toArray(new double[spec.spectra.size()][]);
spec.setZoomX(640d/(double)spectrum.length);
BufferedImage image = SignalConverter.createImage(spec,640,480);
return ImageTools.toImage(image);
}
public static Image renderSignalSpectrogram2(double[][] spectrogram) {
SpectrumPlot2 spectrumPlot = new SpectrumPlot2(spectrogram);
AnalysisLogger.getLogger().debug("Spectrum W:"+spectrumPlot.width);
AnalysisLogger.getLogger().debug("Spectrum H:"+spectrumPlot.height);
// spectrumPlot.hzoomSet(2f);
spectrumPlot.hzoomSet(640f/(float)spectrumPlot.width);
spectrumPlot.vzoomSet(480f/(float)spectrumPlot.height);
/*
ApplicationFrame app = new ApplicationFrame("Spectrogram ");
app.setContentPane(spectrumPlot);
app.pack();
app.setVisible(true);
*/
BufferedImage image = SignalConverter.createImage(spectrumPlot,640,480);
return ImageTools.toImage(image);
}
public static void displaySignalWithTime(double[] signal, Date[] dates, String name, String format) {
org.jfree.data.time.TimeSeries series = new org.jfree.data.time.TimeSeries(name);
for (int i = 0; i < signal.length; i++)