I have a 90 frames animation and i want to display it on the minecraft hud.
Here is the code i use now:
String CType = "Target";
int CSpeed = 30;
int fast = 0;
public int CenterRoteryCounter = 0;
#ForgeSubscribe
public void CenterRotery(RenderGameOverlayEvent.Post event){
//========Resolution========
res = new ScaledResolution(mc.gameSettings, mc.displayWidth, mc.displayHeight);
int width = res.getScaledWidth();
int height = res.getScaledHeight();
//========Resolution========+
if(CenterRoteryCounter == 90){CenterRoteryCounter = 0;}
if(CenterRoteryCounter < 10){
this.mc.renderEngine.func_110577_a(new ResourceLocation("CenterRotery/"+CType+"000" + CenterRoteryCounter + ".png"));
}else{if(CenterRoteryCounter < 100){
this.mc.renderEngine.func_110577_a(new ResourceLocation("CenterRotery/"+CType+"00" + CenterRoteryCounter + ".png"));
}else{
this.mc.renderEngine.func_110577_a(new ResourceLocation("CenterRotery/"+CType+"0" + CenterRoteryCounter + ".png"));
}
}
drawTexturedModalRect((width/2)-44, (height/2)-37, 0, 0, 250, 250);
mc.func_110434_K().func_110577_a(Gui.field_110324_m);
if((fast % CSpeed)==0){CenterRoteryCounter++;}fast++;
}
but as you can see, this is creating ~30 new ResourceLocations every second..!!
How can i pre-load the textures and display them the same way?
You can simply use a private static final Hashmap from your class in a method getResourceLocation(String resourceLocation). Something like :
private static ResourceLocation getResourceLocation(String resourceLocation) {
ResourceLocation myRes = myHashMap.get(resourceLocation);
if (myRes == null) {
myRes = new ResourceLocation(resourceLocation);
myHashMap.put(resourceLocation, myRes);
}
return myRes;
}
It will cache your resources on demand. Just be sure of the necessary amount of memory needed !
Related
Good afternoon, I am using stm32 Blue Pill on USB raised com - port, development environment "IAR".
The problem is the following, when I connect through the application, the number "3"
does not change to the number "50" after the arrow, but on the contrary is shown next !
See Figure 1.2. I work under the protocol.
How do you achieve this?
I'm using the controlP5 library and cp5.addNumberbox.
Data in "IAR".
int Bullet = 50; // variable for result
sprintf((char *)str, "(,%d,-Ђ",Bullet); // sending a command with data to stm32.
In the code of the Displaydata tab, the line "case 40" is the symbol (
The command can also be sent through the terminal using a virtual com port.
Command: (, 50 ,! Figure 3.
I'll have to lay out the whole little project for you to check it out.
Com_Interface1:
import processing.serial.*;
import controlP5.*;
ControlP5 cp5;
DropdownList serialPortsList;
Serial serialPort;
final int BAUD_RATE = 9600;
char parity = 'N';
int dataBits = 8;
float stopBits = 1.0;
public void setup() {
background(50);
size(700, 420, P3D);
surface.setTitle("TEST");
surface.setResizable(false);
setupUI();
smooth();
frameRate(30);
writeOutgioing[lengthmas-1]=1;
String[] portNames = Serial.list();
//serialPort.clear(); // Why does not it work?
for (int i = 0; i < portNames.length; i++) serialPortsList.addItem(portNames[i], i);
}
public void toplug (int theValue)
{ // Start button on click sends a commad 1.
println("Button click events: "+theValue);
strata =!strata;
if (!strata) {
connection.setLabel("Пуск");
serialPort.dispose();
Vin.setText("Voltage K.V - ");
inputPULI.setLabel("Bullet");
} else {
connection.setLabel("СТОП");
serialports((int)serialPortsList.getValue());
writeOutgioing[0]=1;
writeOut();
}
}
public void serialports(int theValue) {
try {
serialPort = new Serial(this, Serial.list()[theValue], BAUD_RATE, parity, dataBits, stopBits);
serialPort.bufferUntil('\n');
println("COM connected: "+ Serial.list()[theValue] );
/*Send.unlock();
connection.unlock();*/ // locking buttons in applications if not connected via rs-232.
}
catch(Exception e) {
System.err.println("Error opening serial port" + Serial.list()[theValue]);
e.printStackTrace();
}
}
/*void controlEvent(ControlEvent event){
println(event.getController().getName(),"changed value to",event.getValue(),"inputPULI = ",PUL,"inputNapryzenieKV = ",NapryzenieKV,"CheckBoxuvum= ",
UV/UM,"P4 = ",std2,);
}*/
Displaydata:
void Displaydata() {
switch(x)
{
case 20:
// What to write?
// label(testRead[1]+" Мин."); // ImageButton
// min=testRead[1];
break;
case 30:
// What to write?
// P4.setText("std2"+ testRead[1]); // CheckBox
break;
case 40:
inputPULI.setLabel("Bullet: " + testRead[1] );
break;
case 70:
inputNapryzenieKV.setLabel("Voltage: " + testRead[1] );
break;
case 60:
Vin.setText("Voltage K.V: " + testRead[1] + " " + testRead[2]);
break;
case 50:
// What to write?
//CheckBoxuvum.setText("UV/UM - " +testRead[1] ); // RadioButton
break;
default:
println("DisplayData(): no case selected.");
break; // technically not necessary, but I like my switches tidy
}
}
GUI:
int PUL;
float NapryzenieKV;
boolean strata=false;
ImageButton button;
Numberbox inputPULI;
Numberbox inputNapryzenieKV;
RadioButton CheckBoxuvum;
CheckBox P4;
Textlabel Vin;
Button connection;
Button Send;
public void setupUI()
{
cp5 = new ControlP5(this);
PFont fontn = createFont("Times New Roman", 18);
PFont p = createFont("Times New Roman", 18);
ControlFont font=new
ControlFont(p);
cp5.setFont(font);
connection = cp5.addButton("toplug")
.setCaptionLabel("ПУСК")
.setPosition(387, 30)
.setSize(150, 30);
serialPortsList = cp5.addDropdownList("Порт")
.setPosition(130, 30)
.setSize(150, 200)
.setItemHeight(30)
.setBarHeight(30);
PImage[] imgs = {loadImage("button101.png"), loadImage("button102.png"), loadImage("button103.png")};
Send = cp5.addButton("toapply")
//.setCaptionLabel("Apply")
//.setPosition(510, 370)
//.setSize(150, 30);
.setPosition(590, 330)
.setImages(imgs)
.updateSize();
//.lock()
Vin = cp5.addTextlabel("naprazhenie kondencatora")
.setText("Voltage K.V")
.setFont(p)
.setColor(color(#00ffff))
.setPosition(45, 320);
CheckBoxuvum = cp5.addRadioButton("UV/UM")
.setPosition(155, 360)
.setSize(15, 15)
.setColorActive(color(255))
.setItemsPerRow(2)
.setSpacingColumn(85)
.addItem("+", 1)
.addItem("-", 2);
P4 = cp5.addCheckBox("std2")
.setPosition(150, 190)
.setSize(15, 15)
.setItemsPerRow(1)
.setSpacingColumn(30)
.setSpacingRow(20)
.addItem("Check", 2);
inputPULI = cp5.addNumberbox("PUL")
.setLabel("Bullet")
.setPosition(220, 220)
.setSize(80, 30)
.setColorValue(0xffffff00)
.setFont(p)
.setScrollSensitivity(1.1)
.setDirection(Controller.HORIZONTAL)
.setRange(1, 199)
.setValue(3);
Label labelinputPULI = inputPULI.getCaptionLabel();
labelinputPULI.setFont(font);
labelinputPULI.setColor(color(#00ffff));
labelinputPULI.toUpperCase(false);
labelinputPULI.setText("Bullet");
labelinputPULI.align(ControlP5.LEFT_OUTSIDE, CENTER);
labelinputPULI.getStyle().setPaddingLeft(-25);
inputNapryzenieKV = cp5.addNumberbox("NapryzenieKV")
.setLabel("Voltage")
.setPosition(150, 270)
.setSize(80, 30)
.setColorValue(0xffffff00)
.setFont(p)
.setScrollSensitivity(1.1)
.setMin(25)
.setMax(99)
.setMultiplier(0.01)
.setDirection(Controller.HORIZONTAL)
.setValue(25);
Label labelinputNapryzenieKV = inputNapryzenieKV.getCaptionLabel();
labelinputNapryzenieKV.setFont(font);
labelinputNapryzenieKV.setColor(color(#00ffff));
labelinputNapryzenieKV.toUpperCase(false);
labelinputNapryzenieKV.setText("Напряжение");
labelinputNapryzenieKV.align(ControlP5.LEFT_OUTSIDE, CENTER);
labelinputNapryzenieKV.getStyle().setPaddingLeft(-45);
textFont(fontn);
{
// button dimensions
int w = 99;
int h = 25;
// test with generated images
button = new ImageButton(555, 230, w, h,
new PImage[]{
loadImage("0.png"), // off
loadImage("1.png"), // 10
loadImage("2.png"), // 20
loadImage("3.png"), // 30
loadImage("4.png"), // 40
loadImage("5.png"), // 50
loadImage("6.png"), // 60
});
}
}
void mousePressed() {
button.mousePressed(mouseX, mouseY);
println(button.min);
}
// test images to represent loaded state images
PImage getImage(int w, int h, int c) {
PImage img = createImage(w, h, RGB);
java.util.Arrays.fill(img.pixels, c);
img.updatePixels();
return img;
}
// make a custom image button class
class ImageButton {
// minutes is the data it stores
int min = 0;
// images for each state
PImage[] stateImages;
// which image to display
int stateIndex;
// position
int x, y;
// dimensions: width , height
int w, h;
// text to display
String label = "ВЫКЛ";
ImageButton(int x, int y, int w, int h, PImage[] stateImages) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.stateImages = stateImages;
}
void mousePressed(int mx, int my) {
// check the cursor is within the button bounds
boolean isOver = ((mx >= x && mx <= x + w) && // check horizontal
(my >= y && my <= y + h) ); // check vertical
if (isOver) {
min += 10;
stateIndex++;
if (min>60) {
min = 0;
stateIndex = 0;
label = "ВЫКЛ";
} else {
label = (str(min) + "Мин");
}
}
}
void draw() {
// if the images and index are valid
if (stateImages != null && stateIndex < stateImages.length) {
image(stateImages[stateIndex], x, y, w, h);
} else {
println("error displaying button state image");
println("stateImages: ");
printArray(stateImages);
println("stateIndex: " + stateIndex);
}
// display text
//text(label, x + 17, y + h - 8);
}
}
void controlEvent(ControlEvent theEvent) {
if (theEvent.isFrom(CheckBoxuvum)) {
//myColorBackground = 0;
print("got an event from "+CheckBoxuvum.getName()+"\t\n");
// checkbox uses arrayValue to store the state of
// individual checkbox-items. usage:
println(CheckBoxuvum.getArrayValue());
int col = 0;
for (int i=0; i<CheckBoxuvum.getArrayValue().length; i++) {
int n = (int)CheckBoxuvum.getArrayValue()[i];
print(n);
if (n==1) {
//myColorBackground += CheckBoxuvum.getItem(i).internalValue();
}
}
println();
}
if (theEvent.isGroup()) {
// check if the Event was triggered from a ControlGroup
println("event from group : "+theEvent.getGroup().getValue()+" from "+theEvent.getGroup());
} else if (theEvent.isController()) {
println("event from controller : "+theEvent.getController().getValue()+" from "+theEvent.getController());
}
}
Protocol:
int lengthmas = 7;
int RC = 0x21; // -128 separating byte в java
int[] writeOutgioing = new int[lengthmas];
String incomingData= null;
String outgoingData=null;
String[] testRead = new String[lengthmas];
int x;
void readInc() {
while ( serialPort.available() > 0)
{
incomingData = serialPort.readStringUntil(RC);
testRead = split (incomingData, ',' );
if (testRead != null)
{
x = (int) testRead[0].charAt(0);
Displaydata();
}
}
}
void writeOut() {
outgoingData=str(writeOutgioing[0])+str(writeOutgioing[1])+str(writeOutgioing[2])+str(writeOutgioing[3])+str(writeOutgioing[4])+str(writeOutgioing[5])+str(writeOutgioing[6]); // sending data as a string.
serialPort.write(outgoingData);
}
Senddata:
public void toapply()
{
}
loop:
void draw()
{
background(50);
button.draw();
if (strata)
{
readInc();
}
}
code:
inputPULI = cp5.addNumberbox("PUL")
.setLabel("Bullet")
.setPosition(220, 220)
.setSize(80, 30)
.setColorValue(0xffffff00)
.setFont(p)
.setScrollSensitivity(1.1)
.setDirection(Controller.HORIZONTAL)
.setRange(1, 199)
.setValue(3);
Label labelinputPULI = inputPULI.getCaptionLabel();
labelinputPULI.setFont(font);
labelinputPULI.setColor(color(#00ffff));
labelinputPULI.toUpperCase(false);
labelinputPULI.setText("Bullet");
labelinputPULI.align(ControlP5.LEFT_OUTSIDE, CENTER);
labelinputPULI.getStyle().setPaddingLeft(-25);
I figured it out myself, I had to write setLabel->setValueLabel
example
What I've tried.
Please help me.. I really don't know.
I think it's related to canvas class.
CustomLineChartRenderer
It seems to me that color is not filled according to x value, but color is filled at once.
It's hard because I'm not used to canvas. Please help me.
Here are three methods for drawing lines and filling in colors.
#Override
protected void drawLinearFill(Canvas c, ILineDataSet dataSet, Transformer trans, XBounds bounds) {
final Path filled = mGenerateFilledPathBuffer;
final int startingIndex = bounds.min;
final int endingIndex = bounds.range + bounds.min;
final int indexInterval = 128;
int currentStartIndex = 0;
int currentEndIndex = indexInterval;
int iterations = 0;
// Doing this iteratively in order to avoid OutOfMemory errors that can happen on large bounds sets.
do {
currentStartIndex = startingIndex + (iterations * indexInterval);
currentEndIndex = currentStartIndex + indexInterval;
currentEndIndex = currentEndIndex > endingIndex ? endingIndex : currentEndIndex;
if (currentStartIndex <= currentEndIndex) {
generateFilledPath(dataSet, currentStartIndex, currentEndIndex, filled);
trans.pathValueToPixel(filled);
final Drawable drawable = dataSet.getFillDrawable();
if (drawable != null) {
drawFilledPath(c, filled, drawable);
} else {
//////Here part of applying color
drawFilledPath(c, filled, dataSet.getFillColor(), dataSet.getFillAlpha());
}
}
iterations++;
} while (currentStartIndex <= currentEndIndex);
}
#Override
protected void drawFilledPath(Canvas c, Path filledPath, int fillColor, int fillAlpha) {
int color = (fillAlpha << 24) | (fillColor & 0xffffff);
if (clipPathSupported()) {
Log.e("clipPathSupported","1");
int save = c.save();
c.clipPath(filledPath);
c.drawColor(color);
c.restoreToCount(save);
} else {
Log.e("clipPathSupported","2");
// save
Paint.Style previous = mRenderPaint.getStyle();
int previousColor = mRenderPaint.getColor();
// set
mRenderPaint.setStyle(Paint.Style.FILL);
mRenderPaint.setColor(color);
c.drawPath(filledPath, mRenderPaint);
// restore
mRenderPaint.setColor(previousColor);
mRenderPaint.setStyle(previous);
}
}
private void generateFilledPath(final ILineDataSet dataSet, final int startIndex, final int endIndex, final Path outputPath) {
final float fillMin = dataSet.getFillFormatter().getFillLinePosition(dataSet, mChart);
final float phaseY = mAnimator.getPhaseY();
final boolean isDrawSteppedEnabled = dataSet.getMode() == LineDataSet.Mode.STEPPED;
final Path filled = outputPath;
filled.reset();
final Entry entry = dataSet.getEntryForIndex(startIndex);
filled.moveTo(entry.getX(), fillMin);
filled.lineTo(entry.getX(), entry.getY() * phaseY);
// create a new path
Entry currentEntry = null;
Entry previousEntry = entry;
for (int x = startIndex + 1; x <= endIndex; x++) {
currentEntry = dataSet.getEntryForIndex(x);
if (isDrawSteppedEnabled) {
filled.lineTo(currentEntry.getX(), previousEntry.getY() * phaseY);
}
filled.lineTo(currentEntry.getX(), currentEntry.getY() * phaseY);
previousEntry = currentEntry;
}
// close up
if (currentEntry != null) {
filled.lineTo(currentEntry.getX(), fillMin);
}
filled.close();
}
You can use shader, same :
mRenderPaint.shader = LinearGradient(fromX, fromY, toX, toY, color1,
color2,
Shader.TileMode.CLAMP)
I'm trying to display 550 data points with periodic peaks (the flat line is 61). The problem is, that androidplot isn't drawing all the points correctly! From my log:
ECG I values 61,61,62,63,62,61,61,61,61,67,71,68,61,53,61,61,61,61,61,61,61,61,62,63,64,64,64,63,62,61,61,61
I've got the rangeboundaries set to plot.setRangeBoundaries(0,100, BoundaryMode.AUTO);, but as you can see, the peaks never drop to the 53 data point. I can see this lower point sometimes, but it gets smoothed out a fraction of a second later (as you can see in the screenshot).
My line and point formatter is:
LineAndPointFormatter lapf = new LineAndPointFormatter(p.color, null, null, null);
lapf.getLinePaint().setStrokeJoin(Paint.Join.MITER);
lapf.getLinePaint().setStrokeWidth(1);
I've tried with the both Paint.Join.ROUND and Paint.Join.BEVEL and got the same effect. I've also used the debugger to check that 53 is being inserted into the series.
EDIT
After some debugging, it looks like my pulse loop thread is wrong:
while (keepRunning) {
for (PulseXYSeries j : series) {
for (int k = 0; k < j.plotStep; k++) {
int at = (j.position + k) % j.getSize();
if (j.pulsing) {
if (j.pulsePosition == j.pulseValues.size() - 1) {
j.pulsing = false;
j.pulsePosition = 0;
} else {
try {
int pulseVal = j.pulseValues.get(j.pulsePosition);
j.setY(pulseVal,at);
j.pulsePosition += 1;
} catch(IndexOutOfBoundsException e) {
j.pulsePosition = 0;
}
}
} else {
j.setY(j.pulseValues.get(0), at);
long currTime = SystemClock.elapsedRealtime();
if (currTime - j.getLastPulse() >= j.getPulseDelay()) {
j.pulsing = true;
j.setLastPulse(currTime);
}
}
j.remove(((at + j.eraserSize) % j.getSize()));
}
j.position = (j.position + 1) % j.getSize(); // fixed it by changing +1 to + j.plotStep
}
Thread.sleep(delay);
}
My custom series looks like:
private class PulseXYSeries implements XYSeries {
private List<Integer> pulseValues = new ArrayList<Integer>();
private int pulsePerMinute;
public int pulsePosition;
public int position;
private ArrayList<Integer> values;
private String title;
private long lastPulse;
public boolean pulsing = false;
public int eraserSize = 20;
public int plotStep = 3;
}
I am implementing hybrid image with ImageJ and stuck at merging low filter image and high filter image to form a hybrid image.
This is what I already done.I have 2 images from Gaussian Blur and Laplician of Gaussian filer. I need to merge these 2 images by layer after that. Any idea how to achieve it?
import ij.*;
import ij.process.*;
import ij.gui.*;
import java.awt.*;
import ij.plugin.filter.*;
import ij.plugin.*;
import ij.io.*;
import java.io.*;
public class HybridImage_Plugin implements PlugInFilter{
int cfsize=3;
String img_lowPass;
String img_highPass;
private double[][] filter;
private double sigma;
float w=2 ,delta=0 , thr=0;
int mode=0;
//dialogbox
private boolean GUI()
{
GenericDialog gd = new GenericDialog("Enter Values", IJ.getInstance());
gd.addNumericField("Sigma (3,5,9,17,35)", cfsize, 0);
gd.addStringField("Low-Pass", "/home/atrx/ImageJ/plugins/hybridimage/l1.tif");
gd.addStringField("High-Pass", "/home/atrx/ImageJ/plugins/hybridimage/l2.tif");
return getUserParams(gd);
}
//get parameters
private boolean getUserParams(GenericDialog gd)
{
gd.showDialog();
if (gd.wasCanceled())
{
return false;
}
cfsize = (int) gd.getNextNumber();
img_lowPass = gd.getNextString();
img_highPass= gd.getNextString();
return true;
}
public int setup(String arg, ImagePlus imp) {
return PlugInFilter.NO_IMAGE_REQUIRED;
}
public void run(ImageProcessor ip) {
int[][] result;
if(GUI() == false)
{
return;
}
else
{
Opener opener1 = new Opener();
Opener opener2 = new Opener();
ImagePlus imp1= opener1.openImage(img_lowPass);
ImagePlus imp2= opener2.openImage(img_highPass);
//imp1.show("Low Pass Image");
//imp2.show("HighPass Image");
ImageProcessor ip1 = imp1.getProcessor();
ImageProcessor ip2 = imp2.getProcessor();
//lowpass filter(Gaussian Blur)
ip1.blurGaussian(cfsize);
showProcessor(ip1,"Low Pass Filtered Image");
//highpass filter(LoG)
int csize = ip2.getHeight();
int rsize = ip2.getWidth();
Rectangle rect = ip2.getRoi();
int d0,a0,acr,dow,it;
int i,x,y;
double h12, h21, ft, h1h2, h2h1, fmu, dh, dv;
double r, dt, dmx, dmn;
float logaus[] = new float[(rect.width>rect.height)? rect.width : rect.height];
float gaus[] = new float[(rect.width>rect.height)? rect.width : rect.height];
float dgaus[] = new float[(rect.width>rect.height)? rect.width : rect.height];
long zcn =0;
byte pixels[] = (byte[])ip2.getPixels();
int img_in[] = new int[rect.width*rect.height];
if (cfsize<0) cfsize=3;
if (cfsize>35) cfsize=35;
if(w<0) w=0;
int fsize = (int)(cfsize*w);
if (fsize%2 == 0)
{
fsize += 1;
}
double dimg[] = new double[rect.height*rect.width];
double dr[] = new double[rect.height*rect.width];
i=0;
for(y=rect.y;y<(rect.y+rect.height);y++)
{
for(x=rect.x;x<(rect.x+rect.width);x++)
{
img_in[i] = (pixels[(y*rsize)+x]&0xff);
i++;
}
}
int size = rect.width + fsize -1;
int image[] = new int[(rect.width+fsize-1)*(rect.height+fsize-1)];
int extension= (fsize/2);
for( i=0; i<rect.height;i++)
{
System.arraycopy(img_in,(i*rect.width),image,( ((i+extension)*(rect.width+fsize-1))+ extension ),rect.width);
}
h1h2= h2h1 = h12 =0.0;
for(i=1; i<( (fsize+1) /2);i++)
{
w = (float)cfsize/(float)2.0/(float)1.414;
ft = i/w;
gaus[i] = (float)Math.exp(-ft*ft/2);
h1h2 += 2.0 *(gaus[i]);
logaus[i] =(float)(1-ft*ft)*(float)Math.exp(-ft*ft/2);
h2h1 += 2.0*(logaus[i]);
dgaus[i] =(float)ft*(float)Math.exp(-ft*ft/2);
}
fmu = (h2h1 + 1)* (h1h2+1);
int prel[] = new int[rect.width+1];
dmx = -99999.9;
dmn = 99999.9;
int limit = ((rect.width+fsize-1)*(rect.height+fsize-1));
for(d0=0;d0<rect.height;d0++)
{
for(a0=0;a0<rect.width;a0++)
{
acr = a0 + fsize/2;
dow = d0 + fsize/2;
dh = dv = 0.0;
h1h2 = h2h1 = 0.0;
for (int j=1; j<(fsize+1)/2; j++)
{
int a0d0, a0d1, a1d0, a1d1;
h12=h21=0.0;
for(i=1;i<(fsize+1)/2;i++)
{
a0d0 = acr-i+((dow-j)*size);
a0d1 = acr-i+((dow+j)*size);
a1d0 = acr+i+((dow-j)*size);
a1d1 = acr+i+((dow+j)*size);
h12 += logaus[i]*(image[a0d0] + image[a0d1]+
image[a1d0] + image[a1d1]);
h21 += gaus[i]* (image[a0d0] + image[a0d1] +
image[a1d0] + image[a1d1]);
}
a0d0 = acr-j+dow*size;
a0d1 = acr+(dow-j)*size;
a1d0 = acr+j+dow*size;
a1d1 = acr+(dow+j)*size;
h1h2 += gaus[j] * (h12+ image[a0d0]+image[a0d1]+
image[a1d0]+image[a1d1]);
h2h1 += logaus[j]*(h21+ image[a0d0]+ image[a0d1] +
image[a1d0] + image[a1d1] );
if(thr != 0.0)
{
dh += dgaus[j] * ( image[a1d0] - image[a0d0] );
dv += dgaus[j] * ( image[a1d1] - image[a0d1] );
}
}
dt = dimg[d0*rect.width+a0] = h1h2 + h2h1 + (2*image[dow*size+acr]) ;
if (dt > dmx) dmx = dt;
if (dt < dmn) dmn = dt;
if( thr!= 0.0)
{
dr[(d0*rect.width)+a0] = Math.abs(dh) + Math.abs(dv);
}
}
}
dmx = (dmx-dmn) / 2;
dmn += dmx;
int row=0, column=0;
for(d0=0;d0<rect.height;d0++)
{
for(a0=0;a0<rect.width;a0++)
{
int id = (d0*rect.width) +a0;
int index = rsize*(rect.y+d0) + (a0+rect.x);
int k = 15;
it = (int)(dt = (dimg[id] - (dmn-delta*dmx))*255 / (dmx*(1+Math.abs(delta))));
switch(mode){
case 0:
pixels[index] = (byte)((dt-dmn+dmx)/dmx*127);
break;
case 1:
pixels[index] = (byte)Math.abs(it);
break;
case 2:
pixels[index] = (byte)( ((dt!=0)?((dt>0) ? 1: -1) : 0) * 192);
break;
case 3:
default:
r = dr[id];
it = ( (dt!=0) ? ((dt>0) ? 1: -1) : 0);
if( it==0 && r>=thr)
{
k = 255;
zcn++;
}
else
{
if( (it*prel[a0]<0 || it*prel[a0+1]<0) && r>=thr)
{
k = 255;
zcn++;
}
}
prel[a0+1] = it;
if(k==255 || mode!=3)
pixels[index] = (byte)k;
break;
}
}
}
showProcessor(ip2,"High Pass Filtered Image");
}
}
static void showProcessor(ImageProcessor ip, String title){
ImagePlus win = new ImagePlus(title,ip);
win.show();
}
}
Have you tried performing a weighted sum?
OUT = w*LPF + (1 - w)*HPF
This kind of sum is used everywhere. In particular, image blending, alpha matting and even in some optimization schemes.
However because there are patches of varying spatial frequencies all around your image, you may have to make the weight adaptive. You also have to choose which one you want to emphasize more. Do you want the low pass or high pass information to stand out more? Depending on which you want, you might want to use information in either one of those images and run it through some distance or similarity measure to get the right weight.
i'm posting a simple game code, written in java. It took my hours today to write this but now i'm stuck! The problem is, in the second level of this game (after failure or success) i can't see the red tiles. It works only the first time.
games logic:
it starts up with a 3x3 matrix and rebound the dimension of this matrix in case of success (testing the ability of memory, memorising the coordinates of red tiles in 1200 ms). So we show the red tiles first, than we check the estimations. If there became a wrong try, failure!. If it is a bigger matrix than 3x3, it gets smaller.
the code is a little bit long but just one class, so it is so easy yo execute it. If you have time i would be appreciate.
So there it goes:
package skeleton;
public class Memory extends JFrame implements ActionListener {
private static final long serialVersionUID = 5963518754230629235L;
private static int minDimX = 3, minDimY = 3;
private static int maxDimX = 15, maxDimY = 15;
private static int counter = 13;
private static int memoriseTime = 1200; // milliseconds
private static int memGridWidthX = 60;
private static int memGridWidthY = 60;
private JPanel centerPanel;
private JButton memTile;
private Random generator;
private int memGridDimX, memGridDimY, coef, numberOfMemTilesToGuess;
int[][] memTileCoordinates;
int[] randomNums;
Border grayBorder = LineBorder.createGrayLineBorder();
public Memory(int xDim, int yDim) {
waitALittleBit(1300);
memGridDimX = xDim;
memGridDimY = yDim;
coef = 3;
numberOfMemTilesToGuess = memGridDimX*memGridDimY / coef;
centerPanel = new JPanel();
centerPanel.setLayout(new GridLayout(memGridDimY, memGridDimX, 0, 0));
add(centerPanel, BorderLayout.CENTER);
System.out.println("int[" + memGridDimX + "][" + memGridDimY + "] array is created ");
randomNums = new int[numberOfMemTilesToGuess];
for (int i = 0 ; i < numberOfMemTilesToGuess ; i ++) {
System.out.println("> we are in for the "+ (i+1) +". time!");
int randomNum;
boolean randomNumberAlreadySelected = false;
do {
randomNum = calculateARandomNumber(memGridDimX * memGridDimY);
if (i != 0) { //for the first time, we don't need to compare any numbers
randomNumberAlreadySelected = isThisRandomNumberExistInAlreadyFoundRandomNumbersArray(randomNum, randomNums, i);
if (randomNumberAlreadySelected)
System.out.println("######## RECALCULATING RANDOM NUMBER !! ##########");
else
System.out.println("They are not equal, go on!");
}
} while (randomNumberAlreadySelected);
randomNums[i] = (Integer)randomNum;
}
//show the memory tiles
setMemTiles(randomNums, true);
waitALittleBit(memoriseTime);
//hide the memory tiles
setMemTiles(randomNums, false);
}
private int calculateARandomNumber(int limit) {
generator = new Random();
System.out.println("* Calculating random number which is smaller than " + memGridDimX * memGridDimY);
int randomNum = generator.nextInt() % (memGridDimX * memGridDimY);
System.out.println("- Calculated random number: " + randomNum);
if (randomNum < 0) {
System.out.println(".. it is negative, so we add: " + memGridDimX * memGridDimY);
randomNum += memGridDimX * memGridDimY;
}
System.out.println(".. and we add 1 to have a grid array between 1 and 12");
randomNum += 1;
System.out.println(".. and our new random number is: " + randomNum);
return randomNum;
}
private boolean isThisRandomNumberExistInAlreadyFoundRandomNumbersArray(int number, int[] numberArr, int numberArrSize) {
for (int j = 0 ; j < numberArrSize ; j ++) {
System.out.println("# Comparing random number: " + number + " and " + (j+1) + ". random number selected earlier: " + numberArr[j]);
if (number == numberArr[j])
return true;
}
return false;
}
private void setMemTiles(int[] randomNums, boolean showMemTiles) {
centerPanel.removeAll();
memTileCoordinates = new int[randomNums.length][2];
for (int i = 1 ; i <= memGridDimY ; i ++) {
for (int j = 1 ; j <= memGridDimX ; j ++) {
int rnX = -1;
int rnY = -1;
boolean isMemTile = false;
for (int k = 0 ; k < randomNums.length ; k ++) {
int rn = randomNums[k];
if (rn % memGridDimX == 0) {
rnY = rn / memGridDimX;
rnX = memGridDimX;
} else {
rnY = rn / memGridDimX + 1;
rnX = rn % memGridDimX;
}
if (i == 1 && j == 1 && !showMemTiles) { //do it once
System.out.println("********* ************");
System.out.println("Random label number: " + rn + " and it's position in the grid: " + rnX + "," + rnY);
memTileCoordinates[k][0] = rnX;
memTileCoordinates[k][1] = rnY;
System.out.println("> Memory Tiles coordinates: " + memTileCoordinates[k][0] + "," + memTileCoordinates[k][1]);
System.out.println("> Memory Tiles length: " + memTileCoordinates.length);
System.out.println("********* ************");
}
if (rnX == j && rnY == i)
isMemTile = true;
}
memTile = new JButton();
if (isMemTile) {
update(getGraphics());
if (showMemTiles) {
memTile.setBackground(Color.red);
System.out.println("%%%% PAINTING MEM TILES IN RED %%%%");
} else
memTile.setBackground(Color.white);
update(getGraphics());
} else
memTile.setBackground(Color.white);
if (!showMemTiles) // we listen actions after the memory tiles disappears
memTile.addActionListener(this);
centerPanel.add(memTile);
update(getGraphics());
}
}
setJPanelSettings();
}
private void setJPanelSettings() {
setSize(memGridDimX * memGridWidthX, memGridDimY * memGridWidthY);
setTitle("Memory :: " + memGridDimX + "x" + memGridDimY);
setResizable(false);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setVisible(true);
}
private void waitALittleBit(long waitingMillisSeconds) {
long t0 = System.currentTimeMillis();
long t1 ;
do {
t1 = System.currentTimeMillis();
} while (t1 - t0 < waitingMillisSeconds);
}
public static void main(String[] args) {
new Memory(minDimX,minDimY);
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(">>> An action came >>>");
JButton memTile = (JButton) e.getSource();
Dimension size = memTile.getSize();
int chosenMemTileDimX = memTile.getX();
int chosenMemTileDimY = memTile.getY();
int chosenMemTilePosX = chosenMemTileDimX / size.width + 1; // we add 1 becausee we present our tile numbers as 1:1, 1:2, ... ( instead of 0:0,0:1, ... )
int chosenMemTilePosY = chosenMemTileDimY / size.height + 1;
System.out.println("Chosen Tile's x dimension: " + chosenMemTileDimX + " ans y dimension: " + chosenMemTileDimY);
System.out.println("Chosen Tile's width: " + size.width + " and height: " + size.height);
System.out.println("Chosen Tile's coordinates: " + chosenMemTilePosX + ", " + chosenMemTilePosY);
boolean tileIsMemTile = false;
System.out.println("Memory Tiles Coordinates: ");
for (int i = 0 ; i < memTileCoordinates.length ; i ++) {
int memTileDimX = memTileCoordinates[i][0];
int memTileDimY = memTileCoordinates[i][1];
System.out.println("x: " + memTileDimX + ", y: " + memTileDimY);
if (chosenMemTilePosX == memTileDimX && chosenMemTilePosY == memTileDimY)
tileIsMemTile = true;
}
if (tileIsMemTile) {
System.out.println("!!! Right Tile !!!");
memTile.setBackground(Color.red);
numberOfMemTilesToGuess -= 1;
System.out.println("It rest " + numberOfMemTilesToGuess + " tiles to guess");
} else {
System.out.println("!!! Wrong Tile !!!");
Icon falseTileIcon;
try {
falseTileIcon = new ImageIcon(getClass().getResource("wrong.png"));
if (falseTileIcon.getIconHeight() > 0)
memTile.setIcon(falseTileIcon);
} catch (Exception e1) {
memTile.setBackground(Color.black);
}
update(getGraphics()); // good trick!!
waitALittleBit(1000);
//TODO !!! FAILED IN LEVEL MESSAGE !!!
dispose();
if (memGridDimX == minDimX && ( memGridDimY == minDimY || memGridDimY == minDimY + 1))
new Memory(minDimX, minDimY);
else if (memGridDimX == memGridDimY)
new Memory(memGridDimX - 1, memGridDimY);
else
new Memory(memGridDimX, memGridDimY -1);
}
System.out.println(">>> Action processed >>>");
if (numberOfMemTilesToGuess == 0) {
System.out.println("\n END OF THE LEVEL");
System.out.println("Congratulations, you guessed all the tiles without error !! \n");
dispose();
//TODO !!!! SHOW INTERLEVEL INFORMATION !!!!
if (memGridDimX != maxDimX && memGridDimY != maxDimY) {
if (memGridDimX == memGridDimY)
new Memory(memGridDimX, memGridDimY + 1);
else
new Memory(memGridDimX + 1, memGridDimY);
} else
System.out.println("You have a really good memory my friend!");
}
}}
I used update(getGraphics()); many times, it was just for a test...
Thanks in advance.
You where told in your last posting to NOT use the update() method.
do
{
t1 = System.currentTimeMillis();
}
while (t1 - t0 < waitingMillisSeconds);
Also, never use a tight loop like that. Its just as bad as using Thread.sleep(...);
You where given suggestions in your last posting!
I think you can use LWJGL, which is a java game library.
https://www.lwjgl.org
Some of the issues may be due to the thread on which the various bit of code run. The first time through you are running on the "Main" thread, and to be completely correct calls to update the AWT/Swing GUI should be done using the "Event Dispatcher Thread".
The actionPerformed method is called from the "Event Dispatcher Thread" and so then the second time you call into the constructor for Memory you are in this thread.
Also, aside from the fact you have implemented a delay with a spin-loop, which is not efficient; you should not delay the "Event Dispatcher Thread".
See this short overview: http://www.javamex.com/tutorials/threads/swing_ui.shtml