1
package org.helioviewer.jhv.internal_plugins.NRGFilterPlugin;
7
import java.util.ArrayList;
8
import java.util.Collection;
9
import java.util.LinkedList;
10
import java.util.List;
12
import java.lang.Object;
13
import java.lang.Double;
15
import org.helioviewer.viewmodel.filter.Filter;
16
import org.helioviewer.viewmodel.filter.FilterListener;
17
import org.helioviewer.viewmodel.filter.FullImageFilter;
18
import org.helioviewer.viewmodel.filter.MetaDataFilter;
19
import org.helioviewer.viewmodel.filter.ObservableFilter;
20
import org.helioviewer.viewmodel.filter.RegionFilter;
21
import org.helioviewer.viewmodel.imagedata.ImageData;
22
import org.helioviewer.viewmodel.imagedata.SingleChannelByte8ImageData;
23
import org.helioviewer.viewmodel.imageformat.SingleChannelIntegralImageFormat;
24
import org.helioviewer.viewmodel.imagetransport.Byte8ImageTransport;
25
import org.helioviewer.viewmodel.metadata.HelioviewerMetaData;
26
import org.helioviewer.viewmodel.metadata.MetaData;
27
import org.helioviewer.viewmodel.region.Region;
28
import org.helioviewer.base.math.Vector2dDouble;
29
import org.helioviewer.base.math.Vector2dInt;
33
* A plugin implementing the Normalising Radial Gradient Filter.
34
* Removes the steep radial gradient in brightness in LASCO C2/C3 images
36
* @author Michelle Picardo
41
public class NRGFilter2 implements FullImageFilter, MetaDataFilter{
43
private Region region;
44
private MetaData metaData;
45
private ImageData fullImageData = null;
46
private List<Byte> bin = null;
47
private int steps = 100; //number of bins in array of lists
52
private byte[] pixelData = null;
53
private Filter filter;
57
public void setFullImage(ImageData newFullImageData) {
58
fullImageData = newFullImageData;
61
public void setRegion(Region newRegion) {
65
public void setMetaData(MetaData newMetaData) {
66
metaData = newMetaData;
69
public Filter getFilter() {
75
public ImageData filter(ImageData data) {
82
if (! (data.getImageFormat() instanceof SingleChannelIntegralImageFormat)) {
86
if (! (data.getImageTransport() instanceof Byte8ImageTransport)) {
90
if(! (metaData instanceof HelioviewerMetaData)) {
95
// Get array of intensities from PixelDatafor each pixel: integers from 0 to 255
96
pixelData = ((Byte8ImageTransport) data.getImageTransport()).getByte8PixelData();
97
System.out.println(pixelData);
100
Vector2dDouble sunPoint = ((HelioviewerMetaData)metaData).getPhysicalSunPosition();
102
double[] radius = new double[data.getWidth()*data.getHeight()];
104
for(int row=0; row < data.getWidth(); row++) {
105
for(int col=0; col < data.getHeight(); col++) {
106
Vector2dDouble physPosition = calculatePhysicalFromPixelPosition(new Vector2dInt(col, row));
107
radius[row*data.getWidth()+col] = Math.sqrt(Math.pow(physPosition.getX()-sunPoint.getX(), 2) + Math.pow(physPosition.getY()-sunPoint.getY(), 2));
111
double[] radIndexV = new double[data.getWidth()*data.getHeight()];
113
// Calculate maximum radius
114
for (int j = 0; j < radius.length; j++){
116
max = radius[j]; //find max radius
120
//index each radius by dividing by max radius and multiplying by steps
122
for (int j = 0; j < radius.length; j++) {
123
radIndexV[j] = (radius[j]/max)*steps;
129
ArrayList<List<Byte>> bins = new ArrayList<List<Byte>>();
131
for(int i = 0; i < steps; i++) {
136
//when radius index = bin index, add PixelData Intensity for the radius to that list
137
for(int row=0; row < data.getWidth(); row++) {
138
for(int col=0; col < data.getHeight(); col++) {
140
for(int k=0; k< radius.length; k++){
142
int radIndexValue = (int)Math.round(radIndexV[k]);
143
if (radIndexValue == bins.indexOf(bin)){
144
bin.add() ; // Want to add byte(or double?) intensity values to each list here...should index each radius with pixelData intensity in separate method?
149
// for each bin, calculate and assign mean and stddev values
150
for ( List<Byte> i : bins){
152
BinProperty BinProperty = new BinProperty(mean, stddev);
154
double mean = BinProperty.mean;
155
double stdDev = BinProperty.stddev;
165
public byte calcByteValue(double processedIntensity) {
167
Double d = new Double(processedIntensity);
168
byte b = d.byteValue();
174
private Vector2dDouble calculatePhysicalFromPixelPosition(Vector2dInt pixelPosition) {
175
double meterPerPixel = ((HelioviewerMetaData)metaData).getUnitsPerPixel();
176
return new Vector2dDouble(pixelPosition).scale(meterPerPixel);
180
private class BinProperty {
182
private double stddev;
184
public BinProperty(double mean, double stddev) {
185
this.mean = calcMean(null);
186
this.stddev = calcStdDeviation(null, 0);
189
public double calcMean(List<Byte> bin) {
190
double sum = 0; // sum of all the elements
193
if (i == Integer.MAX_VALUE) break;
196
return sum / bin.size();
200
public double calcStdDeviation(List<Byte> bin, double mean) {
204
s += Math.pow(( i - mean), 2);
207
return Math.sqrt(s / bin.size());
216
public ImageData apply(ImageData data) {
220
byte[] newIntensityArray = new byte[data.getWidth()*data.getHeight()];
222
//calculate the bin that each pixel is in and use the mean/stdDev of that bin for calculation
223
for (int i=0; i<pixelData.length; i++){
225
getBin# //create new method here? can it access bin index/BinProperty from filter?
227
double processedIntensity = i - bin#(BinProperty.mean)/bin#(BinProperty.stddev);
228
//here,is the value of i in byte form from PixelData? Should I cast it to double for the calculation?
230
byte byteProcessedIntensity = calcByteValue(processedIntensity);
231
newIntensityArray[i] = (byte) byteProcessedIntensity;
232
System.out.println(newIntensityArray);
234
return new SingleChannelByte8ImageData(data.getWidth(), data.getHeight(),newIntensityArray);